Merge 30de43163e
into 218070eb13
This commit is contained in:
commit
13cfb89719
|
@ -106,6 +106,11 @@ export async function common(createVue: () => Promise<App<Element>>) {
|
||||||
window.history.replaceState(null, '', window.location.href.replace('#pswp', ''));
|
window.history.replaceState(null, '', window.location.href.replace('#pswp', ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// URLにfolderPageのhashが含まれる場合は取り除く
|
||||||
|
if (window.location.hash.startsWith('#fp_')) {
|
||||||
|
window.history.replaceState(null, '', window.location.href.replace(window.location.hash, ''));
|
||||||
|
}
|
||||||
|
|
||||||
// 一斉リロード
|
// 一斉リロード
|
||||||
reloadChannel.addEventListener('message', path => {
|
reloadChannel.addEventListener('message', path => {
|
||||||
if (path !== null) window.location.href = path;
|
if (path !== null) window.location.href = path;
|
||||||
|
|
|
@ -96,10 +96,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { nextTick, onMounted, ref, useTemplateRef } from 'vue';
|
import { nextTick, onMounted, ref, useTemplateRef, watch } from 'vue';
|
||||||
import { prefer } from '@/preferences.js';
|
import { prefer } from '@/preferences.js';
|
||||||
import { getBgColor } from '@/utility/get-bg-color.js';
|
import { getBgColor } from '@/utility/get-bg-color.js';
|
||||||
import { pageFolderTeleportCount, popup } from '@/os.js';
|
import { popup } from '@/os.js';
|
||||||
|
import { pageFolderTeleportedIds } from '@/utility/folder-page.js';
|
||||||
|
import { genId } from '@/utility/id.js';
|
||||||
import MkFolderPage from '@/components/MkFolderPage.vue';
|
import MkFolderPage from '@/components/MkFolderPage.vue';
|
||||||
import { deviceKind } from '@/utility/device-kind.js';
|
import { deviceKind } from '@/utility/device-kind.js';
|
||||||
|
|
||||||
|
@ -123,6 +125,8 @@ const rootEl = useTemplateRef('rootEl');
|
||||||
const asPage = props.canPage && deviceKind === 'smartphone' && prefer.s['experimental.enableFolderPageView'];
|
const asPage = props.canPage && deviceKind === 'smartphone' && prefer.s['experimental.enableFolderPageView'];
|
||||||
const bgSame = ref(false);
|
const bgSame = ref(false);
|
||||||
const opened = ref(asPage ? false : props.defaultOpen);
|
const opened = ref(asPage ? false : props.defaultOpen);
|
||||||
|
const pageShowing = ref(false);
|
||||||
|
const pageId = ref(genId());
|
||||||
const openedAtLeastOnce = ref(opened.value);
|
const openedAtLeastOnce = ref(opened.value);
|
||||||
|
|
||||||
//#region interpolate-sizeに対応していないブラウザ向け(TODO: 主要ブラウザが対応したら消す)
|
//#region interpolate-sizeに対応していないブラウザ向け(TODO: 主要ブラウザが対応したら消す)
|
||||||
|
@ -161,17 +165,24 @@ function afterLeave(el: Element) {
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
let pageId = pageFolderTeleportCount.value;
|
|
||||||
pageFolderTeleportCount.value += 1000;
|
|
||||||
|
|
||||||
async function toggle() {
|
async function toggle() {
|
||||||
if (asPage && !opened.value) {
|
if (asPage && !opened.value && !pageShowing.value) {
|
||||||
pageId++;
|
if (pageFolderTeleportedIds.value.includes(pageId.value)) {
|
||||||
const { dispose } = await popup(MkFolderPage, {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pageShowing.value = true;
|
||||||
|
pageId.value = genId();
|
||||||
|
pageFolderTeleportedIds.value.push(pageId.value);
|
||||||
|
|
||||||
|
const { dispose } = popup(MkFolderPage, {
|
||||||
pageId,
|
pageId,
|
||||||
|
showing: pageShowing,
|
||||||
}, {
|
}, {
|
||||||
closed: () => {
|
closed: () => {
|
||||||
opened.value = false;
|
opened.value = false;
|
||||||
|
pageShowing.value = false;
|
||||||
|
pageFolderTeleportedIds.value = pageFolderTeleportedIds.value.filter((v) => v !== pageId.value);
|
||||||
dispose();
|
dispose();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -186,6 +197,12 @@ async function toggle() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(pageFolderTeleportedIds, (newVal) => {
|
||||||
|
if (!newVal.includes(pageId.value) && pageShowing.value) {
|
||||||
|
pageShowing.value = false;
|
||||||
|
}
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const computedStyle = getComputedStyle(window.document.documentElement);
|
const computedStyle = getComputedStyle(window.document.documentElement);
|
||||||
const parentBg = getBgColor(rootEl.value?.parentElement) ?? 'transparent';
|
const parentBg = getBgColor(rootEl.value?.parentElement) ?? 'transparent';
|
||||||
|
|
|
@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
:leaveToClass="prefer.s.animation ? $style.transition_x_leaveTo : ''"
|
:leaveToClass="prefer.s.animation ? $style.transition_x_leaveTo : ''"
|
||||||
:duration="300" appear @afterLeave="onClosed"
|
:duration="300" appear @afterLeave="onClosed"
|
||||||
>
|
>
|
||||||
<div v-show="showing" :class="[$style.root]" :style="{ zIndex }">
|
<div v-show="actualShowingState" :class="[$style.root]" :style="{ zIndex }">
|
||||||
<div :class="[$style.bg]" :style="{ zIndex }"></div>
|
<div :class="[$style.bg]" :style="{ zIndex }"></div>
|
||||||
<div :class="[$style.content]" :style="{ zIndex }">
|
<div :class="[$style.content]" :style="{ zIndex }">
|
||||||
<div :class="$style.header">
|
<div :class="$style.header">
|
||||||
|
@ -27,31 +27,30 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { claimZIndex } from '@/os.js';
|
import { claimZIndex } from '@/os.js';
|
||||||
import { prefer } from '@/preferences.js';
|
import { prefer } from '@/preferences.js';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = defineProps<{
|
||||||
pageId: number,
|
pageId: string;
|
||||||
}>(), {
|
showing: boolean;
|
||||||
pageId: 0,
|
}>();
|
||||||
});
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(_: 'closed'): void
|
(_: 'closed'): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const zIndex = claimZIndex('low');
|
const zIndex = claimZIndex('low');
|
||||||
const showing = ref(true);
|
const manualShowing = ref(true);
|
||||||
|
const actualShowingState = computed(() => props.showing && manualShowing.value);
|
||||||
|
|
||||||
function closePage() {
|
function closePage() {
|
||||||
showing.value = false;
|
manualShowing.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onClosed() {
|
function onClosed() {
|
||||||
emit('closed');
|
emit('closed');
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
|
|
|
@ -803,5 +803,3 @@ export function launchUploader(
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const pageFolderTeleportCount = ref(0);
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
|
||||||
|
const FOLDER_PAGE_HASH_PREFIX = 'fp_';
|
||||||
|
|
||||||
|
export const pageFolderTeleportedIds = ref<string[]>([]);
|
||||||
|
|
||||||
|
window.addEventListener('popstate', () => {
|
||||||
|
const newHash = location.hash.split('#')[1] ?? '';
|
||||||
|
let newHashIds: string[] | null = null;
|
||||||
|
|
||||||
|
if (newHash.startsWith(FOLDER_PAGE_HASH_PREFIX)) {
|
||||||
|
newHashIds = newHash
|
||||||
|
.slice(FOLDER_PAGE_HASH_PREFIX.length)
|
||||||
|
.split(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newHashIds === null || newHashIds.length === 0) {
|
||||||
|
pageFolderTeleportedIds.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newHashIds !== null) {
|
||||||
|
pageFolderTeleportedIds.value = newHashIds;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(pageFolderTeleportedIds, (newVal) => {
|
||||||
|
const newHash = newVal.join(',');
|
||||||
|
const expectedHash = newHash ? `#${FOLDER_PAGE_HASH_PREFIX}${newHash}` : location.pathname + location.search;
|
||||||
|
if (location.hash !== expectedHash) {
|
||||||
|
history.pushState(null, '', expectedHash);
|
||||||
|
}
|
||||||
|
}, { immediate: true, deep: true });
|
Loading…
Reference in New Issue