chore: format
This commit is contained in:
parent
cda17e71b0
commit
6d072bbdc7
|
@ -10,7 +10,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed, provide, onUnmounted } from "vue";
|
||||
import XNotes from "@/components/MkNotes.vue";
|
||||
import { defaultStore } from "@/store";
|
||||
import { defaultStore } from "@/store";
|
||||
import { stream } from "@/stream";
|
||||
import * as sound from "@/scripts/sound";
|
||||
import { $i } from "@/account";
|
||||
|
@ -97,14 +97,14 @@ if (props.src === "antenna") {
|
|||
endpoint = "notes/global-timeline";
|
||||
connection = stream.useChannel("globalTimeline");
|
||||
connection.on("note", prepend);
|
||||
} else if (props.src === 'featured') {
|
||||
endpoint = 'notes/featured';
|
||||
} else if (props.src === "featured") {
|
||||
endpoint = "notes/featured";
|
||||
query = {
|
||||
origin: 'combined',
|
||||
origin: "combined",
|
||||
offsetMode: true,
|
||||
days: 5,
|
||||
limit: 10,
|
||||
}
|
||||
};
|
||||
} else if (props.src === "mentions") {
|
||||
endpoint = "notes/mentions";
|
||||
connection = stream.useChannel("main");
|
||||
|
|
|
@ -154,16 +154,22 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, defineAsyncComponent, defineComponent, ref, toRef } from 'vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import MkInput from '@/components/form/input.vue';
|
||||
import MkPagination from '@/components/MkPagination.vue';
|
||||
import MkSwitch from '@/components/form/switch.vue';
|
||||
import FormSplit from '@/components/form/split.vue';
|
||||
import { selectFile, selectFiles } from '@/scripts/select-file';
|
||||
import * as os from '@/os';
|
||||
import { i18n } from '@/i18n';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
import {
|
||||
computed,
|
||||
defineAsyncComponent,
|
||||
defineComponent,
|
||||
ref,
|
||||
toRef,
|
||||
} from "vue";
|
||||
import MkButton from "@/components/MkButton.vue";
|
||||
import MkInput from "@/components/form/input.vue";
|
||||
import MkPagination from "@/components/MkPagination.vue";
|
||||
import MkSwitch from "@/components/form/switch.vue";
|
||||
import FormSplit from "@/components/form/split.vue";
|
||||
import { selectFile, selectFiles } from "@/scripts/select-file";
|
||||
import * as os from "@/os";
|
||||
import { i18n } from "@/i18n";
|
||||
import { definePageMetadata } from "@/scripts/page-metadata";
|
||||
|
||||
const emojisPaginationComponent = ref<InstanceType<typeof MkPagination>>();
|
||||
|
||||
|
|
|
@ -1,26 +1,36 @@
|
|||
<template>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<div class="lznhrdub">
|
||||
<MkSpacer :content-max="1200">
|
||||
<swiper
|
||||
:modules="[Virtual]"
|
||||
:space-between="20"
|
||||
:virtual="true"
|
||||
:allow-touch-move="!(deviceKind === 'desktop' && !defaultStore.state.swipeOnDesktop)"
|
||||
@swiper="setSwiperRef"
|
||||
@slide-change="onSlideChange"
|
||||
<MkStickyContainer>
|
||||
<template #header
|
||||
><MkPageHeader
|
||||
v-model:tab="tab"
|
||||
:actions="headerActions"
|
||||
:tabs="headerTabs"
|
||||
/></template>
|
||||
<div class="lznhrdub">
|
||||
<MkSpacer :content-max="1200">
|
||||
<swiper
|
||||
:modules="[Virtual]"
|
||||
:space-between="20"
|
||||
:virtual="true"
|
||||
:allow-touch-move="
|
||||
!(
|
||||
deviceKind === 'desktop' &&
|
||||
!defaultStore.state.swipeOnDesktop
|
||||
)
|
||||
"
|
||||
@swiper="setSwiperRef"
|
||||
@slide-change="onSlideChange"
|
||||
>
|
||||
<swiper-slide>
|
||||
<XUsers/>
|
||||
</swiper-slide>
|
||||
<swiper-slide>
|
||||
<XFeatured/>
|
||||
</swiper-slide>
|
||||
</swiper>
|
||||
</MkSpacer>
|
||||
</div>
|
||||
</MkStickyContainer>
|
||||
<swiper-slide>
|
||||
<XUsers />
|
||||
</swiper-slide>
|
||||
<swiper-slide>
|
||||
<XFeatured />
|
||||
</swiper-slide>
|
||||
</swiper>
|
||||
</MkSpacer>
|
||||
</div>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -41,7 +51,7 @@ const props = defineProps<{
|
|||
tag?: string;
|
||||
}>();
|
||||
|
||||
const tabs = ['users', 'featured'];
|
||||
const tabs = ["users", "featured"];
|
||||
let tab = $ref(tabs[0]);
|
||||
watch($$(tab), () => syncSlide(tabs.indexOf(tab)));
|
||||
|
||||
|
@ -56,15 +66,18 @@ watch(
|
|||
|
||||
const headerActions = $computed(() => []);
|
||||
|
||||
const headerTabs = $computed(() => [{
|
||||
key: 'users',
|
||||
icon: 'ph-users ph-bold ph-lg',
|
||||
title: i18n.ts.users,
|
||||
}, {
|
||||
key: 'featured',
|
||||
icon: 'ph-lightning ph-bold ph-lg',
|
||||
title: i18n.ts.featured,
|
||||
}]);
|
||||
const headerTabs = $computed(() => [
|
||||
{
|
||||
key: "users",
|
||||
icon: "ph-users ph-bold ph-lg",
|
||||
title: i18n.ts.users,
|
||||
},
|
||||
{
|
||||
key: "featured",
|
||||
icon: "ph-lightning ph-bold ph-lg",
|
||||
title: i18n.ts.featured,
|
||||
},
|
||||
]);
|
||||
|
||||
definePageMetadata(
|
||||
computed(() => ({
|
||||
|
|
|
@ -1,42 +1,19 @@
|
|||
<template>
|
||||
<div class="_formRoot">
|
||||
<FormSelect v-model="lang" class="_formBlock">
|
||||
<template #label>{{ i18n.ts.uiLanguage }}</template>
|
||||
<option v-for="x in langs" :key="x[0]" :value="x[0]">{{ x[1] }}</option>
|
||||
<template #caption>
|
||||
<I18n :src="i18n.ts.i18nInfo" tag="span">
|
||||
<template #link>
|
||||
<MkLink url="https://hosted.weblate.org/engage/calckey/">Weblate</MkLink>
|
||||
</template>
|
||||
</I18n>
|
||||
</template>
|
||||
</FormSelect>
|
||||
|
||||
<FormRadios v-model="overridedDeviceKind" class="_formBlock">
|
||||
<template #label>{{ i18n.ts.overridedDeviceKind }}</template>
|
||||
<option :value="null">{{ i18n.ts.auto }}</option>
|
||||
<option value="smartphone"><i class="ph-device-mobile ph-bold ph-lg"/> {{ i18n.ts.smartphone }}</option>
|
||||
<option value="tablet"><i class="ph-device-tablet ph-bold ph-lg"/> {{ i18n.ts.tablet }}</option>
|
||||
<option value="desktop"><i class="ph-desktop ph-bold ph-lg"/> {{ i18n.ts.desktop }}</option>
|
||||
</FormRadios>
|
||||
|
||||
<FormSwitch v-model="showFixedPostForm" class="_formBlock">{{ i18n.ts.showFixedPostForm }}</FormSwitch>
|
||||
|
||||
<FormSection>
|
||||
<template #label>{{ i18n.ts.behavior }}</template>
|
||||
<FormSwitch v-model="imageNewTab" class="_formBlock">{{ i18n.ts.openImageInNewTab }}</FormSwitch>
|
||||
<FormSwitch v-model="enableInfiniteScroll" class="_formBlock">{{ i18n.ts.enableInfiniteScroll }}</FormSwitch>
|
||||
<FormSwitch v-model="useReactionPickerForContextMenu" class="_formBlock">{{ i18n.ts.useReactionPickerForContextMenu }}</FormSwitch>
|
||||
<FormSwitch v-model="swipeOnDesktop" class="_formBlock">{{ i18n.ts.swipeOnDesktop }}</FormSwitch>
|
||||
<FormSwitch v-model="enterSendsMessage" class="_formBlock">{{ i18n.ts.enterSendsMessage }}</FormSwitch>
|
||||
<FormSwitch v-model="disablePagesScript" class="_formBlock">{{ i18n.ts.disablePagesScript }}</FormSwitch>
|
||||
|
||||
<FormSelect v-model="serverDisconnectedBehavior" class="_formBlock">
|
||||
<template #label>{{ i18n.ts.whenServerDisconnected }}</template>
|
||||
<option value="reload">{{ i18n.ts._serverDisconnectedBehavior.reload }}</option>
|
||||
<option value="dialog">{{ i18n.ts._serverDisconnectedBehavior.dialog }}</option>
|
||||
<option value="quiet">{{ i18n.ts._serverDisconnectedBehavior.quiet }}</option>
|
||||
<option value="nothing">{{ i18n.ts._serverDisconnectedBehavior.nothing }}</option>
|
||||
<div class="_formRoot">
|
||||
<FormSelect v-model="lang" class="_formBlock">
|
||||
<template #label>{{ i18n.ts.uiLanguage }}</template>
|
||||
<option v-for="x in langs" :key="x[0]" :value="x[0]">
|
||||
{{ x[1] }}
|
||||
</option>
|
||||
<template #caption>
|
||||
<I18n :src="i18n.ts.i18nInfo" tag="span">
|
||||
<template #link>
|
||||
<MkLink url="https://hosted.weblate.org/engage/calckey/"
|
||||
>Weblate</MkLink
|
||||
>
|
||||
</template>
|
||||
</I18n>
|
||||
</template>
|
||||
</FormSelect>
|
||||
|
||||
<FormRadios v-model="overridedDeviceKind" class="_formBlock">
|
||||
|
@ -55,17 +32,6 @@
|
|||
</option>
|
||||
</FormRadios>
|
||||
|
||||
<FormRadios v-model="showLocalPostsInTimeline" class="_formBlock">
|
||||
<template #label>{{ i18n.ts.showLocalPosts }}</template>
|
||||
<option value="home">
|
||||
<i class="ph-house ph-bold ph-lg" /> {{ i18n.ts.homeTimeline }}
|
||||
</option>
|
||||
<option value="social">
|
||||
<i class="ph-handshake ph-bold ph-lg" />
|
||||
{{ i18n.ts.socialTimeline }}
|
||||
</option>
|
||||
</FormRadios>
|
||||
|
||||
<FormSwitch v-model="showFixedPostForm" class="_formBlock">{{
|
||||
i18n.ts.showFixedPostForm
|
||||
}}</FormSwitch>
|
||||
|
@ -108,6 +74,71 @@
|
|||
{{ i18n.ts._serverDisconnectedBehavior.nothing }}
|
||||
</option>
|
||||
</FormSelect>
|
||||
|
||||
<FormRadios v-model="overridedDeviceKind" class="_formBlock">
|
||||
<template #label>{{ i18n.ts.overridedDeviceKind }}</template>
|
||||
<option :value="null">{{ i18n.ts.auto }}</option>
|
||||
<option value="smartphone">
|
||||
<i class="ph-device-mobile ph-bold ph-lg" />
|
||||
{{ i18n.ts.smartphone }}
|
||||
</option>
|
||||
<option value="tablet">
|
||||
<i class="ph-device-tablet ph-bold ph-lg" />
|
||||
{{ i18n.ts.tablet }}
|
||||
</option>
|
||||
<option value="desktop">
|
||||
<i class="ph-desktop ph-bold ph-lg" /> {{ i18n.ts.desktop }}
|
||||
</option>
|
||||
</FormRadios>
|
||||
|
||||
<FormSwitch v-model="showFixedPostForm" class="_formBlock">{{
|
||||
i18n.ts.showFixedPostForm
|
||||
}}</FormSwitch>
|
||||
|
||||
<FormSection>
|
||||
<template #label>{{ i18n.ts.behavior }}</template>
|
||||
<FormSwitch v-model="imageNewTab" class="_formBlock">{{
|
||||
i18n.ts.openImageInNewTab
|
||||
}}</FormSwitch>
|
||||
<FormSwitch v-model="enableInfiniteScroll" class="_formBlock">{{
|
||||
i18n.ts.enableInfiniteScroll
|
||||
}}</FormSwitch>
|
||||
<FormSwitch
|
||||
v-model="useReactionPickerForContextMenu"
|
||||
class="_formBlock"
|
||||
>{{ i18n.ts.useReactionPickerForContextMenu }}</FormSwitch
|
||||
>
|
||||
<FormSwitch v-model="swipeOnDesktop" class="_formBlock">{{
|
||||
i18n.ts.swipeOnDesktop
|
||||
}}</FormSwitch>
|
||||
<FormSwitch v-model="enterSendsMessage" class="_formBlock">{{
|
||||
i18n.ts.enterSendsMessage
|
||||
}}</FormSwitch>
|
||||
<FormSwitch v-model="disablePagesScript" class="_formBlock">{{
|
||||
i18n.ts.disablePagesScript
|
||||
}}</FormSwitch>
|
||||
|
||||
<FormSelect
|
||||
v-model="serverDisconnectedBehavior"
|
||||
class="_formBlock"
|
||||
>
|
||||
<template #label>{{
|
||||
i18n.ts.whenServerDisconnected
|
||||
}}</template>
|
||||
<option value="reload">
|
||||
{{ i18n.ts._serverDisconnectedBehavior.reload }}
|
||||
</option>
|
||||
<option value="dialog">
|
||||
{{ i18n.ts._serverDisconnectedBehavior.dialog }}
|
||||
</option>
|
||||
<option value="quiet">
|
||||
{{ i18n.ts._serverDisconnectedBehavior.quiet }}
|
||||
</option>
|
||||
<option value="nothing">
|
||||
{{ i18n.ts._serverDisconnectedBehavior.nothing }}
|
||||
</option>
|
||||
</FormSelect>
|
||||
</FormSection>
|
||||
</FormSection>
|
||||
|
||||
<FormSection>
|
||||
|
@ -260,32 +291,76 @@ async function reloadAsk() {
|
|||
unisonReload();
|
||||
}
|
||||
|
||||
const overridedDeviceKind = computed(defaultStore.makeGetterSetter('overridedDeviceKind'));
|
||||
const serverDisconnectedBehavior = computed(defaultStore.makeGetterSetter('serverDisconnectedBehavior'));
|
||||
const reduceAnimation = computed(defaultStore.makeGetterSetter('animation', v => !v, v => !v));
|
||||
const useBlurEffectForModal = computed(defaultStore.makeGetterSetter('useBlurEffectForModal'));
|
||||
const useBlurEffect = computed(defaultStore.makeGetterSetter('useBlurEffect'));
|
||||
const showGapBetweenNotesInTimeline = computed(defaultStore.makeGetterSetter('showGapBetweenNotesInTimeline'));
|
||||
const showAds = computed(defaultStore.makeGetterSetter('showAds'));
|
||||
const disableAnimatedMfm = computed(defaultStore.makeGetterSetter('animatedMfm', v => !v, v => !v));
|
||||
const useOsNativeEmojis = computed(defaultStore.makeGetterSetter('useOsNativeEmojis'));
|
||||
const disableDrawer = computed(defaultStore.makeGetterSetter('disableDrawer'));
|
||||
const disableShowingAnimatedImages = computed(defaultStore.makeGetterSetter('disableShowingAnimatedImages'));
|
||||
const loadRawImages = computed(defaultStore.makeGetterSetter('loadRawImages'));
|
||||
const imageNewTab = computed(defaultStore.makeGetterSetter('imageNewTab'));
|
||||
const nsfw = computed(defaultStore.makeGetterSetter('nsfw'));
|
||||
const disablePagesScript = computed(defaultStore.makeGetterSetter('disablePagesScript'));
|
||||
const showFixedPostForm = computed(defaultStore.makeGetterSetter('showFixedPostForm'));
|
||||
const numberOfPageCache = computed(defaultStore.makeGetterSetter('numberOfPageCache'));
|
||||
const instanceTicker = computed(defaultStore.makeGetterSetter('instanceTicker'));
|
||||
const enableInfiniteScroll = computed(defaultStore.makeGetterSetter('enableInfiniteScroll'));
|
||||
const enterSendsMessage = computed(defaultStore.makeGetterSetter('enterSendsMessage'));
|
||||
const useReactionPickerForContextMenu = computed(defaultStore.makeGetterSetter('useReactionPickerForContextMenu'));
|
||||
const seperateRenoteQuote = computed(defaultStore.makeGetterSetter('seperateRenoteQuote'));
|
||||
const squareAvatars = computed(defaultStore.makeGetterSetter('squareAvatars'));
|
||||
const showUpdates = computed(defaultStore.makeGetterSetter('showUpdates'));
|
||||
const swipeOnDesktop = computed(defaultStore.makeGetterSetter('swipeOnDesktop'));
|
||||
const showAdminUpdates = computed(defaultStore.makeGetterSetter('showAdminUpdates'));
|
||||
const overridedDeviceKind = computed(
|
||||
defaultStore.makeGetterSetter("overridedDeviceKind")
|
||||
);
|
||||
const serverDisconnectedBehavior = computed(
|
||||
defaultStore.makeGetterSetter("serverDisconnectedBehavior")
|
||||
);
|
||||
const reduceAnimation = computed(
|
||||
defaultStore.makeGetterSetter(
|
||||
"animation",
|
||||
(v) => !v,
|
||||
(v) => !v
|
||||
)
|
||||
);
|
||||
const useBlurEffectForModal = computed(
|
||||
defaultStore.makeGetterSetter("useBlurEffectForModal")
|
||||
);
|
||||
const useBlurEffect = computed(defaultStore.makeGetterSetter("useBlurEffect"));
|
||||
const showGapBetweenNotesInTimeline = computed(
|
||||
defaultStore.makeGetterSetter("showGapBetweenNotesInTimeline")
|
||||
);
|
||||
const showAds = computed(defaultStore.makeGetterSetter("showAds"));
|
||||
const disableAnimatedMfm = computed(
|
||||
defaultStore.makeGetterSetter(
|
||||
"animatedMfm",
|
||||
(v) => !v,
|
||||
(v) => !v
|
||||
)
|
||||
);
|
||||
const useOsNativeEmojis = computed(
|
||||
defaultStore.makeGetterSetter("useOsNativeEmojis")
|
||||
);
|
||||
const disableDrawer = computed(defaultStore.makeGetterSetter("disableDrawer"));
|
||||
const disableShowingAnimatedImages = computed(
|
||||
defaultStore.makeGetterSetter("disableShowingAnimatedImages")
|
||||
);
|
||||
const loadRawImages = computed(defaultStore.makeGetterSetter("loadRawImages"));
|
||||
const imageNewTab = computed(defaultStore.makeGetterSetter("imageNewTab"));
|
||||
const nsfw = computed(defaultStore.makeGetterSetter("nsfw"));
|
||||
const disablePagesScript = computed(
|
||||
defaultStore.makeGetterSetter("disablePagesScript")
|
||||
);
|
||||
const showFixedPostForm = computed(
|
||||
defaultStore.makeGetterSetter("showFixedPostForm")
|
||||
);
|
||||
const numberOfPageCache = computed(
|
||||
defaultStore.makeGetterSetter("numberOfPageCache")
|
||||
);
|
||||
const instanceTicker = computed(
|
||||
defaultStore.makeGetterSetter("instanceTicker")
|
||||
);
|
||||
const enableInfiniteScroll = computed(
|
||||
defaultStore.makeGetterSetter("enableInfiniteScroll")
|
||||
);
|
||||
const enterSendsMessage = computed(
|
||||
defaultStore.makeGetterSetter("enterSendsMessage")
|
||||
);
|
||||
const useReactionPickerForContextMenu = computed(
|
||||
defaultStore.makeGetterSetter("useReactionPickerForContextMenu")
|
||||
);
|
||||
const seperateRenoteQuote = computed(
|
||||
defaultStore.makeGetterSetter("seperateRenoteQuote")
|
||||
);
|
||||
const squareAvatars = computed(defaultStore.makeGetterSetter("squareAvatars"));
|
||||
const showUpdates = computed(defaultStore.makeGetterSetter("showUpdates"));
|
||||
const swipeOnDesktop = computed(
|
||||
defaultStore.makeGetterSetter("swipeOnDesktop")
|
||||
);
|
||||
const showAdminUpdates = computed(
|
||||
defaultStore.makeGetterSetter("showAdminUpdates")
|
||||
);
|
||||
|
||||
watch(lang, () => {
|
||||
localStorage.setItem("lang", lang.value as string);
|
||||
|
@ -308,23 +383,26 @@ watch(useSystemFont, () => {
|
|||
}
|
||||
});
|
||||
|
||||
watch([
|
||||
lang,
|
||||
fontSize,
|
||||
useSystemFont,
|
||||
enableInfiniteScroll,
|
||||
squareAvatars,
|
||||
showGapBetweenNotesInTimeline,
|
||||
instanceTicker,
|
||||
overridedDeviceKind,
|
||||
showAds,
|
||||
showUpdates,
|
||||
swipeOnDesktop,
|
||||
seperateRenoteQuote,
|
||||
showAdminUpdates,
|
||||
], async () => {
|
||||
await reloadAsk();
|
||||
});
|
||||
watch(
|
||||
[
|
||||
lang,
|
||||
fontSize,
|
||||
useSystemFont,
|
||||
enableInfiniteScroll,
|
||||
squareAvatars,
|
||||
showGapBetweenNotesInTimeline,
|
||||
instanceTicker,
|
||||
overridedDeviceKind,
|
||||
showAds,
|
||||
showUpdates,
|
||||
swipeOnDesktop,
|
||||
seperateRenoteQuote,
|
||||
showAdminUpdates,
|
||||
],
|
||||
async () => {
|
||||
await reloadAsk();
|
||||
}
|
||||
);
|
||||
|
||||
const headerActions = $computed(() => []);
|
||||
|
||||
|
|
|
@ -73,48 +73,48 @@ const { t, ts } = i18n;
|
|||
|
||||
useCssModule();
|
||||
|
||||
const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
|
||||
'menu',
|
||||
'visibility',
|
||||
'localOnly',
|
||||
'statusbars',
|
||||
'widgets',
|
||||
'tl',
|
||||
'forYouTl',
|
||||
'discoverTl',
|
||||
'overridedDeviceKind',
|
||||
'serverDisconnectedBehavior',
|
||||
'nsfw',
|
||||
'showAds',
|
||||
'animation',
|
||||
'animatedMfm',
|
||||
'loadRawImages',
|
||||
'imageNewTab',
|
||||
'disableShowingAnimatedImages',
|
||||
'disablePagesScript',
|
||||
'enterSendsMessage',
|
||||
'useOsNativeEmojis',
|
||||
'disableDrawer',
|
||||
'useBlurEffectForModal',
|
||||
'useBlurEffect',
|
||||
'showFixedPostForm',
|
||||
'enableInfiniteScroll',
|
||||
'useReactionPickerForContextMenu',
|
||||
'showGapBetweenNotesInTimeline',
|
||||
'instanceTicker',
|
||||
'reactionPickerSize',
|
||||
'reactionPickerWidth',
|
||||
'reactionPickerHeight',
|
||||
'reactionPickerUseDrawerForMobile',
|
||||
'defaultSideView',
|
||||
'menuDisplay',
|
||||
'reportError',
|
||||
'squareAvatars',
|
||||
'numberOfPageCache',
|
||||
'showUpdates',
|
||||
'swipeOnDesktop',
|
||||
'showAdminUpdates',
|
||||
'enableCustomKaTeXMacro',
|
||||
const defaultStoreSaveKeys: (keyof (typeof defaultStore)["state"])[] = [
|
||||
"menu",
|
||||
"visibility",
|
||||
"localOnly",
|
||||
"statusbars",
|
||||
"widgets",
|
||||
"tl",
|
||||
"forYouTl",
|
||||
"discoverTl",
|
||||
"overridedDeviceKind",
|
||||
"serverDisconnectedBehavior",
|
||||
"nsfw",
|
||||
"showAds",
|
||||
"animation",
|
||||
"animatedMfm",
|
||||
"loadRawImages",
|
||||
"imageNewTab",
|
||||
"disableShowingAnimatedImages",
|
||||
"disablePagesScript",
|
||||
"enterSendsMessage",
|
||||
"useOsNativeEmojis",
|
||||
"disableDrawer",
|
||||
"useBlurEffectForModal",
|
||||
"useBlurEffect",
|
||||
"showFixedPostForm",
|
||||
"enableInfiniteScroll",
|
||||
"useReactionPickerForContextMenu",
|
||||
"showGapBetweenNotesInTimeline",
|
||||
"instanceTicker",
|
||||
"reactionPickerSize",
|
||||
"reactionPickerWidth",
|
||||
"reactionPickerHeight",
|
||||
"reactionPickerUseDrawerForMobile",
|
||||
"defaultSideView",
|
||||
"menuDisplay",
|
||||
"reportError",
|
||||
"squareAvatars",
|
||||
"numberOfPageCache",
|
||||
"showUpdates",
|
||||
"swipeOnDesktop",
|
||||
"showAdminUpdates",
|
||||
"enableCustomKaTeXMacro",
|
||||
];
|
||||
const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [
|
||||
"lightTheme",
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
<template>
|
||||
<MkSpacer :content-max="800">
|
||||
<MkTab v-model="tab" style="margin-bottom: var(--margin);">
|
||||
<MkTab v-model="tab" style="margin-bottom: var(--margin)">
|
||||
<option value="hot">{{ i18n.ts._timelines.hot }}</option>
|
||||
<option v-if="isRecommendedTimelineAvailable" value="recommended">{{ i18n.ts._timelines.recommended }}</option>
|
||||
<option v-if="isGlobalTimelineAvailable" value="global">{{ i18n.ts._timelines.global }}</option>
|
||||
<option v-if="isRecommendedTimelineAvailable" value="recommended">
|
||||
{{ i18n.ts._timelines.recommended }}
|
||||
</option>
|
||||
<option v-if="isGlobalTimelineAvailable" value="global">
|
||||
{{ i18n.ts._timelines.global }}
|
||||
</option>
|
||||
</MkTab>
|
||||
<XTimeline
|
||||
v-if="tab === 'hot'"
|
||||
|
@ -30,25 +34,23 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import XTimeline from '@/components/MkTimeline.vue';
|
||||
import MkTab from '@/components/MkTab.vue';
|
||||
import { defaultStore } from '@/store';
|
||||
import { i18n } from '@/i18n';
|
||||
import { instance } from '@/instance';
|
||||
import { $i } from '@/account';
|
||||
import XTimeline from "@/components/MkTimeline.vue";
|
||||
import MkTab from "@/components/MkTab.vue";
|
||||
import { defaultStore } from "@/store";
|
||||
import { i18n } from "@/i18n";
|
||||
import { instance } from "@/instance";
|
||||
import { $i } from "@/account";
|
||||
|
||||
const tab = $computed({
|
||||
get: () => defaultStore.reactiveState.discoverTl.value.src,
|
||||
set: (x) => saveSrc(x),
|
||||
});
|
||||
|
||||
function saveSrc(
|
||||
newSrc: 'hot' | 'recommended' | 'global',
|
||||
): void {
|
||||
defaultStore.set('discoverTl', {
|
||||
function saveSrc(newSrc: "hot" | "recommended" | "global"): void {
|
||||
defaultStore.set("discoverTl", {
|
||||
...defaultStore.state.discoverTl,
|
||||
src: newSrc
|
||||
})
|
||||
src: newSrc,
|
||||
});
|
||||
}
|
||||
|
||||
const isRecommendedTimelineAvailable = !instance.disableRecommendedTimeline;
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
<template>
|
||||
<MkSpacer :content-max="800">
|
||||
<MkTab v-model="tab" style="margin-bottom: var(--margin);">
|
||||
<option v-if="isLocalTimelineAvailable" value="social">{{ i18n.ts._timelines.social }}</option>
|
||||
<MkTab v-model="tab" style="margin-bottom: var(--margin)">
|
||||
<option v-if="isLocalTimelineAvailable" value="social">
|
||||
{{ i18n.ts._timelines.social }}
|
||||
</option>
|
||||
<option value="home">{{ i18n.ts._timelines.home }}</option>
|
||||
<option value="local" v-if="isLocalTimelineAvailable">{{ i18n.ts._timelines.local }}</option>
|
||||
<option value="local" v-if="isLocalTimelineAvailable">
|
||||
{{ i18n.ts._timelines.local }}
|
||||
</option>
|
||||
</MkTab>
|
||||
<XTimeline
|
||||
v-if="tab === 'social'"
|
||||
|
@ -30,25 +34,23 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import XTimeline from '@/components/MkTimeline.vue';
|
||||
import MkTab from '@/components/MkTab.vue';
|
||||
import { defaultStore } from '@/store';
|
||||
import { i18n } from '@/i18n';
|
||||
import { instance } from '@/instance';
|
||||
import { $i } from '@/account';
|
||||
import XTimeline from "@/components/MkTimeline.vue";
|
||||
import MkTab from "@/components/MkTab.vue";
|
||||
import { defaultStore } from "@/store";
|
||||
import { i18n } from "@/i18n";
|
||||
import { instance } from "@/instance";
|
||||
import { $i } from "@/account";
|
||||
|
||||
const tab = $computed({
|
||||
get: () => defaultStore.reactiveState.forYouTl.value.src,
|
||||
set: (x) => saveSrc(x),
|
||||
});
|
||||
|
||||
function saveSrc(
|
||||
newSrc: 'home' | 'local' | 'social',
|
||||
): void {
|
||||
defaultStore.set('forYouTl', {
|
||||
function saveSrc(newSrc: "home" | "local" | "social"): void {
|
||||
defaultStore.set("forYouTl", {
|
||||
...defaultStore.state.forYouTl,
|
||||
src: newSrc
|
||||
})
|
||||
src: newSrc,
|
||||
});
|
||||
}
|
||||
|
||||
const isLocalTimelineAvailable =
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
class="post-form _block"
|
||||
fixed
|
||||
/>
|
||||
|
||||
|
||||
<div v-if="queue > 0" class="new">
|
||||
<button class="_buttonPrimary" @click="top()">
|
||||
{{ i18n.ts.newNoteRecived }}
|
||||
|
@ -36,218 +36,228 @@
|
|||
:modules="[Virtual]"
|
||||
:space-between="20"
|
||||
:virtual="true"
|
||||
:allow-touch-move="!(deviceKind === 'desktop' && !defaultStore.state.swipeOnDesktop)"
|
||||
:allow-touch-move="
|
||||
!(
|
||||
deviceKind === 'desktop' &&
|
||||
!defaultStore.state.swipeOnDesktop
|
||||
)
|
||||
"
|
||||
@swiper="setSwiperRef"
|
||||
@slide-change="onSlideChange"
|
||||
>
|
||||
>
|
||||
<swiper-slide>
|
||||
<XForYou/>
|
||||
<XForYou />
|
||||
</swiper-slide>
|
||||
<swiper-slide>
|
||||
<XDiscover/>
|
||||
<XDiscover />
|
||||
</swiper-slide>
|
||||
</swiper>
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, onMounted } from 'vue';
|
||||
import { Virtual } from 'swiper';
|
||||
import { Swiper, SwiperSlide } from 'swiper/vue';
|
||||
import XTutorial from '@/components/MkTutorialDialog.vue';
|
||||
import XPostForm from '@/components/MkPostForm.vue';
|
||||
import XForYou from './timeline.foryou.vue';
|
||||
import XDiscover from './timeline.discover.vue';
|
||||
import { scroll } from '@/scripts/scroll';
|
||||
import * as os from '@/os';
|
||||
import { defaultStore } from '@/store';
|
||||
import { i18n } from '@/i18n';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
import { deviceKind } from '@/scripts/device-kind';
|
||||
import 'swiper/scss';
|
||||
import 'swiper/scss/virtual';
|
||||
|
||||
if (defaultStore.reactiveState.tutorial.value !== -1) {
|
||||
os.popup(XTutorial, {}, {}, 'closed');
|
||||
}
|
||||
|
||||
let timelines = ['forYou', 'discover'];
|
||||
|
||||
const MOBILE_THRESHOLD = 500;
|
||||
|
||||
// デスクトップでウィンドウを狭くしたときモバイルUIが表示されて欲しいことはあるので deviceKind === 'desktop' の判定は行わない
|
||||
const isMobile = ref(
|
||||
deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD,
|
||||
);
|
||||
window.addEventListener('resize', () => {
|
||||
isMobile.value =
|
||||
(deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD);
|
||||
});
|
||||
|
||||
const rootEl = $ref<HTMLElement>();
|
||||
|
||||
let queue = $ref(0);
|
||||
const src = $computed({
|
||||
get: () => defaultStore.reactiveState.tl.value.src,
|
||||
set: (x) => {
|
||||
saveSrc(x);
|
||||
syncSlide(timelines.indexOf(x));
|
||||
},
|
||||
});
|
||||
|
||||
function top(): void {
|
||||
scroll(rootEl!, { top: 0 });
|
||||
}
|
||||
|
||||
async function chooseList(ev: MouseEvent): Promise<void> {
|
||||
const lists = await os.api('users/lists/list');
|
||||
const items = [{
|
||||
type: 'link' as const,
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, onMounted } from "vue";
|
||||
import { Virtual } from "swiper";
|
||||
import { Swiper, SwiperSlide } from "swiper/vue";
|
||||
import XTutorial from "@/components/MkTutorialDialog.vue";
|
||||
import XPostForm from "@/components/MkPostForm.vue";
|
||||
import XForYou from "./timeline.foryou.vue";
|
||||
import XDiscover from "./timeline.discover.vue";
|
||||
import { scroll } from "@/scripts/scroll";
|
||||
import * as os from "@/os";
|
||||
import { defaultStore } from "@/store";
|
||||
import { i18n } from "@/i18n";
|
||||
import { definePageMetadata } from "@/scripts/page-metadata";
|
||||
import { deviceKind } from "@/scripts/device-kind";
|
||||
import "swiper/scss";
|
||||
import "swiper/scss/virtual";
|
||||
|
||||
if (defaultStore.reactiveState.tutorial.value !== -1) {
|
||||
os.popup(XTutorial, {}, {}, "closed");
|
||||
}
|
||||
|
||||
let timelines = ["forYou", "discover"];
|
||||
|
||||
const MOBILE_THRESHOLD = 500;
|
||||
|
||||
// デスクトップでウィンドウを狭くしたときモバイルUIが表示されて欲しいことはあるので deviceKind === 'desktop' の判定は行わない
|
||||
const isMobile = ref(
|
||||
deviceKind === "smartphone" || window.innerWidth <= MOBILE_THRESHOLD
|
||||
);
|
||||
window.addEventListener("resize", () => {
|
||||
isMobile.value =
|
||||
deviceKind === "smartphone" || window.innerWidth <= MOBILE_THRESHOLD;
|
||||
});
|
||||
|
||||
const rootEl = $ref<HTMLElement>();
|
||||
|
||||
let queue = $ref(0);
|
||||
const src = $computed({
|
||||
get: () => defaultStore.reactiveState.tl.value.src,
|
||||
set: (x) => {
|
||||
saveSrc(x);
|
||||
syncSlide(timelines.indexOf(x));
|
||||
},
|
||||
});
|
||||
|
||||
function top(): void {
|
||||
scroll(rootEl!, { top: 0 });
|
||||
}
|
||||
|
||||
async function chooseList(ev: MouseEvent): Promise<void> {
|
||||
const lists = await os.api("users/lists/list");
|
||||
const items = [
|
||||
{
|
||||
type: "link" as const,
|
||||
text: i18n.ts.manageLists,
|
||||
icon: 'ph-faders-horizontal ph-bold ph-lg',
|
||||
to: '/my/lists',
|
||||
}].concat(lists.map((list) => ({
|
||||
type: 'link' as const,
|
||||
icon: "ph-faders-horizontal ph-bold ph-lg",
|
||||
to: "/my/lists",
|
||||
},
|
||||
].concat(
|
||||
lists.map((list) => ({
|
||||
type: "link" as const,
|
||||
text: list.name,
|
||||
icon: '',
|
||||
icon: "",
|
||||
to: `/timeline/list/${list.id}`,
|
||||
})));
|
||||
os.popupMenu(items, ev.currentTarget ?? ev.target);
|
||||
}
|
||||
|
||||
async function chooseAntenna(ev: MouseEvent): Promise<void> {
|
||||
const antennas = await os.api('antennas/list');
|
||||
const items = [{
|
||||
type: 'link' as const,
|
||||
}))
|
||||
);
|
||||
os.popupMenu(items, ev.currentTarget ?? ev.target);
|
||||
}
|
||||
|
||||
async function chooseAntenna(ev: MouseEvent): Promise<void> {
|
||||
const antennas = await os.api("antennas/list");
|
||||
const items = [
|
||||
{
|
||||
type: "link" as const,
|
||||
indicate: false,
|
||||
text: i18n.ts.manageAntennas,
|
||||
icon: 'ph-faders-horizontal ph-bold ph-lg',
|
||||
to: '/my/antennas',
|
||||
}].concat(antennas.map((antenna) => ({
|
||||
type: 'link' as const,
|
||||
icon: "ph-faders-horizontal ph-bold ph-lg",
|
||||
to: "/my/antennas",
|
||||
},
|
||||
].concat(
|
||||
antennas.map((antenna) => ({
|
||||
type: "link" as const,
|
||||
text: antenna.name,
|
||||
icon: '',
|
||||
icon: "",
|
||||
indicate: antenna.hasUnreadNote,
|
||||
to: `/timeline/antenna/${antenna.id}`,
|
||||
})));
|
||||
os.popupMenu(items, ev.currentTarget ?? ev.target);
|
||||
}
|
||||
|
||||
function saveSrc(
|
||||
newSrc: 'forYou' | 'discover',
|
||||
): void {
|
||||
defaultStore.set('tl', {
|
||||
...defaultStore.state.tl,
|
||||
src: newSrc,
|
||||
});
|
||||
}
|
||||
|
||||
function saveDiscoverSrc(
|
||||
newSrc: 'hot' | 'recommended' | 'global',
|
||||
): void {
|
||||
defaultStore.set('discoverTl', {
|
||||
...defaultStore.state.discoverTl,
|
||||
src: newSrc
|
||||
})
|
||||
}
|
||||
|
||||
const headerActions = $computed(() => [
|
||||
{
|
||||
icon: 'ph-list-bullets ph-bold ph-lg',
|
||||
title: i18n.ts.lists,
|
||||
text: i18n.ts.lists,
|
||||
iconOnly: true,
|
||||
handler: chooseList,
|
||||
},
|
||||
{
|
||||
icon: 'ph-flying-saucer ph-bold ph-lg',
|
||||
title: i18n.ts.antennas,
|
||||
text: i18n.ts.antennas,
|
||||
iconOnly: true,
|
||||
handler: chooseAntenna,
|
||||
} /* **TODO: fix timetravel** {
|
||||
}))
|
||||
);
|
||||
os.popupMenu(items, ev.currentTarget ?? ev.target);
|
||||
}
|
||||
|
||||
function saveSrc(newSrc: "forYou" | "discover"): void {
|
||||
defaultStore.set("tl", {
|
||||
...defaultStore.state.tl,
|
||||
src: newSrc,
|
||||
});
|
||||
}
|
||||
|
||||
function saveDiscoverSrc(newSrc: "hot" | "recommended" | "global"): void {
|
||||
defaultStore.set("discoverTl", {
|
||||
...defaultStore.state.discoverTl,
|
||||
src: newSrc,
|
||||
});
|
||||
}
|
||||
|
||||
const headerActions = $computed(() => [
|
||||
{
|
||||
icon: "ph-list-bullets ph-bold ph-lg",
|
||||
title: i18n.ts.lists,
|
||||
text: i18n.ts.lists,
|
||||
iconOnly: true,
|
||||
handler: chooseList,
|
||||
},
|
||||
{
|
||||
icon: "ph-flying-saucer ph-bold ph-lg",
|
||||
title: i18n.ts.antennas,
|
||||
text: i18n.ts.antennas,
|
||||
iconOnly: true,
|
||||
handler: chooseAntenna,
|
||||
} /* **TODO: fix timetravel** {
|
||||
icon: 'ph-calendar-blank ph-bold ph-lg',
|
||||
title: i18n.ts.jumpToSpecifiedDate,
|
||||
iconOnly: true,
|
||||
handler: timetravel,
|
||||
}*/,
|
||||
]);
|
||||
|
||||
const headerTabs = $computed(() => [
|
||||
{
|
||||
key: 'forYou',
|
||||
title: i18n.ts._timelines.forYou,
|
||||
icon: 'ph-house ph-bold ph-lg',
|
||||
},
|
||||
{
|
||||
key: 'discover',
|
||||
title: i18n.ts._timelines.discover,
|
||||
icon: 'ph-planet ph-bold ph-lg',
|
||||
}
|
||||
]);
|
||||
|
||||
definePageMetadata(
|
||||
computed(() => ({
|
||||
title: i18n.ts.timeline,
|
||||
icon:
|
||||
src === 'discover'
|
||||
? 'ph-planet ph-bold ph-lg'
|
||||
: 'ph-house ph-bold ph-lg',
|
||||
})),
|
||||
]);
|
||||
|
||||
const headerTabs = $computed(() => [
|
||||
{
|
||||
key: "forYou",
|
||||
title: i18n.ts._timelines.forYou,
|
||||
icon: "ph-house ph-bold ph-lg",
|
||||
},
|
||||
{
|
||||
key: "discover",
|
||||
title: i18n.ts._timelines.discover,
|
||||
icon: "ph-planet ph-bold ph-lg",
|
||||
},
|
||||
]);
|
||||
|
||||
definePageMetadata(
|
||||
computed(() => ({
|
||||
title: i18n.ts.timeline,
|
||||
icon:
|
||||
src === "discover"
|
||||
? "ph-planet ph-bold ph-lg"
|
||||
: "ph-house ph-bold ph-lg",
|
||||
}))
|
||||
);
|
||||
|
||||
let swiperRef: any = null;
|
||||
|
||||
function setSwiperRef(swiper) {
|
||||
swiperRef = swiper;
|
||||
syncSlide(timelines.indexOf(src));
|
||||
}
|
||||
|
||||
function onSlideChange() {
|
||||
saveSrc(timelines[swiperRef.activeIndex]);
|
||||
}
|
||||
|
||||
function syncSlide(index) {
|
||||
swiperRef.slideTo(index);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
syncSlide(
|
||||
timelines.indexOf(defaultStore.state.tl?.src || swiperRef.activeIndex)
|
||||
);
|
||||
|
||||
let swiperRef: any = null;
|
||||
|
||||
function setSwiperRef(swiper) {
|
||||
swiperRef = swiper;
|
||||
syncSlide(timelines.indexOf(src));
|
||||
}
|
||||
|
||||
function onSlideChange() {
|
||||
saveSrc(timelines[swiperRef.activeIndex]);
|
||||
}
|
||||
|
||||
function syncSlide(index) {
|
||||
swiperRef.slideTo(index);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
syncSlide(timelines.indexOf(defaultStore.state.tl?.src || swiperRef.activeIndex));
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cmuxhskf {
|
||||
--swiper-theme-color: var(--accent);
|
||||
|
||||
> .new {
|
||||
position: sticky;
|
||||
top: calc(var(--stickyTop, 0px) + 16px);
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
> button {
|
||||
display: block;
|
||||
margin: var(--margin) auto 0 auto;
|
||||
padding: 8px 16px;
|
||||
border-radius: 32px;
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
|
||||
> .post-form {
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
> .tl {
|
||||
background: var(--bg);
|
||||
border-radius: var(--radius);
|
||||
overflow: clip;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cmuxhskf {
|
||||
--swiper-theme-color: var(--accent);
|
||||
|
||||
> .new {
|
||||
position: sticky;
|
||||
top: calc(var(--stickyTop, 0px) + 16px);
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
> button {
|
||||
display: block;
|
||||
margin: var(--margin) auto 0 auto;
|
||||
padding: 8px 16px;
|
||||
border-radius: 32px;
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
> .post-form {
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
> .tl {
|
||||
background: var(--bg);
|
||||
border-radius: var(--radius);
|
||||
overflow: clip;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue