chore: format

This commit is contained in:
Kainoa Kanter 2023-04-07 17:18:13 -07:00
parent cda17e71b0
commit 6d072bbdc7
8 changed files with 510 additions and 399 deletions

View File

@ -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");

View File

@ -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>>();

View File

@ -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(() => ({

View File

@ -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(() => []);

View File

@ -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",

View File

@ -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;

View File

@ -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 =

View File

@ -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>