Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import { del, get, set } from '@/scripts/idb-proxy';
|
||||
import { reactive } from 'vue';
|
||||
import * as misskey from 'misskey-js';
|
||||
import { apiUrl } from '@/config';
|
||||
import { waiting, api, popup, popupMenu, success } from '@/os';
|
||||
import { unisonReload, reloadChannel } from '@/scripts/unison-reload';
|
||||
@ -8,13 +9,7 @@ import { i18n } from './i18n';
|
||||
|
||||
// TODO: 他のタブと永続化されたstateを同期
|
||||
|
||||
type Account = {
|
||||
id: string;
|
||||
token: string;
|
||||
isModerator: boolean;
|
||||
isAdmin: boolean;
|
||||
isDeleted: boolean;
|
||||
};
|
||||
type Account = misskey.entities.MeDetailed;
|
||||
|
||||
const data = localStorage.getItem('account');
|
||||
|
||||
|
@ -157,7 +157,7 @@ export default defineComponent({
|
||||
items: [],
|
||||
mfmTags: [],
|
||||
select: -1,
|
||||
zIndex: os.claimZIndex(true),
|
||||
zIndex: os.claimZIndex('high'),
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" :prefer-type="'dialog'" :front="true" @click="done(true)" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" :prefer-type="'dialog'" :z-priority="'high'" @click="done(true)" @closed="$emit('closed')">
|
||||
<div class="mk-dialog">
|
||||
<div v-if="icon" class="icon">
|
||||
<i :class="icon"></i>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" v-slot="{ type, maxHeight }" :prefer-type="asReactionPicker && $store.state.reactionPickerUseDrawerForMobile === false ? 'popup' : 'auto'" :transparent-bg="true" :manual-showing="manualShowing" :src="src" :front="true" @click="$refs.modal.close()" @opening="opening" @close="$emit('close')" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" v-slot="{ type, maxHeight }" :z-priority="'middle'" :prefer-type="asReactionPicker && $store.state.reactionPickerUseDrawerForMobile === false ? 'popup' : 'auto'" :transparent-bg="true" :manual-showing="manualShowing" :src="src" @click="$refs.modal.close()" @opening="opening" @close="$emit('close')" @closed="$emit('closed')">
|
||||
<MkEmojiPicker ref="picker" class="ryghynhb _popup _shadow" :class="{ drawer: type === 'drawer' }" :show-pinned="showPinned" :as-reaction-picker="asReactionPicker" :as-drawer="type === 'drawer'" :max-height="maxHeight" @chosen="chosen"/>
|
||||
</MkModal>
|
||||
</template>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" :z-priority="'middle'" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<div class="xubzgfga">
|
||||
<header>{{ image.name }}</header>
|
||||
<img :src="image.url" :alt="image.comment" :title="image.comment" @click="$refs.modal.close()"/>
|
||||
|
74
packages/client/src/components/notification-toast.vue
Normal file
74
packages/client/src/components/notification-toast.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div class="mk-notification-toast" :style="{ zIndex }">
|
||||
<transition name="notification-toast" appear @after-leave="$emit('closed')">
|
||||
<XNotification v-if="showing" :notification="notification" class="notification _acrylic"/>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import XNotification from './notification.vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XNotification
|
||||
},
|
||||
props: {
|
||||
notification: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
emits: ['closed'],
|
||||
data() {
|
||||
return {
|
||||
showing: true,
|
||||
zIndex: os.claimZIndex('high'),
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
setTimeout(() => {
|
||||
this.showing = false;
|
||||
}, 6000);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notification-toast-enter-active, .notification-toast-leave-active {
|
||||
transition: opacity 0.3s, transform 0.3s !important;
|
||||
}
|
||||
.notification-toast-enter-from, .notification-toast-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(-250px);
|
||||
}
|
||||
|
||||
.mk-notification-toast {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
top: 32px;
|
||||
padding: 0 32px;
|
||||
pointer-events: none;
|
||||
|
||||
@media (max-width: 700px) {
|
||||
top: initial;
|
||||
bottom: 112px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
bottom: 92px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
> .notification {
|
||||
height: 100%;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,74 +1,70 @@
|
||||
<template>
|
||||
<div class="mk-toast" :style="{ zIndex }">
|
||||
<transition name="notification-slide" appear @after-leave="$emit('closed')">
|
||||
<XNotification v-if="showing" :notification="notification" class="notification _acrylic"/>
|
||||
<div class="mk-toast">
|
||||
<transition name="toast" appear @after-leave="$emit('closed')">
|
||||
<div v-if="showing" class="body _acrylic" :style="{ zIndex }">
|
||||
<div class="message">
|
||||
{{ message }}
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import XNotification from './notification.vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XNotification
|
||||
},
|
||||
props: {
|
||||
notification: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
message: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ['closed'],
|
||||
data() {
|
||||
return {
|
||||
showing: true,
|
||||
zIndex: os.claimZIndex(true),
|
||||
zIndex: os.claimZIndex('high'),
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
setTimeout(() => {
|
||||
this.showing = false;
|
||||
}, 6000);
|
||||
}, 4000);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notification-slide-enter-active, .notification-slide-leave-active {
|
||||
.toast-enter-active, .toast-leave-active {
|
||||
transition: opacity 0.3s, transform 0.3s !important;
|
||||
}
|
||||
.notification-slide-enter-from, .notification-slide-leave-to {
|
||||
.toast-enter-from, .toast-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(-250px);
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.mk-toast {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
top: 32px;
|
||||
padding: 0 32px;
|
||||
pointer-events: none;
|
||||
|
||||
@media (max-width: 700px) {
|
||||
top: initial;
|
||||
bottom: 112px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
bottom: 92px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
> .notification {
|
||||
height: 100%;
|
||||
> .body {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
margin: 0 auto;
|
||||
margin-top: 16px;
|
||||
min-width: 300px;
|
||||
max-width: calc(100% - 32px);
|
||||
width: min-content;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
overflow: clip;
|
||||
text-align: center;
|
||||
pointer-events: none;
|
||||
|
||||
> .message {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<transition :name="$store.state.animation ? 'fade' : ''" appear>
|
||||
<div class="nvlagfpb" @contextmenu.prevent.stop="() => {}">
|
||||
<div class="nvlagfpb" :style="{ zIndex }" @contextmenu.prevent.stop="() => {}">
|
||||
<MkMenu :items="items" class="_popup _shadow" :align="'left'" @close="$emit('closed')"/>
|
||||
</div>
|
||||
</transition>
|
||||
@ -10,6 +10,7 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import contains from '@/scripts/contains';
|
||||
import MkMenu from './menu.vue';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -29,6 +30,11 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
emits: ['closed'],
|
||||
data() {
|
||||
return {
|
||||
zIndex: os.claimZIndex('high'),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
keymap(): any {
|
||||
return {
|
||||
@ -82,7 +88,6 @@ export default defineComponent({
|
||||
<style lang="scss" scoped>
|
||||
.nvlagfpb {
|
||||
position: absolute;
|
||||
z-index: 65535;
|
||||
}
|
||||
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
|
@ -280,8 +280,7 @@ export default defineComponent({
|
||||
|
||||
> .divider {
|
||||
margin: 8px 0;
|
||||
height: 1px;
|
||||
background: var(--divider);
|
||||
border-top: solid 0.5px var(--divider);
|
||||
}
|
||||
|
||||
&.asDrawer {
|
||||
|
@ -49,10 +49,10 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: 'auto',
|
||||
},
|
||||
front: {
|
||||
type: Boolean,
|
||||
zPriority: {
|
||||
type: String as PropType<'low' | 'middle' | 'high'>,
|
||||
required: false,
|
||||
default: false,
|
||||
default: 'low',
|
||||
},
|
||||
noOverlap: {
|
||||
type: Boolean,
|
||||
@ -74,7 +74,7 @@ export default defineComponent({
|
||||
const transformOrigin = ref('center');
|
||||
const showing = ref(true);
|
||||
const content = ref<HTMLElement>();
|
||||
const zIndex = os.claimZIndex(props.front);
|
||||
const zIndex = os.claimZIndex(props.zPriority);
|
||||
const type = computed(() => {
|
||||
if (props.preferType === 'auto') {
|
||||
if (isTouchUsing && window.innerWidth < 500 && window.innerHeight < 1000) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" v-slot="{ type, maxHeight }" :src="src" :transparent-bg="true" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" v-slot="{ type, maxHeight }" :z-priority="'high'" :src="src" :transparent-bg="true" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<MkMenu :items="items" :align="align" :width="width" :max-height="maxHeight" :as-drawer="type === 'drawer'" class="sfhdhdhq _popup _shadow" :class="{ drawer: type === 'drawer' }" @close="$refs.modal.close()"/>
|
||||
</MkModal>
|
||||
</template>
|
||||
|
@ -34,7 +34,7 @@ export default defineComponent({
|
||||
|
||||
setup(props, context) {
|
||||
const el = ref<HTMLElement>();
|
||||
const zIndex = os.claimZIndex(true);
|
||||
const zIndex = os.claimZIndex('high');
|
||||
|
||||
const setPosition = () => {
|
||||
if (el.value == null) return;
|
||||
|
@ -155,7 +155,7 @@ export default defineComponent({
|
||||
|
||||
// 最前面へ移動
|
||||
top() {
|
||||
(this.$el as any).style.zIndex = os.claimZIndex(this.front);
|
||||
(this.$el as any).style.zIndex = os.claimZIndex(this.front ? 'middle' : 'low');
|
||||
},
|
||||
|
||||
onBodyMousedown() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" :z-priority="'middle'" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<div class="ewlycnyt">
|
||||
<div class="title">{{ $ts.misskeyUpdated }}</div>
|
||||
<div class="version">✨{{ version }}🚀</div>
|
||||
|
@ -35,7 +35,7 @@ export default defineComponent({
|
||||
u: null,
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: os.claimZIndex(),
|
||||
zIndex: os.claimZIndex('middle'),
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -65,7 +65,7 @@ export default defineComponent({
|
||||
fetched: false,
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: os.claimZIndex(),
|
||||
zIndex: os.claimZIndex('middle'),
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" :src="src" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" :z-priority="'high'" :src="src" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||
<div class="gqyayizv _popup">
|
||||
<button key="public" class="_button" :class="{ active: v == 'public' }" data-index="1" @click="choose('public')">
|
||||
<div><i class="fas fa-globe"></i></div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MkModal ref="modal" :prefer-type="'dialog'" @click="success ? done() : () => {}" @closed="$emit('closed')">
|
||||
<MkModal ref="modal" :prefer-type="'dialog'" :z-priority="'high'" @click="success ? done() : () => {}" @closed="$emit('closed')">
|
||||
<div class="iuyakobc" :class="{ iconOnly: (text == null) || success }">
|
||||
<i v-if="success" class="fas fa-check icon success"></i>
|
||||
<i v-else class="fas fa-spinner fa-pulse icon waiting"></i>
|
||||
|
@ -26,7 +26,7 @@ import { router } from '@/router';
|
||||
import { applyTheme } from '@/scripts/theme';
|
||||
import { isDeviceDarkmode } from '@/scripts/is-device-darkmode';
|
||||
import { i18n } from '@/i18n';
|
||||
import { stream, confirm, alert, post, popup } from '@/os';
|
||||
import { stream, confirm, alert, post, popup, toast } from '@/os';
|
||||
import * as sound from '@/scripts/sound';
|
||||
import { $i, refreshAccount, login, updateAccount, signout } from '@/account';
|
||||
import { defaultStore, ColdDeviceStorage } from '@/store';
|
||||
@ -342,6 +342,18 @@ if ($i) {
|
||||
});
|
||||
}
|
||||
|
||||
const lastUsed = localStorage.getItem('lastUsed');
|
||||
if (lastUsed) {
|
||||
const lastUsedDate = parseInt(lastUsed, 10);
|
||||
// 二時間以上前なら
|
||||
if (Date.now() - lastUsedDate > 1000 * 60 * 60 * 2) {
|
||||
toast(i18n.t('welcomeBackWithName', {
|
||||
name: $i.name || $i.username,
|
||||
}));
|
||||
}
|
||||
}
|
||||
localStorage.setItem('lastUsed', Date.now().toString());
|
||||
|
||||
if ('Notification' in window) {
|
||||
// 許可を得ていなかったらリクエスト
|
||||
if (Notification.permission === 'default') {
|
||||
|
@ -162,16 +162,14 @@ export const popups = ref([]) as Ref<{
|
||||
props: Record<string, any>;
|
||||
}[]>;
|
||||
|
||||
let popupZIndex = 1000000;
|
||||
let popupZIndexForFront = 2000000;
|
||||
export function claimZIndex(front = false): number {
|
||||
if (front) {
|
||||
popupZIndexForFront += 100;
|
||||
return popupZIndexForFront;
|
||||
} else {
|
||||
popupZIndex += 100;
|
||||
return popupZIndex;
|
||||
}
|
||||
const zIndexes = {
|
||||
low: 1000000,
|
||||
middle: 2000000,
|
||||
high: 3000000,
|
||||
};
|
||||
export function claimZIndex(priority: 'low' | 'middle' | 'high' = 'low'): number {
|
||||
zIndexes[priority] += 100;
|
||||
return zIndexes[priority];
|
||||
}
|
||||
|
||||
export async function popup(component: Component | typeof import('*.vue') | Promise<Component | typeof import('*.vue')>, props: Record<string, any>, events = {}, disposeEvent?: string) {
|
||||
@ -223,7 +221,9 @@ export function modalPageWindow(path: string) {
|
||||
}
|
||||
|
||||
export function toast(message: string) {
|
||||
// TODO
|
||||
popup(import('@/components/toast.vue'), {
|
||||
message
|
||||
}, {}, 'closed');
|
||||
}
|
||||
|
||||
export function alert(props: {
|
||||
|
@ -12,7 +12,6 @@
|
||||
import { defineComponent } from 'vue';
|
||||
import * as os from '@/os';
|
||||
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
||||
import VanillaTilt from 'vanilla-tilt';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -22,17 +21,6 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.$store.animation) {
|
||||
VanillaTilt.init(this.$el, {
|
||||
reverse: true,
|
||||
gyroscope: false,
|
||||
scale: 1.1,
|
||||
speed: 500,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
menu(ev) {
|
||||
os.popupMenu([{
|
||||
@ -59,8 +47,6 @@ export default defineComponent({
|
||||
text-align: left;
|
||||
background: var(--panel);
|
||||
border-radius: 8px;
|
||||
transform-style: preserve-3d;
|
||||
transform: perspective(1000px);
|
||||
|
||||
&:hover {
|
||||
border-color: var(--accent);
|
||||
@ -69,14 +55,12 @@ export default defineComponent({
|
||||
> .img {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
transform: translateZ(20px);
|
||||
}
|
||||
|
||||
> .body {
|
||||
padding: 0 0 0 8px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
transform: translateZ(10px);
|
||||
|
||||
> .name {
|
||||
text-overflow: ellipsis;
|
||||
|
@ -30,7 +30,10 @@
|
||||
<option :value="3">{{ $ts.large }}</option>
|
||||
</FormRadios>
|
||||
|
||||
<FormSwitch v-model="reactionPickerUseDrawerForMobile" class="_formBlock">{{ $ts.useDrawerReactionPickerForMobile }}</FormSwitch>
|
||||
<FormSwitch v-model="reactionPickerUseDrawerForMobile" class="_formBlock">
|
||||
{{ $ts.useDrawerReactionPickerForMobile }}
|
||||
<template #caption>{{ $ts.needReloadToApply }}</template>
|
||||
</FormSwitch>
|
||||
|
||||
<FormSection>
|
||||
<div style="display: flex; gap: var(--margin); flex-wrap: wrap;">
|
||||
|
@ -34,7 +34,7 @@ export default defineComponent({
|
||||
id: notification.id
|
||||
});
|
||||
|
||||
popup(import('@/components/toast.vue'), {
|
||||
popup(import('@/components/notification-toast.vue'), {
|
||||
notification
|
||||
}, {}, 'closed');
|
||||
}
|
||||
@ -60,7 +60,7 @@ export default defineComponent({
|
||||
#wait {
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 3000000;
|
||||
z-index: 4000000;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
|
||||
|
@ -25,7 +25,7 @@ export default defineComponent({
|
||||
data() {
|
||||
return {
|
||||
uploads: os.uploads,
|
||||
zIndex: os.claimZIndex(true),
|
||||
zIndex: os.claimZIndex('high'),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -82,7 +82,7 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
const columns = deckStore.reactiveState.columns;
|
||||
const layout = deckStore.reactiveState.layout.value;
|
||||
const layout = deckStore.reactiveState.layout;
|
||||
const menuIndicated = computed(() => {
|
||||
if ($i == null) return false;
|
||||
for (const def in menuDef) {
|
||||
|
Reference in New Issue
Block a user