diff --git a/locales/en-US.yml b/locales/en-US.yml
index 42a1c93662..70a5629769 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -1461,6 +1461,9 @@ _timelines:
recommended: "Recommended"
social: "Social"
global: "Global"
+ hot: "Hot"
+ forYou: "For You"
+ discover: "Discover"
_pages:
newPage: "Create a new Page"
editPage: "Edit this Page"
diff --git a/package.json b/package.json
index 3af5dc01dc..b5c2b21a38 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "calckey",
- "version": "13.2.0-dev33",
+ "version": "13.2.0-dev34",
"codename": "aqua",
"repository": {
"type": "git",
diff --git a/packages/client/src/pages/explore.vue b/packages/client/src/pages/explore.vue
index cbc53f0667..1cf4d10cd9 100644
--- a/packages/client/src/pages/explore.vue
+++ b/packages/client/src/pages/explore.vue
@@ -10,13 +10,13 @@
:allow-touch-move="!(deviceKind === 'desktop' && !defaultStore.state.swipeOnDesktop)"
@swiper="setSwiperRef"
@slide-change="onSlideChange"
- >
-
-
-
+ >
+
+
+
diff --git a/packages/client/src/pages/timeline.vue b/packages/client/src/pages/timeline.vue
index ada88d47a2..a09ebae39b 100644
--- a/packages/client/src/pages/timeline.vue
+++ b/packages/client/src/pages/timeline.vue
@@ -39,17 +39,33 @@
:allow-touch-move="!(deviceKind === 'desktop' && !defaultStore.state.swipeOnDesktop)"
@swiper="setSwiperRef"
@slide-change="onSlideChange"
- >
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -67,6 +83,7 @@ import { Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/vue';
import XTutorial from '@/components/MkTutorialDialog.vue';
import XTimeline from '@/components/MkTimeline.vue';
+import MkTab from '@/components/MkTab.vue';
import XPostForm from '@/components/MkPostForm.vue';
import { scroll } from '@/scripts/scroll';
import * as os from '@/os';
@@ -79,6 +96,9 @@ import { deviceKind } from '@/scripts/device-kind';
import 'swiper/scss';
import 'swiper/scss/virtual';
+let forYouTab = $ref('home');
+let discoverTab = $ref('hot');
+
if (defaultStore.reactiveState.tutorial.value !== -1) {
os.popup(XTutorial, {}, {}, 'closed');
}
@@ -94,19 +114,32 @@ const keymap = {
t: focus,
};
-let timelines = ['home'];
+let timelines = ['forYou']
+
+if (isRecommendedTimelineAvailable || isGlobalTimelineAvailable) {
+ timelines.push('explore');
+}
+
+let forYouTimelines = ['home'];
+let discoverTimelines = ['hot'];
if (isLocalTimelineAvailable) {
- timelines.push('local');
+ forYouTimelines.push('local');
+ forYouTimelines.push('social');
}
if (isRecommendedTimelineAvailable) {
- timelines.push('recommended');
-}
-if (isLocalTimelineAvailable) {
- timelines.push('social');
+ discoverTimelines.push('recommended');
}
if (isGlobalTimelineAvailable) {
- timelines.push('global');
+ discoverTimelines.push('global');
+}
+
+const hotPagination = {
+ endpoint: 'notes/featured' as const,
+ limit: 20,
+ params: {
+ origin: 'combined',
+ }
}
const MOBILE_THRESHOLD = 500;
@@ -131,15 +164,25 @@ const src = $computed({
syncSlide(timelines.indexOf(x));
},
});
+const forYouSrc = $computed({
+ get: () => defaultStore.reactiveState.forYouTl.value.src,
+ set: (x) => saveForYouSrc(x),
+});
+const discoverSrc = $computed({
+ get: () => defaultStore.reactiveState.discoverTl.value.src,
+ set: (x) => saveDiscoverSrc(x),
+});
watch($$(src), () => (queue = 0));
+watch($$(forYouSrc), () => (queue = 0));
+watch($$(discoverSrc), () => (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 {
@@ -177,21 +220,28 @@ async function chooseAntenna(ev: MouseEvent): Promise {
}
function saveSrc(
- newSrc: 'home' | 'local' | 'recommended' | 'social' | 'global',
+ newSrc: 'forYou' | 'discover',
): void {
defaultStore.set('tl', {
...defaultStore.state.tl,
src: newSrc,
});
}
-
-async function timetravel(): Promise {
- const { canceled, result: date } = await os.inputDate({
- title: i18n.ts.date,
- });
- if (canceled) return;
-
- tlComponent.timetravel(date);
+function saveForYouSrc(
+ newSrc: 'home' | 'local' | 'social',
+): void {
+ defaultStore.set('forYouTl', {
+ ...defaultStore.state.forYouTl,
+ src: newSrc
+ })
+}
+function saveDiscoverSrc(
+ newSrc: 'hot' | 'recommended' | 'global',
+): void {
+ defaultStore.set('discoverTl', {
+ ...defaultStore.state.discoverTl,
+ src: newSrc
+ })
}
function focus(): void {
@@ -222,66 +272,24 @@ const headerActions = $computed(() => [
const headerTabs = $computed(() => [
{
- key: 'home',
- title: i18n.ts._timelines.home,
+ key: 'forYou',
+ title: i18n.ts._timelines.forYou,
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,
- },
- ]
- : []),
- ...(isRecommendedTimelineAvailable
- ? [
- {
- key: 'recommended',
- title: i18n.ts._timelines.recommended,
- icon: 'ph-thumbs-up ph-bold ph-lg',
- iconOnly: true,
- },
- ]
- : []),
- ...(isLocalTimelineAvailable
- ? [
- {
- key: 'social',
- title: i18n.ts._timelines.social,
- icon: 'ph-handshake ph-bold ph-lg',
- iconOnly: true,
- },
- ]
- : []),
- ...(isGlobalTimelineAvailable
- ? [
- {
- key: 'global',
- title: i18n.ts._timelines.global,
- icon: 'ph-planet ph-bold ph-lg',
- iconOnly: true,
- },
- ]
- : []),
+ {
+ 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'
- ? 'ph-handshake ph-bold ph-lg'
- : src === 'recommended'
- ? 'ph-thumbs-up ph-bold ph-lg'
- : src === 'global'
- ? 'ph-planet ph-bold ph-lg'
- : 'ph-house ph-bold ph-lg',
+ src === 'discover'
+ ? 'ph-planet ph-bold ph-lg'
+ : 'ph-house ph-bold ph-lg',
})),
);
diff --git a/packages/client/src/store.ts b/packages/client/src/store.ts
index 2de1c01b3f..307c661ad1 100644
--- a/packages/client/src/store.ts
+++ b/packages/client/src/store.ts
@@ -125,11 +125,24 @@ 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",