Compare commits

...

18 Commits

Author SHA1 Message Date
ThatOneCalculator 94b496fd83
fix 2023-04-08 20:41:08 -07:00
ThatOneCalculator 0262437975
sticky~ 2023-04-08 20:34:36 -07:00
Kainoa Kanter 6d072bbdc7 chore: format 2023-04-07 17:18:13 -07:00
Kainoa Kanter cda17e71b0 Merge branch 'develop' into experiment/timelines 2023-04-07 17:17:59 -07:00
Kainoa Kanter 3149b3a803 limits 2023-04-07 16:46:02 -07:00
Kainoa Kanter b3c166976c locales 2023-04-07 16:45:21 -07:00
Kainoa Kanter 327495c9f0 limits 2023-04-06 23:06:41 -07:00
Kainoa Kanter 67d080fecc 30 days of hot 2023-04-06 22:51:00 -07:00
Kainoa Kanter 51b908e136 Merge branch 'develop' into experiment/timelines 2023-04-06 22:49:50 -07:00
Kainoa Kanter de39c70919 style 2023-04-06 22:03:27 -07:00
Kainoa Kanter 7a3d543438 last fix 2023-04-06 20:09:21 -07:00
Kainoa Kanter 00edb30db5 proper hot tl 2023-04-06 20:02:26 -07:00
Kainoa Kanter b31dfcd752 fix, seperate 2023-04-06 19:43:48 -07:00
Kainoa Kanter 88ff928c30 fix 2023-04-06 19:23:59 -07:00
Kainoa Kanter 2ff78829c4 fix 2023-04-06 19:09:50 -07:00
Kainoa Kanter 468b14be54 fix 2023-04-06 19:06:31 -07:00
Kainoa Kanter 8229e618e9 feat: new TL layout, hot TL 2023-04-06 18:55:47 -07:00
Kainoa Kanter 0a8c1bdbc3 Revert "feat: swap home timeline with social's functionality (#9597)"
This reverts commit df68d5ffff.
2023-04-06 18:13:14 -07:00
19 changed files with 370 additions and 236 deletions

View File

@ -1027,6 +1027,27 @@ _time:
minute: "د"
hour: "سا"
day: "ي"
_tutorial:
title: "How to use Calckey"
step1_1: "Welcome!"
step1_2: "Let's get you set up. You'll be up and running in no time!"
step2_1: "First, please fill out your profile."
step2_2: "Providing some information about who you are will make it easier for others to tell if they want to see your notes or follow you."
step3_1: "Now time to follow some people!"
step3_2: "Your home and social timelines are based off of who you follow, so try following a couple accounts to get started.\nClick the plus circle on the top right of a profile to follow them."
step4_1: "Let's get you out there."
step4_2: "For your first post, some people like to made a {introduction} post or a simple \"Hello world!\""
step5_1: "Timelines, timelines everywhere!"
step5_2: "Your instance has {timelines} different timelines enabled."
step5_3: "The Home {icon} timeline is where you can see posts from your followers."
step5_4: "The Local {icon} timeline is where you can see posts from everyone else on this instance."
step5_5: "The Recommended {icon} timeline is where you can see posts from instances the admins recommend."
step5_6: "The Social {icon} timeline is where you can see posts from friends of your followers."
step5_7: "The Global {icon} timeline is where you can see posts from every other connected instance."
step6_1: "So, what is this place?"
step6_2: "Well, you didn't just join Calckey. You joined a portal to the Fediverse, an interconnected network of thousands of servers, called \"instances\"."
step6_3: "Each server works in different ways, and not all servers run Calckey. This one does though! It's a bit complicated, but you'll get the hang of it in no time."
step6_4: "Now go, explore, and have fun!"
_2fa:
alreadyRegistered: "سجلت سلفًا جهازًا للاستيثاق بعاملين."
registerDevice: "سجّل جهازًا جديدًا"

View File

