Compare commits
18 Commits
main
...
experiment
Author | SHA1 | Date |
---|---|---|
ThatOneCalculator | 94b496fd83 | |
ThatOneCalculator | 0262437975 | |
Kainoa Kanter | 6d072bbdc7 | |
Kainoa Kanter | cda17e71b0 | |
Kainoa Kanter | 3149b3a803 | |
Kainoa Kanter | b3c166976c | |
Kainoa Kanter | 327495c9f0 | |
Kainoa Kanter | 67d080fecc | |
Kainoa Kanter | 51b908e136 | |
Kainoa Kanter | de39c70919 | |
Kainoa Kanter | 7a3d543438 | |
Kainoa Kanter | 00edb30db5 | |
Kainoa Kanter | b31dfcd752 | |
Kainoa Kanter | 88ff928c30 | |
Kainoa Kanter | 2ff78829c4 | |
Kainoa Kanter | 468b14be54 | |
Kainoa Kanter | 8229e618e9 | |
Kainoa Kanter | 0a8c1bdbc3 |
|
@ -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: "سجّل جهازًا جديدًا"
|
||||
|
|
|
@ -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: "নতুন ডিভাইস নিবন্ধন করুন"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1460,11 +1460,13 @@ _instanceCharts:
|
|||
files: "ファイル数の増減"
|
||||
filesTotal: "ファイル数の累積"
|
||||
_timelines:
|
||||
home: "ホーム"
|
||||
home: "フォロー"
|
||||
forYou: "ホーム"
|
||||
local: "ローカル"
|
||||
recommended: "おすすめ"
|
||||
social: "ソーシャル"
|
||||
global: "グローバル"
|
||||
hot: "トレンド"
|
||||
_pages:
|
||||
newPage: "ページの作成"
|
||||
editPage: "ページの編集"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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ị"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "calckey",
|
||||
"version": "13.2.0-dev33",
|
||||
"version": "13.2.0-dev34",
|
||||
"codename": "aqua",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -80,8 +80,9 @@ const defaultStoreSaveKeys: (keyof (typeof defaultStore)["state"])[] = [
|
|||
"statusbars",
|
||||
"widgets",
|
||||
"tl",
|
||||
"forYouTl",
|
||||
"discoverTl",
|
||||
"overridedDeviceKind",
|
||||
"showLocalPostsInTimeline",
|
||||
"serverDisconnectedBehavior",
|
||||
"nsfw",
|
||||
"showAds",
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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",
|
||||
}))
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue