mirror of
https://iceshrimp.dev/limepotato/jormungandr-bite.git
synced 2025-01-10 15:40:57 -07:00
er?
This commit is contained in:
parent
52792b706e
commit
8b4a927bce
3 changed files with 213 additions and 209 deletions
BIN
.yarn/cache/libopenmpt-wasm-https-c2e0cb89a7-ace14fcb0e.zip
(Stored with Git LFS)
vendored
Normal file
BIN
.yarn/cache/libopenmpt-wasm-https-c2e0cb89a7-ace14fcb0e.zip
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
|
@ -1,34 +1,34 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="achievements" class="root">
|
<div v-if="achievements" :class="'.root'">
|
||||||
<div v-for="achievement in achievements" :key="achievement" class="_panel achievement">
|
<div v-for="achievement in achievements" :key="achievement" :class="'.achievement'" class="_panel">
|
||||||
<div class="icon">
|
<div :class="'.icon'">
|
||||||
<div :class="[['iconFrame'], ['iconFrame_' + ACHIEVEMENT_BADGES[achievement.name].frame]]">
|
<div :class="['.iconFrame', ['iconFrame_' + ACHIEVEMENT_BADGES[achievement.name].frame]]">
|
||||||
<div class="iconInner" :style="{ background: ACHIEVEMENT_BADGES[achievement.name].bg }">
|
<div :class="['.iconInner']" :style="{ background: ACHIEVEMENT_BADGES[achievement.name].bg }">
|
||||||
<img class="iconImg" :src="ACHIEVEMENT_BADGES[achievement.name].img">
|
<img :class="'.iconImg'" :src="ACHIEVEMENT_BADGES[achievement.name].img">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="body">
|
<div :class="'.body'">
|
||||||
<div class="header">
|
<div :class="'.header'">
|
||||||
<span class="title">{{ i18n.ts._achievements._types['_' + achievement.name].title }}</span>
|
<span :class="'.title'">{{ i18n.ts._achievements._types['_' + achievement.name].title }}</span>
|
||||||
<span class="time">
|
<span :class="'.time'">
|
||||||
<time v-tooltip="new Date(achievement.unlockedAt).toLocaleString()">{{ new Date(achievement.unlockedAt).getFullYear() }}/{{ new Date(achievement.unlockedAt).getMonth() + 1 }}/{{ new Date(achievement.unlockedAt).getDate() }}</time>
|
<time v-tooltip="new Date(achievement.unlockedAt).toLocaleString()">{{ new Date(achievement.unlockedAt).getFullYear() }}/{{ new Date(achievement.unlockedAt).getMonth() + 1 }}/{{ new Date(achievement.unlockedAt).getDate() }}</time>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="description">{{ i18n.ts._achievements._types['_' + achievement.name].description }}</div>
|
<div :class="'.description'">{{ i18n.ts._achievements._types['_' + achievement.name].description }}</div>
|
||||||
<div v-if="i18n.ts._achievements._types['_' + achievement.name].flavor" class="flavor">{{ i18n.ts._achievements._types['_' + achievement.name].flavor }}</div>
|
<div v-if="i18n.ts._achievements._types['_' + achievement.name].flavor" :class="'.flavor'">{{ i18n.ts._achievements._types['_' + achievement.name].flavor }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="withLocked">
|
<template v-if="withLocked">
|
||||||
<div v-for="achievement in lockedAchievements" :key="achievement" class="_panel achievement locked" @click="achievement === 'clickedClickHere' ? clickHere() : () => {}">
|
<div v-for="achievement in lockedAchievements" :key="achievement" :class="['.achievement', '.locked']" class="_panel" @click="achievement === 'clickedClickHere' ? clickHere() : () => {}">
|
||||||
<div class="icon">
|
<div :class="'.icon'">
|
||||||
</div>
|
</div>
|
||||||
<div class="body">
|
<div :class="'.body'">
|
||||||
<div class="header">
|
<div :class="'.header'">
|
||||||
<span class="title">???</span>
|
<span :class="'.title'">???</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="description">???</div>
|
<div :class="'.description'">???</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -36,27 +36,27 @@
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<MkLoading/>
|
<MkLoading/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import * as misskey from 'misskey-js';
|
import * as misskey from 'misskey-js';
|
||||||
import { onMounted } from 'vue';
|
import { onMounted } from 'vue';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { ACHIEVEMENT_TYPES, ACHIEVEMENT_BADGES, claimAchievement } from '@/scripts/achievements';
|
import { ACHIEVEMENT_TYPES, ACHIEVEMENT_BADGES, claimAchievement } from '@/scripts/achievements';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
user: misskey.entities.User;
|
user: misskey.entities.User;
|
||||||
withLocked: boolean;
|
withLocked: boolean;
|
||||||
}>(), {
|
}>(), {
|
||||||
withLocked: true,
|
withLocked: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let achievements = $ref();
|
let achievements = $ref();
|
||||||
const lockedAchievements = $computed(() => ACHIEVEMENT_TYPES.filter(x => !(achievements ?? []).some(a => a.name === x)));
|
const lockedAchievements = $computed(() => ACHIEVEMENT_TYPES.filter(x => !(achievements ?? []).some(a => a.name === x)));
|
||||||
|
|
||||||
function fetch() {
|
function fetch() {
|
||||||
os.api('users/achievements', { userId: props.user.id }).then(res => {
|
os.api('users/achievements', { userId: props.user.id }).then(res => {
|
||||||
achievements = [];
|
achievements = [];
|
||||||
for (const t of ACHIEVEMENT_TYPES) {
|
for (const t of ACHIEVEMENT_TYPES) {
|
||||||
|
@ -65,46 +65,46 @@ function fetch() {
|
||||||
}
|
}
|
||||||
//achievements = res.sort((a, b) => b.unlockedAt - a.unlockedAt);
|
//achievements = res.sort((a, b) => b.unlockedAt - a.unlockedAt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickHere() {
|
function clickHere() {
|
||||||
claimAchievement('clickedClickHere');
|
claimAchievement('clickedClickHere');
|
||||||
fetch();
|
fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetch();
|
fetch();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.root {
|
.root {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, min(380px, 100%));
|
grid-template-columns: repeat(auto-fill, min(380px, 100%));
|
||||||
grid-gap: 12px;
|
grid-gap: 12px;
|
||||||
place-content: center;
|
place-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.achievement {
|
.achievement {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
|
||||||
&.locked {
|
&.locked {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes shine {
|
@keyframes shine {
|
||||||
0% { translate: -30px; }
|
0% { translate: -30px; }
|
||||||
100% { translate: -130px; }
|
100% { translate: -130px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconFrame {
|
.iconFrame {
|
||||||
width: 58px;
|
width: 58px;
|
||||||
height: 58px;
|
height: 58px;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
|
@ -115,22 +115,22 @@ onMounted(() => {
|
||||||
filter: drop-shadow(0px 2px 2px #00000044);
|
filter: drop-shadow(0px 2px 2px #00000044);
|
||||||
box-shadow: 0 1px 0px #ffffff88 inset;
|
box-shadow: 0 1px 0px #ffffff88 inset;
|
||||||
overflow: clip;
|
overflow: clip;
|
||||||
}
|
}
|
||||||
.iconFrame_bronze {
|
.iconFrame_bronze {
|
||||||
background: linear-gradient(0deg, #703827, #d37566);
|
background: linear-gradient(0deg, #703827, #d37566);
|
||||||
|
|
||||||
> .iconInner {
|
> .iconInner {
|
||||||
background: linear-gradient(0deg, #d37566, #703827);
|
background: linear-gradient(0deg, #d37566, #703827);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.iconFrame_silver {
|
.iconFrame_silver {
|
||||||
background: linear-gradient(0deg, #7c7c7c, #e1e1e1);
|
background: linear-gradient(0deg, #7c7c7c, #e1e1e1);
|
||||||
|
|
||||||
> .iconInner {
|
> .iconInner {
|
||||||
background: linear-gradient(0deg, #e1e1e1, #7c7c7c);
|
background: linear-gradient(0deg, #e1e1e1, #7c7c7c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.iconFrame_gold {
|
.iconFrame_gold {
|
||||||
background: linear-gradient(0deg, rgba(255,182,85,1) 0%, rgba(233,133,0,1) 49%, rgba(255,243,93,1) 51%, rgba(255,187,25,1) 100%);
|
background: linear-gradient(0deg, rgba(255,182,85,1) 0%, rgba(233,133,0,1) 49%, rgba(255,243,93,1) 51%, rgba(255,187,25,1) 100%);
|
||||||
|
|
||||||
> .iconInner {
|
> .iconInner {
|
||||||
|
@ -149,8 +149,8 @@ onMounted(() => {
|
||||||
background: #ffffff88;
|
background: #ffffff88;
|
||||||
animation: shine 2s infinite;
|
animation: shine 2s infinite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.iconFrame_platinum {
|
.iconFrame_platinum {
|
||||||
background: linear-gradient(0deg, rgba(154,154,154,1) 0%, rgba(226,226,226,1) 49%, rgba(255,255,255,1) 51%, rgba(195,195,195,1) 100%);
|
background: linear-gradient(0deg, rgba(154,154,154,1) 0%, rgba(226,226,226,1) 49%, rgba(255,255,255,1) 51%, rgba(195,195,195,1) 100%);
|
||||||
|
|
||||||
> .iconInner {
|
> .iconInner {
|
||||||
|
@ -169,17 +169,17 @@ onMounted(() => {
|
||||||
background: #ffffffee;
|
background: #ffffffee;
|
||||||
animation: shine 2s infinite;
|
animation: shine 2s infinite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconInner {
|
.iconInner {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
box-shadow: 0 1px 0px #ffffff88 inset;
|
box-shadow: 0 1px 0px #ffffff88 inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconImg {
|
.iconImg {
|
||||||
width: calc(100% - 12px);
|
width: calc(100% - 12px);
|
||||||
height: calc(100% - 12px);
|
height: calc(100% - 12px);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -189,36 +189,37 @@ onMounted(() => {
|
||||||
left: 0;
|
left: 0;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
filter: drop-shadow(0px 1px 2px #000000aa);
|
filter: drop-shadow(0px 1px 2px #000000aa);
|
||||||
}
|
}
|
||||||
|
|
||||||
.body {
|
.body {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.time {
|
.time {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
font-size: 85%;
|
font-size: 85%;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
font-size: 85%;
|
font-size: 85%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flavor {
|
.flavor {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
transform: skewX(-15deg);
|
transform: skewX(-15deg);
|
||||||
font-size: 85%;
|
font-size: 85%;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -225,7 +225,7 @@
|
||||||
<MkA
|
<MkA
|
||||||
v-if="notification.type === 'achievementEarned'"
|
v-if="notification.type === 'achievementEarned'"
|
||||||
class="text"
|
class="text"
|
||||||
:to="/my/achievements">
|
:to="'/my/achievements'">
|
||||||
{{ i18n.ts._achievements._types['_' + notification.achievement].title }}
|
{{ i18n.ts._achievements._types['_' + notification.achievement].title }}
|
||||||
</MkA>
|
</MkA>
|
||||||
<span
|
<span
|
||||||
|
|
Loading…
Reference in a new issue