@ -1108,6 +1108,27 @@ _time:
minute: "মিনিট"
hour: "ঘণ্টা"
day: "দিন"
_tutorial:
title: "How to use Calckey"
step1_1: "Welcome!"
step1_2: "Let's get you set up. You'll be up and running in no time!"
step2_1: "First, please fill out your profile."
step2_2: "Providing some information about who you are will make it easier for others to tell if they want to see your notes or follow you."
step3_1: "Now time to follow some people!"
step3_2: "Your home and social timelines are based off of who you follow, so try following a couple accounts to get started.\nClick the plus circle on the top right of a profile to follow them."
step4_1: "Let's get you out there."
step4_2: "For your first post, some people like to made a {introduction} post or a simple \"Hello world!\""
step5_1: "Timelines, timelines everywhere!"
step5_2: "Your instance has {timelines} different timelines enabled."
step5_3: "The Home {icon} timeline is where you can see posts from your followers."
step5_4: "The Local {icon} timeline is where you can see posts from everyone else on this instance."
step5_5: "The Recommended {icon} timeline is where you can see posts from instances the admins recommend."
step5_6: "The Social {icon} timeline is where you can see posts from friends of your followers."
step5_7: "The Global {icon} timeline is where you can see posts from every other connected instance."
step6_1: "So, what is this place?"
step6_2: "Well, you didn't just join Calckey. You joined a portal to the Fediverse, an interconnected network of thousands of servers, called \"instances\"."
step6_3: "Each server works in different ways, and not all servers run Calckey. This one does though! It's a bit complicated, but you'll get the hang of it in no time."
step6_4: "Now go, explore, and have fun!"
_2fa:
alreadyRegistered: "আপনি ইতিমধ্যে একটি 2-ফ্যাক্টর অথেনটিকেশন ডিভাইস নিবন্ধন করেছেন৷"
registerDevice: "নতুন ডিভাইস নিবন্ধন করুন"

View File

@ -370,13 +370,13 @@ antennaExcludeKeywords: "Keywords to exclude"
antennaKeywordsDescription: "Separate with spaces for an AND condition or with line breaks for an OR condition."
notifyAntenna: "Notify about new posts"
withFileAntenna: "Only posts with files"
enableServiceworker: "Enable Push-Notifications for your Browser"
enableServiceworker: "Enable Push Notifications for your Browser"
antennaUsersDescription: "List one username per line"
antennaInstancesDescription: "List one instance host per line"
caseSensitive: "Case sensitive"
withReplies: "Include replies"
connectedTo: "Following account(s) are connected"
notesAndReplies: "Posts and replies"
notesAndReplies: "Replies"
withFiles: "Including files"
silence: "Silence"
silenceConfirm: "Are you sure that you want to silence this user?"
@ -856,9 +856,6 @@ overridedDeviceKind: "Device type"
smartphone: "Smartphone"
tablet: "Tablet"
auto: "Auto"
showLocalPosts: "Show local posts in:"
homeTimeline: "Home Timeline"
socialTimeline: "Social Timeline"
themeColor: "Instance Ticker Color"
size: "Size"
numberOfColumn: "Number of columns"
@ -1263,10 +1260,10 @@ _tutorial:
step4_2: "For your first post, some people like to made a {introduction} post or a simple \"Hello world!\""
step5_1: "Timelines, timelines everywhere!"
step5_2: "Your instance has {timelines} different timelines enabled."
step5_3: "The Home {icon} timeline is where you can see posts from the accounts you follow and from everyone else on this instance. If you prefer your Home timeline to only display posts from accounts you follow, you can easily change this in Settings!"
step5_3: "The Home {icon} timeline is where you can see posts from your followers."
step5_4: "The Local {icon} timeline is where you can see posts from everyone else on this instance."
step5_5: "The Social {icon} timeline is where you can see posts only from the accounts you follow."
step5_6: "The Recommended {icon} timeline is where you can see posts from instances the admins recommend."
step5_5: "The Recommended {icon} timeline is where you can see posts from instances the admins recommend."
step5_6: "The Social {icon} timeline is your home + local."
step5_7: "The Global {icon} timeline is where you can see posts from every other connected instance."
step6_1: "So, what is this place?"
step6_2: "Well, you didn't just join Calckey. You joined a portal to the Fediverse, an interconnected network of thousands of servers, called \"instances\"."
@ -1460,11 +1457,14 @@ _instanceCharts:
files: "Difference in the number of files"
filesTotal: "Cumulative number of files"
_timelines:
home: "Home"
home: "Follows"
local: "Local"
recommended: "Recommended"
social: "Social"
global: "Global"
hot: "Hot"
forYou: "Home"
discover: "Discover"
_pages:
newPage: "Create a new Page"
editPage: "Edit this Page"

