This commit is contained in:
syuilo 2025-05-02 08:42:26 +09:00
parent e60abb509a
commit e096841d35
8 changed files with 69 additions and 4 deletions

16
locales/index.d.ts vendored
View File

@ -5717,6 +5717,22 @@ export interface Locale extends ILocale {
*
*/
"enableSyncThemesBetweenDevices": string;
/**
*
*/
"realtimeMode_description": string;
/**
*
*/
"contentsUpdateFrequency": string;
/**
*
*/
"contentsUpdateFrequency_description": string;
/**
*
*/
"contentsUpdateFrequency_description2": string;
"_chat": {
/**
*

View File

@ -1429,6 +1429,10 @@ _settings:
ifOn: "オンのとき"
ifOff: "オフのとき"
enableSyncThemesBetweenDevices: "デバイス間でインストールしたテーマを同期"
realtimeMode_description: "サーバーと接続を確立し、リアルタイムでコンテンツを更新します。通信量とバッテリーの消費が多くなる場合があります。"
contentsUpdateFrequency: "コンテンツの取得頻度"
contentsUpdateFrequency_description: "高いほどリアルタイムにコンテンツが更新されますが、パフォーマンスが低下し、通信量とバッテリーの消費が多くなります。"
contentsUpdateFrequency_description2: "リアルタイムモードがオンのときは、この設定に関わらずリアルタイムでコンテンツが更新されます。"
_chat:
showSenderName: "送信者の名前を表示"

View File

@ -78,7 +78,12 @@ const paginator = usePagination({
},
});
const POLLING_INTERVAL = 1000 * 15;
const MIN_POLLING_INTERVAL = 1000 * 10;
const POLLING_INTERVAL =
prefer.s.pollingInterval === 1 ? MIN_POLLING_INTERVAL :
prefer.s.pollingInterval === 2 ? MIN_POLLING_INTERVAL * 1.5 :
prefer.s.pollingInterval === 3 ? MIN_POLLING_INTERVAL * 1.5 * 1.5 :
MIN_POLLING_INTERVAL;
if (!store.s.realtimeMode) {
useInterval(async () => {

View File

@ -109,7 +109,12 @@ type TimelineQueryType = {
let adInsertionCounter = 0;
const POLLING_INTERVAL = 1000 * 15;
const MIN_POLLING_INTERVAL = 1000 * 10;
const POLLING_INTERVAL =
prefer.s.pollingInterval === 1 ? MIN_POLLING_INTERVAL :
prefer.s.pollingInterval === 2 ? MIN_POLLING_INTERVAL * 1.5 :
prefer.s.pollingInterval === 3 ? MIN_POLLING_INTERVAL * 1.5 * 1.5 :
MIN_POLLING_INTERVAL;
if (!store.s.realtimeMode) {
useInterval(async () => {

View File

@ -41,6 +41,24 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkRadios>
</SearchMarker>
<SearchMarker :keywords="['realtimemode']">
<MkSwitch v-model="realtimeMode">
<template #label><SearchLabel>{{ i18n.ts.realtimeMode }}</SearchLabel></template>
<template #caption><SearchKeyword>{{ i18n.ts._settings.realtimeMode_description }}</SearchKeyword></template>
</MkSwitch>
</SearchMarker>
<MkDisableSection :disabled="realtimeMode">
<SearchMarker :keywords="['polling', 'interval']">
<MkPreferenceContainer k="pollingInterval">
<MkRange v-model="pollingInterval" :min="1" :max="3" :step="1" easing :textConverter="(v) => v === 1 ? i18n.ts.low : v === 2 ? i18n.ts.middle : v === 3 ? i18n.ts.high : ''">
<template #label><SearchLabel>{{ i18n.ts._settings.contentsUpdateFrequency }}</SearchLabel></template>
<template #caption><SearchKeyword>{{ i18n.ts._settings.contentsUpdateFrequency_description }}</SearchKeyword><br><SearchKeyword>{{ i18n.ts._settings.contentsUpdateFrequency_description2 }}</SearchKeyword></template>
</MkRange>
</MkPreferenceContainer>
</SearchMarker>
</MkDisableSection>
<div class="_gaps_s">
<SearchMarker :keywords="['titlebar', 'show']">
<MkPreferenceContainer k="showTitlebar">
@ -717,7 +735,7 @@ import MkRadios from '@/components/MkRadios.vue';
import MkRange from '@/components/MkRange.vue';
import MkFolder from '@/components/MkFolder.vue';
import MkButton from '@/components/MkButton.vue';
import FormSection from '@/components/form/section.vue';
import MkDisableSection from '@/components/MkDisableSection.vue';
import FormLink from '@/components/form/link.vue';
import MkLink from '@/components/MkLink.vue';
import MkInfo from '@/components/MkInfo.vue';
@ -740,8 +758,10 @@ const $i = ensureSignin();
const lang = ref(miLocalStorage.getItem('lang'));
const dataSaver = ref(prefer.s.dataSaver);
const realtimeMode = computed(store.makeGetterSetter('realtimeMode'));
const overridedDeviceKind = prefer.model('overridedDeviceKind');
const pollingInterval = prefer.model('pollingInterval');
const showTitlebar = prefer.model('showTitlebar');
const keepCw = prefer.model('keepCw');
const serverDisconnectedBehavior = prefer.model('serverDisconnectedBehavior');
@ -824,6 +844,8 @@ watch(useSystemFont, () => {
watch([
hemisphere,
lang,
realtimeMode,
pollingInterval,
enableInfiniteScroll,
showNoteActionsOnlyHover,
overridedDeviceKind,

View File

@ -241,6 +241,12 @@ export const PREF_DEF = {
numberOfPageCache: {
default: 3,
},
pollingInterval: {
// 1 ... 低
// 2 ... 中
// 3 ... 高
default: 2,
},
showNoteActionsOnlyHover: {
default: false,
},

View File

@ -11,6 +11,7 @@ import { useStream } from '@/stream.js';
import { $i } from '@/i.js';
import { store } from '@/store.js';
import { misskeyApi } from '@/utility/misskey-api.js';
import { prefer } from '@/preferences.js';
export const noteEvents = new EventEmitter<{
[ev: `reacted:${string}`]: (ctx: { userId: Misskey.entities.User['id']; reaction: string; emoji?: { name: string; url: string; }; }) => void;
@ -59,7 +60,12 @@ function pollingDequeue(note: Pick<Misskey.entities.Note, 'id' | 'createdAt'>) {
}
const CAPTURE_MAX = 30;
const POLLING_INTERVAL = 1000 * 15;
const MIN_POLLING_INTERVAL = 1000 * 10;
const POLLING_INTERVAL =
prefer.s.pollingInterval === 1 ? MIN_POLLING_INTERVAL :
prefer.s.pollingInterval === 2 ? MIN_POLLING_INTERVAL * 1.5 :
prefer.s.pollingInterval === 3 ? MIN_POLLING_INTERVAL * 1.5 * 1.5 :
MIN_POLLING_INTERVAL;
window.setInterval(() => {
const ids = [...pollingQueue.entries()]

View File

@ -64,6 +64,7 @@ export function usePagination<T extends MisskeyEntity>(props: {
async function init(): Promise<void> {
items.value = [];
queue.value = [];
fetching.value = true;
const params = props.ctx.params ? isRef(props.ctx.params) ? props.ctx.params.value : props.ctx.params : {};
await misskeyApi<T[]>(props.ctx.endpoint, {