enhance(client): アップデート時にも花火
This commit is contained in:
parent
82c4f694a0
commit
3b617fafdd
|
@ -10,12 +10,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { shallowRef } from 'vue';
|
import { onMounted, shallowRef } from 'vue';
|
||||||
import MkModal from '@/components/MkModal.vue';
|
import MkModal from '@/components/MkModal.vue';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import MkSparkle from '@/components/MkSparkle.vue';
|
import MkSparkle from '@/components/MkSparkle.vue';
|
||||||
import { version } from '@/config';
|
import { version } from '@/config';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
|
import { confetti } from '@/scripts/confetti';
|
||||||
|
|
||||||
const modal = shallowRef<InstanceType<typeof MkModal>>();
|
const modal = shallowRef<InstanceType<typeof MkModal>>();
|
||||||
|
|
||||||
|
@ -23,6 +24,10 @@ const whatIsNew = () => {
|
||||||
modal.value.close();
|
modal.value.close();
|
||||||
window.open(`https://misskey-hub.net/docs/releases.html#_${version.replace(/\./g, '-')}`, '_blank');
|
window.open(`https://misskey-hub.net/docs/releases.html#_${version.replace(/\./g, '-')}`, '_blank');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
confetti();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -110,7 +110,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent, computed, inject, onMounted, onUnmounted, watch } from 'vue';
|
import { defineAsyncComponent, computed, inject, onMounted, onUnmounted, watch } from 'vue';
|
||||||
import calcAge from 's-age';
|
import calcAge from 's-age';
|
||||||
import confetti from 'canvas-confetti';
|
|
||||||
import * as misskey from 'misskey-js';
|
import * as misskey from 'misskey-js';
|
||||||
import XUserTimeline from './index.timeline.vue';
|
import XUserTimeline from './index.timeline.vue';
|
||||||
import XNote from '@/components/MkNote.vue';
|
import XNote from '@/components/MkNote.vue';
|
||||||
|
@ -129,6 +128,7 @@ import { useRouter } from '@/router';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { $i } from '@/account';
|
import { $i } from '@/account';
|
||||||
import { dateString } from '@/filters/date';
|
import { dateString } from '@/filters/date';
|
||||||
|
import { confetti } from '@/scripts/confetti';
|
||||||
|
|
||||||
const XPhotos = defineAsyncComponent(() => import('./index.photos.vue'));
|
const XPhotos = defineAsyncComponent(() => import('./index.photos.vue'));
|
||||||
const XActivity = defineAsyncComponent(() => import('./index.activity.vue'));
|
const XActivity = defineAsyncComponent(() => import('./index.activity.vue'));
|
||||||
|
@ -156,29 +156,6 @@ const age = $computed(() => {
|
||||||
return calcAge(props.user.birthday);
|
return calcAge(props.user.birthday);
|
||||||
});
|
});
|
||||||
|
|
||||||
function birthdayEffect() {
|
|
||||||
const duration = 1000 * 5;
|
|
||||||
const animationEnd = Date.now() + duration;
|
|
||||||
const defaults = { startVelocity: 30, spread: 360, ticks: 60, zIndex: os.claimZIndex('high') };
|
|
||||||
|
|
||||||
function randomInRange(min, max) {
|
|
||||||
return Math.random() * (max - min) + min;
|
|
||||||
}
|
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
const timeLeft = animationEnd - Date.now();
|
|
||||||
|
|
||||||
if (timeLeft <= 0) {
|
|
||||||
return clearInterval(interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
const particleCount = 50 * (timeLeft / duration);
|
|
||||||
// since particles fall down, start a bit higher than random
|
|
||||||
confetti(Object.assign({}, defaults, { particleCount, origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 } }));
|
|
||||||
confetti(Object.assign({}, defaults, { particleCount, origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 } }));
|
|
||||||
}, 250);
|
|
||||||
}
|
|
||||||
|
|
||||||
function menu(ev) {
|
function menu(ev) {
|
||||||
os.popupMenu(getUserMenu(props.user, router), ev.currentTarget ?? ev.target);
|
os.popupMenu(getUserMenu(props.user, router), ev.currentTarget ?? ev.target);
|
||||||
}
|
}
|
||||||
|
@ -211,7 +188,7 @@ onMounted(() => {
|
||||||
const bm = parseInt(props.user.birthday.split('-')[1]);
|
const bm = parseInt(props.user.birthday.split('-')[1]);
|
||||||
const bd = parseInt(props.user.birthday.split('-')[2]);
|
const bd = parseInt(props.user.birthday.split('-')[2]);
|
||||||
if (m === bm && d === bd) {
|
if (m === bm && d === bd) {
|
||||||
birthdayEffect();
|
confetti();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import _confetti from 'canvas-confetti';
|
||||||
|
import * as os from '@/os';
|
||||||
|
|
||||||
|
export function confetti() {
|
||||||
|
const duration = 1000 * 5;
|
||||||
|
const animationEnd = Date.now() + duration;
|
||||||
|
const defaults = { startVelocity: 30, spread: 360, ticks: 60, zIndex: os.claimZIndex('high') };
|
||||||
|
|
||||||
|
function randomInRange(min, max) {
|
||||||
|
return Math.random() * (max - min) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
const timeLeft = animationEnd - Date.now();
|
||||||
|
|
||||||
|
if (timeLeft <= 0) {
|
||||||
|
return clearInterval(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
const particleCount = 50 * (timeLeft / duration);
|
||||||
|
// since particles fall down, start a bit higher than random
|
||||||
|
_confetti(Object.assign({}, defaults, { particleCount, origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 } }));
|
||||||
|
_confetti(Object.assign({}, defaults, { particleCount, origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 } }));
|
||||||
|
}, 250);
|
||||||
|
}
|
Loading…
Reference in New Issue