View File

@ -1460,11 +1460,13 @@ _instanceCharts:
files: "ファイル数の増減"
filesTotal: "ファイル数の累積"
_timelines:
home: "ホーム"
home: "フォロー"
forYou: "ホーム"
local: "ローカル"
recommended: "おすすめ"
social: "ソーシャル"
global: "グローバル"
hot: "トレンド"
_pages:
newPage: "ページの作成"
editPage: "ページの編集"

View File

@ -1174,6 +1174,27 @@ _time:
minute: "min"
hour: "hod"
day: "dní"
_tutorial:
title: "How to use Calckey"
step1_1: "Welcome!"
step1_2: "Let's get you set up. You'll be up and running in no time!"
step2_1: "First, please fill out your profile."
step2_2: "Providing some information about who you are will make it easier for others to tell if they want to see your notes or follow you."
step3_1: "Now time to follow some people!"
step3_2: "Your home and social timelines are based off of who you follow, so try following a couple accounts to get started.\nClick the plus circle on the top right of a profile to follow them."
step4_1: "Let's get you out there."
step4_2: "For your first post, some people like to made a {introduction} post or a simple \"Hello world!\""
step5_1: "Timelines, timelines everywhere!"
step5_2: "Your instance has {timelines} different timelines enabled."
step5_3: "The Home {icon} timeline is where you can see posts from your followers."
step5_4: "The Local {icon} timeline is where you can see posts from everyone else on this instance."
step5_5: "The Recommended {icon} timeline is where you can see posts from instances the admins recommend."
step5_6: "The Social {icon} timeline is where you can see posts from friends of your followers."
step5_7: "The Global {icon} timeline is where you can see posts from every other connected instance."
step6_1: "So, what is this place?"
step6_2: "Well, you didn't just join Calckey. You joined a portal to the Fediverse, an interconnected network of thousands of servers, called \"instances\"."
step6_3: "Each server works in different ways, and not all servers run Calckey. This one does though! It's a bit complicated, but you'll get the hang of it in no time."
step6_4: "Now go, explore, and have fun!"
_2fa:
alreadyRegistered: "Už ste zaregistrovali 2-faktorové autentifikačné zariadenie."
registerDevice: "Registrovať nové zariadenie"

View File

@ -1179,6 +1179,27 @@ _time:
minute: "phút"
hour: "giờ"
day: "ngày"
_tutorial:
title: "How to use Calckey"
step1_1: "Welcome!"
step1_2: "Let's get you set up. You'll be up and running in no time!"
step2_1: "First, please fill out your profile."
step2_2: "Providing some information about who you are will make it easier for others to tell if they want to see your notes or follow you."
step3_1: "Now time to follow some people!"
step3_2: "Your home and social timelines are based off of who you follow, so try following a couple accounts to get started.\nClick the plus circle on the top right of a profile to follow them."
step4_1: "Let's get you out there."
step4_2: "For your first post, some people like to made a {introduction} post or a simple \"Hello world!\""
step5_1: "Timelines, timelines everywhere!"
step5_2: "Your instance has {timelines} different timelines enabled."
step5_3: "The Home {icon} timeline is where you can see posts from your followers."
step5_4: "The Local {icon} timeline is where you can see posts from everyone else on this instance."
step5_5: "The Recommended {icon} timeline is where you can see posts from instances the admins recommend."
step5_6: "The Social {icon} timeline is where you can see posts from friends of your followers."
step5_7: "The Global {icon} timeline is where you can see posts from every other connected instance."
step6_1: "So, what is this place?"
step6_2: "Well, you didn't just join Calckey. You joined a portal to the Fediverse, an interconnected network of thousands of servers, called \"instances\"."
step6_3: "Each server works in different ways, and not all servers run Calckey. This one does though! It's a bit complicated, but you'll get the hang of it in no time."
step6_4: "Now go, explore, and have fun!"
_2fa:
alreadyRegistered: "Bạn đã đăng ký thiết bị xác minh 2 bước."
registerDevice: "Đăng ký một thiết bị"

View File

@ -1,6 +1,6 @@
{
"name": "calckey",
"version": "13.2.0-dev33",
"version": "13.2.0-dev34",
"codename": "aqua",
"repository": {
"type": "git",

View File

@ -51,11 +51,10 @@ export default defineComponent({
display: flex;
font-size: 90%;
border-radius: var(--radius);
padding: 10px 8px;
> button {
flex: 1;
padding: 10px 8px;
padding: 6px;
margin: 0 8px;
border-radius: var(--radius);
@ -82,13 +81,5 @@ export default defineComponent({
margin-right: 6px;
}
}
&.max-width_500px {
font-size: 80%;
> button {
padding: 11px 8px;
}
}
}
</style>

View File

@ -1,16 +1,16 @@
<template>
<XNotes
ref="tlComponent"
:no-gap="!$store.state.showGapBetweenNotesInTimeline"
:no-gap="!defaultStore.state.showGapBetweenNotesInTimeline"
:pagination="pagination"
@queue="emit('queue', $event)"
/>
</template>
<script lang="ts" setup>
import { ref, computed, provide, onUnmounted } from "vue";
import { computed, provide, onUnmounted } from "vue";
import XNotes from "@/components/MkNotes.vue";
import * as os from "@/os";
import { defaultStore } from "@/store";
import { stream } from "@/stream";
import * as sound from "@/scripts/sound";
import { $i } from "@/account";
@ -97,6 +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";
query = {
origin: "combined",
offsetMode: true,
days: 5,
limit: 10,
};
} else if (props.src === "mentions") {
endpoint = "notes/mentions";
connection = stream.useChannel("main");

View File

@ -164,7 +164,6 @@ import {
import MkButton from "@/components/MkButton.vue";
import MkInput from "@/components/form/input.vue";
import MkPagination from "@/components/MkPagination.vue";
import MkTab from "@/components/MkTab.vue";
import MkSwitch from "@/components/form/switch.vue";
import FormSplit from "@/components/form/split.vue";
import { selectFile, selectFiles } from "@/scripts/select-file";

View File

@ -19,11 +19,11 @@ import { i18n } from "@/i18n";
const paginationForLocal = {
endpoint: "notes/featured" as const,
limit: 10,
limit: 20,
origin: "local",
offsetMode: true,
params: {
days: 14,
days: 5,
},
};
@ -33,7 +33,6 @@ const paginationForRemote = {
offsetMode: true,
params: {
origin: "remote",
days: 7,
},
};

View File

@ -22,10 +22,10 @@
@slide-change="onSlideChange"
>
<swiper-slide>
<XFeatured />
<XUsers />
</swiper-slide>
<swiper-slide>
<XUsers />
<XFeatured />
</swiper-slide>
</swiper>
</MkSpacer>
@ -51,7 +51,7 @@ const props = defineProps<{
tag?: string;
}>();
const tabs = ["featured", "users"];
const tabs = ["users", "featured"];
let tab = $ref(tabs[0]);
watch($$(tab), () => syncSlide(tabs.indexOf(tab)));
@ -67,16 +67,16 @@ watch(
const headerActions = $computed(() => []);
const headerTabs = $computed(() => [
{
key: "featured",
icon: "ph-lightning ph-bold ph-lg",
title: i18n.ts.featured,
},
{
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(

View File

@ -32,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>
@ -85,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>
@ -240,9 +294,6 @@ async function reloadAsk() {
const overridedDeviceKind = computed(
defaultStore.makeGetterSetter("overridedDeviceKind")
);
const showLocalPostsInTimeline = computed(
defaultStore.makeGetterSetter("showLocalPostsInTimeline")
);
const serverDisconnectedBehavior = computed(
defaultStore.makeGetterSetter("serverDisconnectedBehavior")
);
@ -342,7 +393,6 @@ watch(
showGapBetweenNotesInTimeline,
instanceTicker,
overridedDeviceKind,
showLocalPostsInTimeline,
showAds,
showUpdates,
swipeOnDesktop,

View File

@ -80,8 +80,9 @@ const defaultStoreSaveKeys: (keyof (typeof defaultStore)["state"])[] = [
"statusbars",
"widgets",
"tl",
"forYouTl",
"discoverTl",
"overridedDeviceKind",
"showLocalPostsInTimeline",
"serverDisconnectedBehavior",
"nsfw",
"showAds",

View File

@ -0,0 +1,64 @@
<template>
<MkSpacer :content-max="800">
<MkStickyContainer>
<template #header style="margin: 10px; top: 62px">
<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>
</MkTab>
<XTimeline
v-if="tab === 'hot'"
ref="tl"
class="tl"
src="featured"
:sound="true"
/>
<XTimeline
v-else-if="tab === 'recommended'"
ref="tl"
class="tl"
src="recommended"
:sound="true"
/>
<XTimeline
v-else-if="tab === 'global'"
ref="tl"
class="tl"
src="global"
:sound="true"
/>
</template>
</MkStickyContainer>
</MkSpacer>
</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";
const tab = $computed({
get: () => defaultStore.reactiveState.discoverTl.value.src,
set: (x) => saveSrc(x),
});
function saveSrc(newSrc: "hot" | "recommended" | "global"): void {
defaultStore.set("discoverTl", {
...defaultStore.state.discoverTl,
src: newSrc,
});
}
const isRecommendedTimelineAvailable = !instance.disableRecommendedTimeline;
const isGlobalTimelineAvailable =
!instance.disableGlobalTimeline ||
($i != null && ($i.isModerator || $i.isAdmin));
</script>

View File

@ -0,0 +1,63 @@
<template>
<MkSpacer :content-max="800">
<MkStickyContainer>
<template #header style="margin: 10px; top: 62px">
<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>
</MkTab>
<XTimeline
v-if="tab === 'social'"
ref="tl"
class="tl"
src="social"
:sound="true"
/>
<XTimeline
v-else-if="tab === 'home'"
ref="tl"
class="tl"
src="home"
:sound="true"
/>
<XTimeline
v-else-if="tab === 'local'"
ref="tl"
class="tl"
src="local"
:sound="true"
/>
</template>
</MkStickyContainer>
</MkSpacer>
</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";
const tab = $computed({
get: () => defaultStore.reactiveState.forYouTl.value.src,
set: (x) => saveSrc(x),
});
function saveSrc(newSrc: "home" | "local" | "social"): void {
defaultStore.set("forYouTl", {
...defaultStore.state.forYouTl,
src: newSrc,
});
}
const isLocalTimelineAvailable =
!instance.disableLocalTimeline ||
($i != null && ($i.isModerator || $i.isAdmin));
</script>

View File

@ -11,7 +11,7 @@
<MkSpacer :content-max="800">
<div ref="rootEl" v-hotkey.global="keymap" class="cmuxhskf">
<XPostForm
v-if="$store.reactiveState.showFixedPostForm.value"
v-if="defaultStore.reactiveState.showFixedPostForm.value"
class="post-form _block"
fixed
/>
@ -22,15 +22,15 @@
</button>
</div>
<!-- <div v-if="!isMobile" class="tl _block">
<XTimeline
ref="tl"
:key="src"
class="tl"
:src="src"
:sound="true"
@queue="queueUpdated"
/>
</div> *v-else on next div* -->
<XTimeline
ref="tl"
:key="src"
class="tl"
:src="src"
:sound="true"
@queue="queueUpdated"
/>
</div> *v-else on next div* -->
<div class="tl _block">
<swiper
:modules="[Virtual]"
@ -45,19 +45,11 @@
@swiper="setSwiperRef"
@slide-change="onSlideChange"
>
<swiper-slide
v-for="index in timelines"
:key="index"
:virtual-index="index"
>
<XTimeline
ref="tl"
:key="src"
class="tl"
:src="src"
:sound="true"
@queue="queueUpdated"
/>
<swiper-slide>
<XForYou />
</swiper-slide>
<swiper-slide>
<XDiscover />
</swiper-slide>
</swiper>
</div>
@ -67,18 +59,17 @@
</template>
<script lang="ts" setup>
import { computed, watch, ref, onMounted } from "vue";
import { computed, ref, onMounted } from "vue";
import { Virtual } from "swiper";
import { Swiper, SwiperSlide } from "swiper/vue";
import XTutorial from "@/components/MkTutorialDialog.vue";
import XTimeline from "@/components/MkTimeline.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 { instance } from "@/instance";
import { $i } from "@/account";
import { definePageMetadata } from "@/scripts/page-metadata";
import { deviceKind } from "@/scripts/device-kind";
import "swiper/scss";
@ -88,47 +79,7 @@ if (defaultStore.reactiveState.tutorial.value !== -1) {
os.popup(XTutorial, {}, {}, "closed");
}
const isLocalTimelineAvailable =
!instance.disableLocalTimeline ||
($i != null && ($i.isModerator || $i.isAdmin));
const isRecommendedTimelineAvailable = !instance.disableRecommendedTimeline;
const isGlobalTimelineAvailable =
!instance.disableGlobalTimeline ||
($i != null && ($i.isModerator || $i.isAdmin));
const keymap = {
t: focus,
};
let timelines = [];
if (
isLocalTimelineAvailable &&
defaultStore.state.showLocalPostsInTimeline === "home"
) {
timelines.push("social");
} else {
timelines.push("home");
}
if (isLocalTimelineAvailable) {
timelines.push("local");
}
if (
isLocalTimelineAvailable &&
defaultStore.state.showLocalPostsInTimeline === "home"
) {
timelines.push("home");
} else if (isLocalTimelineAvailable) {
timelines.push("social");
}
if (isRecommendedTimelineAvailable) {
timelines.push("recommended");
}
if (isGlobalTimelineAvailable) {
timelines.push("global");
}
let timelines = ["forYou", "discover"];
const MOBILE_THRESHOLD = 500;
@ -141,7 +92,6 @@ window.addEventListener("resize", () => {
deviceKind === "smartphone" || window.innerWidth <= MOBILE_THRESHOLD;
});
const tlComponent = $ref<InstanceType<typeof XTimeline>>();
const rootEl = $ref<HTMLElement>();
let queue = $ref(0);
@ -153,14 +103,8 @@ const src = $computed({
},
});
watch($$(src), () => (queue = 0));
function queueUpdated(q: number): void {
queue = q;
}
function top(): void {
scroll(rootEl, { top: 0 });
scroll(rootEl!, { top: 0 });
}
async function chooseList(ev: MouseEvent): Promise<void> {
@ -205,26 +149,18 @@ async function chooseAntenna(ev: MouseEvent): Promise<void> {
os.popupMenu(items, ev.currentTarget ?? ev.target);
}
function saveSrc(
newSrc: "home" | "local" | "recommended" | "social" | "global"
): void {
function saveSrc(newSrc: "forYou" | "discover"): void {
defaultStore.set("tl", {
...defaultStore.state.tl,
src: newSrc,
});
}
async function timetravel(): Promise<void> {
const { canceled, result: date } = await os.inputDate({
title: i18n.ts.date,
function saveDiscoverSrc(newSrc: "hot" | "recommended" | "global"): void {
defaultStore.set("discoverTl", {
...defaultStore.state.discoverTl,
src: newSrc,
});
if (canceled) return;
tlComponent.timetravel(date);
}
function focus(): void {
tlComponent.focus();
}
const headerActions = $computed(() => [
@ -242,104 +178,32 @@ const headerActions = $computed(() => [
iconOnly: true,
handler: chooseAntenna,
} /* **TODO: fix timetravel** {
icon: 'ph-calendar-blank ph-bold ph-lg',
title: i18n.ts.jumpToSpecifiedDate,
iconOnly: true,
handler: timetravel,
}*/,
icon: 'ph-calendar-blank ph-bold ph-lg',
title: i18n.ts.jumpToSpecifiedDate,
iconOnly: true,
handler: timetravel,
}*/,
]);
// Swap home timeline with social's functionality
const headerTabs = $computed(() => [
...(isLocalTimelineAvailable &&
defaultStore.state.showLocalPostsInTimeline === "home"
? [
{
key: "social",
title: i18n.ts._timelines.home,
icon: "ph-house ph-bold ph-lg",
iconOnly: true,
},
]
: [
{
key: "home",
title: i18n.ts._timelines.home,
icon: "ph-house ph-bold ph-lg",
iconOnly: true,
},
]),
...(isLocalTimelineAvailable
? [
{
key: "local",
title: i18n.ts._timelines.local,
icon: "ph-users ph-bold ph-lg",
iconOnly: true,
},
]
: []),
...(isLocalTimelineAvailable &&
defaultStore.state.showLocalPostsInTimeline === "home"
? [
{
key: "home",
title: i18n.ts._timelines.social,
icon: "ph-handshake ph-bold ph-lg",
iconOnly: true,
},
]
: isLocalTimelineAvailable
? [
{
key: "social",
title: i18n.ts._timelines.social,
icon: "ph-handshake ph-bold ph-lg",
iconOnly: true,
},
]
: []),
...(isRecommendedTimelineAvailable
? [
{
key: "recommended",
title: i18n.ts._timelines.recommended,
icon: "ph-thumbs-up ph-bold ph-lg",
iconOnly: true,
},
]
: []),
...(isGlobalTimelineAvailable
? [
{
key: "global",
title: i18n.ts._timelines.global,
icon: "ph-planet ph-bold ph-lg",
iconOnly: true,
},
]
: []),
{
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 === "local"
? "ph-users ph-bold ph-lg"
: src === "social" &&
defaultStore.state.showLocalPostsInTimeline === "home"
? "ph-house ph-bold ph-lg"
: src === "social"
? "ph-handshake ph-bold ph-lg"
: src === "recommended"
? "ph-thumbs-up ph-bold ph-lg"
: src === "global"
src === "discover"
? "ph-planet ph-bold ph-lg"
: src === "home" &&
defaultStore.state.showLocalPostsInTimeline === "home"
? "ph-handshake ph-bold ph-lg"
: "ph-house ph-bold ph-lg",
}))
);

View File

@ -1,6 +1,6 @@
<template>
<MkStickyContainer>
<template #header>
<template #header style="margin: 10px; top: 62px">
<MkTab v-model="include" :class="$style.tab">
<option :value="null">{{ i18n.ts.notes }}</option>
<option value="replies">{{ i18n.ts.notesAndReplies }}</option>

View File

@ -128,19 +128,28 @@ export const defaultStore = markRaw(
tl: {
where: "deviceAccount",
default: {
src: "home" as "home" | "local" | "social" | "global",
src: "forYou" as "forYou" | "discover",
arg: null,
},
},
forYouTl: {
where: "deviceAccount",
default: {
src: "social" as "home" | "local" | "social",
arg: null,
},
},
discoverTl: {
where: "deviceAccount",
default: {
src: "hot" as "hot" | "recommended" | "global",
arg: null,
},
},
overridedDeviceKind: {
where: "device",
default: null as null | "smartphone" | "tablet" | "desktop",
},
showLocalPostsInTimeline: {
where: "device",
default: "home" as "home" | "social",
},
serverDisconnectedBehavior: {
where: "device",
default: "nothing" as "nothing" | "quiet" | "reload" | "dialog",