This commit is contained in:
mattyatea 2024-05-29 01:19:08 +09:00
parent 07b4338eff
commit 653f5cfbc2
13 changed files with 203 additions and 265 deletions

View File

@ -0,0 +1,11 @@
export class Gapikey1716911535226 {
name = 'Gapikey1716911535226'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "googleAnalyticsId" character varying(1024)`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "googleAnalyticsId"`);
}
}

View File

@ -73,6 +73,7 @@ export class MetaEntityService {
bannerLight: instance.bannerLight, bannerLight: instance.bannerLight,
iconDark: instance.iconDark, iconDark: instance.iconDark,
iconLight: instance.iconLight, iconLight: instance.iconLight,
googleAnalyticsId: instance.googleAnalyticsId,
enableHcaptcha: instance.enableHcaptcha, enableHcaptcha: instance.enableHcaptcha,
hcaptchaSiteKey: instance.hcaptchaSiteKey, hcaptchaSiteKey: instance.hcaptchaSiteKey,
enableMcaptcha: instance.enableMcaptcha, enableMcaptcha: instance.enableMcaptcha,
@ -88,6 +89,7 @@ export class MetaEntityService {
bannerUrl: instance.bannerUrl, bannerUrl: instance.bannerUrl,
infoImageUrl: instance.infoImageUrl, infoImageUrl: instance.infoImageUrl,
serverErrorImageUrl: instance.serverErrorImageUrl, serverErrorImageUrl: instance.serverErrorImageUrl,
googleAnalyticsId: instance.googleAnalyticsId,
notFoundImageUrl: instance.notFoundImageUrl, notFoundImageUrl: instance.notFoundImageUrl,
iconUrl: instance.iconUrl, iconUrl: instance.iconUrl,
backgroundImageUrl: instance.backgroundImageUrl, backgroundImageUrl: instance.backgroundImageUrl,

View File

@ -139,6 +139,11 @@ export class MiMeta {
nullable: true, nullable: true,
}) })
public serverErrorImageUrl: string | null; public serverErrorImageUrl: string | null;
@Column('varchar', {
length: 1024,
nullable: true,
})
public googleAnalyticsId: string | null;
@Column('varchar', { @Column('varchar', {
length: 1024, length: 1024,

View File

@ -50,6 +50,7 @@ export const paramDef = {
mascotImageUrl: { type: 'string', nullable: true }, mascotImageUrl: { type: 'string', nullable: true },
bannerUrl: { type: 'string', nullable: true }, bannerUrl: { type: 'string', nullable: true },
serverErrorImageUrl: { type: 'string', nullable: true }, serverErrorImageUrl: { type: 'string', nullable: true },
googleAnalyticsId: { type: 'string', nullable: true },
infoImageUrl: { type: 'string', nullable: true }, infoImageUrl: { type: 'string', nullable: true },
notFoundImageUrl: { type: 'string', nullable: true }, notFoundImageUrl: { type: 'string', nullable: true },
iconUrl: { type: 'string', nullable: true }, iconUrl: { type: 'string', nullable: true },
@ -257,7 +258,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (ps.serverErrorImageUrl !== undefined) { if (ps.serverErrorImageUrl !== undefined) {
set.serverErrorImageUrl = ps.serverErrorImageUrl; set.serverErrorImageUrl = ps.serverErrorImageUrl;
} }
if (ps.googleAnalyticsId !== undefined) {
set.googleAnalyticsId = ps.googleAnalyticsId;
}
if (ps.enableProxyCheckio !== undefined) { if (ps.enableProxyCheckio !== undefined) {
set.enableProxyCheckio = ps.enableProxyCheckio; set.enableProxyCheckio = ps.enableProxyCheckio;
} }

View File

@ -191,6 +191,7 @@ export class ClientServerService {
appleTouchIcon: meta.app512IconUrl, appleTouchIcon: meta.app512IconUrl,
themeColor: meta.themeColor, themeColor: meta.themeColor,
serverErrorImageUrl: meta.serverErrorImageUrl ?? 'https://xn--931a.moe/assets/error.jpg', serverErrorImageUrl: meta.serverErrorImageUrl ?? 'https://xn--931a.moe/assets/error.jpg',
googleAnalyticsId: meta.googleAnalyticsId ?? null,
infoImageUrl: meta.infoImageUrl ?? 'https://xn--931a.moe/assets/info.jpg', infoImageUrl: meta.infoImageUrl ?? 'https://xn--931a.moe/assets/info.jpg',
notFoundImageUrl: meta.notFoundImageUrl ?? 'https://xn--931a.moe/assets/not-found.jpg', notFoundImageUrl: meta.notFoundImageUrl ?? 'https://xn--931a.moe/assets/not-found.jpg',
instanceUrl: this.config.url, instanceUrl: this.config.url,

View File

@ -35,6 +35,14 @@ html
link(rel='prefetch' href=serverErrorImageUrl) link(rel='prefetch' href=serverErrorImageUrl)
link(rel='prefetch' href=infoImageUrl) link(rel='prefetch' href=infoImageUrl)
link(rel='prefetch' href=notFoundImageUrl) link(rel='prefetch' href=notFoundImageUrl)
if googleAnalyticsId
script(async src='https://www.googletagmanager.com/gtag/js?id='+ googleAnalyticsId)
script.
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '#{googleAnalyticsId}');
//- https://github.com/misskey-dev/misskey/issues/9842 //- https://github.com/misskey-dev/misskey/issues/9842
link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.min.css?v3.3.0') link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.min.css?v3.3.0')
link(rel='modulepreload' href=`/vite/${clientEntry.file}`) link(rel='modulepreload' href=`/vite/${clientEntry.file}`)

View File

@ -43,65 +43,73 @@ export default defineComponent({
setup(props, { slots, expose }) { setup(props, { slots, expose }) {
const $style = useCssModule(); // 使 const $style = useCssModule(); // 使
const dateTextCache = new Map<string, string>();
function getDateText(time: string) { function getDateText(time: string) {
if (dateTextCache.has(time)) {
return dateTextCache.get(time)!;
}
const date = new Date(time).getDate(); const date = new Date(time).getDate();
const month = new Date(time).getMonth() + 1; const month = new Date(time).getMonth() + 1;
return i18n.tsx.monthAndDay({ const text = i18n.tsx.monthAndDay({
month: month.toString(), month: month.toString(),
day: date.toString(), day: date.toString(),
}); });
dateTextCache.set(time, text);
return text;
} }
if (props.items.length === 0) return; if (props.items.length === 0) return;
const renderChildrenImpl = () => props.items.map((item, i) => { const renderChildrenImpl = () => {
if (!slots || !slots.default) return; const slotContent = slots.default ? slots.default : () => [];
return props.items.map((item, i) => {
const el = slotContent({
item: item,
})[0];
if (el.key == null && item.id) el.key = item.id;
const el = slots.default({ if (
item: item, i !== props.items.length - 1 &&
})[0]; new Date(item.createdAt).getDate() !== new Date(props.items[i + 1].createdAt).getDate()
if (el.key == null && item.id) el.key = item.id; ) {
const separator = h('div', {
if ( class: $style['separator'],
i !== props.items.length - 1 && key: item.id + ':separator',
new Date(item.createdAt).getDate() !== new Date(props.items[i + 1].createdAt).getDate() }, h('p', {
) { class: $style['date'],
const separator = h('div', {
class: $style['separator'],
key: item.id + ':separator',
}, h('p', {
class: $style['date'],
}, [
h('span', {
class: $style['date-1'],
}, [ }, [
h('i', { h('span', {
class: `ti ti-chevron-up ${$style['date-1-icon']}`, class: $style['date-1'],
}), }, [
getDateText(item.createdAt), h('i', {
]), class: `ti ti-chevron-up ${$style['date-1-icon']}`,
h('span', { }),
class: $style['date-2'], getDateText(item.createdAt),
}, [ ]),
getDateText(props.items[i + 1].createdAt), h('span', {
h('i', { class: $style['date-2'],
class: `ti ti-chevron-down ${$style['date-2-icon']}`, }, [
}), getDateText(props.items[i + 1].createdAt),
]), h('i', {
])); class: `ti ti-chevron-down ${$style['date-2-icon']}`,
}),
]),
]));
return [el, separator]; return [el, separator];
} else {
if (props.ad && item._shouldInsertAd_) {
return [h(MkAd, {
key: item.id + ':ad',
prefer: ['horizontal', 'horizontal-big'],
}), el];
} else { } else {
return el; if (props.ad && item._shouldInsertAd_) {
return [h(MkAd, {
key: item.id + ':ad',
prefer: ['horizontal', 'horizontal-big'],
}), el];
} else {
return el;
}
} }
} });
}); };
const renderChildren = () => { const renderChildren = () => {
const children = renderChildrenImpl(); const children = renderChildrenImpl();
@ -120,14 +128,12 @@ export default defineComponent({
function onBeforeLeave(element: Element) { function onBeforeLeave(element: Element) {
const el = element as HTMLElement; const el = element as HTMLElement;
el.style.top = `${el.offsetTop}px`; el.classList.add('before-leave');
el.style.left = `${el.offsetLeft}px`;
} }
function onLeaveCancelled(element: Element) { function onLeaveCancelled(element: Element) {
const el = element as HTMLElement; const el = element as HTMLElement;
el.style.top = ''; el.classList.remove('before-leave');
el.style.left = '';
} }
// eslint-disable-next-line vue/no-setup-props-destructure // eslint-disable-next-line vue/no-setup-props-destructure
@ -157,21 +163,21 @@ export default defineComponent({
container-type: inline-size; container-type: inline-size;
&:global { &:global {
> .list-move { > .list-move {
transition: transform 0.7s cubic-bezier(0.23, 1, 0.32, 1); transition: transform 0.7s cubic-bezier(0.23, 1, 0.32, 1);
} }
&.deny-move-transition > .list-move { &.deny-move-transition > .list-move {
transition: none !important; transition: none !important;
} }
> .list-enter-active { > .list-enter-active {
transition: transform 0.7s cubic-bezier(0.23, 1, 0.32, 1), opacity 0.7s cubic-bezier(0.23, 1, 0.32, 1); transition: transform 0.7s cubic-bezier(0.23, 1, 0.32, 1), opacity 0.7s cubic-bezier(0.23, 1, 0.32, 1);
} }
> *:empty { > *:empty {
display: none; display: none;
} }
} }
&:not(.date-separated-list-nogap) > *:not(:last-child) { &:not(.date-separated-list-nogap) > *:not(:last-child) {
@ -194,20 +200,20 @@ export default defineComponent({
.direction-up { .direction-up {
&:global { &:global {
> .list-enter-from, > .list-enter-from,
> .list-leave-to { > .list-leave-to {
opacity: 0; opacity: 0;
transform: translateY(64px); transform: translateY(64px);
} }
} }
} }
.direction-down { .direction-down {
&:global { &:global {
> .list-enter-from, > .list-enter-from,
> .list-leave-to { > .list-leave-to {
opacity: 0; opacity: 0;
transform: translateY(-64px); transform: translateY(-64px);
} }
} }
} }
@ -246,5 +252,8 @@ export default defineComponent({
.date-2-icon { .date-2-icon {
margin-left: 8px; margin-left: 8px;
} }
</style>
.before-leave {
position: absolute !important;
}
</style>

View File

@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:ad="true" :ad="true"
:class="$style.notes" :class="$style.notes"
> >
<MkNote v-if="props.withCw && !note.cw || !props.withCw" :key="note._featuredId_ || note._prId_ || note.id" :class="$style.note" :note="note" :withHardMute="true" /> <MkNote v-if="props.withCw && !note.cw || !props.withCw" :key="note._featuredId_ || note._prId_ || note.id" :class="$style.note" :note="note" :withHardMute="true"/>
</MkDateSeparatedList> </MkDateSeparatedList>
</div> </div>
</template> </template>
@ -45,7 +45,6 @@ const props = defineProps<{
disableAutoLoad?: boolean; disableAutoLoad?: boolean;
withCw?: boolean; withCw?: boolean;
}>(); }>();
const pagingComponent = shallowRef<InstanceType<typeof MkPagination>>(); const pagingComponent = shallowRef<InstanceType<typeof MkPagination>>();
defineExpose({ defineExpose({

View File

@ -234,69 +234,43 @@ const reload = (): Promise<void> => {
return init(); return init();
}; };
const fetchMore = async (): Promise<void> => { async function fetchMore(): Promise<void> {
if (!more.value || fetching.value || moreFetching.value || items.value.size === 0) return; if (!more.value || fetching.value || moreFetching.value || items.value.size === 0) return;
moreFetching.value = true; moreFetching.value = true;
const params = props.pagination.params ? isRef(props.pagination.params) ? props.pagination.params.value : props.pagination.params : {}; try {
await misskeyApi<MisskeyEntity[]>(props.pagination.endpoint, { const params = props.pagination.params ? isRef(props.pagination.params) ? props.pagination.params.value : props.pagination.params : {};
...params, const response = await misskeyApi<MisskeyEntity[]>(props.pagination.endpoint, {
limit: SECOND_FETCH_LIMIT, ...params,
...(props.pagination.offsetMode ? { limit: SECOND_FETCH_LIMIT,
offset: offset.value, ...(props.pagination.offsetMode ? { offset: offset.value } : { untilId: Array.from(items.value.keys()).pop() }),
} : { });
untilId: Array.from(items.value.keys()).at(-1),
}),
}).then(res => {
for (let i = 0; i < res.length; i++) {
const item = res[i];
if (i === 10) item._shouldInsertAd_ = true;
}
const reverseConcat = _res => { const isReversed = props.pagination.reversed;
const oldHeight = scrollableElement.value ? scrollableElement.value.scrollHeight : getBodyScrollHeight(); if (isReversed) {
const oldScroll = scrollableElement.value ? scrollableElement.value.scrollTop : window.scrollY; const oldHeight = scrollableElement.value?.scrollHeight || 0;
const oldScroll = scrollableElement.value?.scrollTop || 0;
items.value = concatMapWithArray(items.value, _res); items.value = concatMapWithArray(items.value, response);
return nextTick(() => { await nextTick();
if (scrollableElement.value) { if (scrollableElement.value) {
scroll(scrollableElement.value, { top: oldScroll + (scrollableElement.value.scrollHeight - oldHeight), behavior: 'instant' }); scroll(scrollableElement.value, {
} else { top: oldScroll + (scrollableElement.value.scrollHeight - oldHeight),
window.scroll({ top: oldScroll + (getBodyScrollHeight() - oldHeight), behavior: 'instant' }); behavior: 'instant',
}
return nextTick();
});
};
if (res.length === 0) {
if (props.pagination.reversed) {
reverseConcat(res).then(() => {
more.value = false;
moreFetching.value = false;
}); });
} else {
items.value = concatMapWithArray(items.value, res);
more.value = false;
moreFetching.value = false;
} }
} else { } else {
if (props.pagination.reversed) { items.value = concatMapWithArray(items.value, response);
reverseConcat(res).then(() => {
more.value = true;
moreFetching.value = false;
});
} else {
items.value = concatMapWithArray(items.value, res);
more.value = true;
moreFetching.value = false;
}
} }
offset.value += res.length;
}, err => { more.value = response.length > 0;
} catch (error) {
console.error(error);
} finally {
moreFetching.value = false; moreFetching.value = false;
}); }
}; }
const fetchMoreAhead = async (): Promise<void> => { const fetchMoreAhead = async (): Promise<void> => {
if (!more.value || fetching.value || moreFetching.value || items.value.size === 0) return; if (!more.value || fetching.value || moreFetching.value || items.value.size === 0) return;

View File

@ -1,8 +1,3 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->
<template> <template>
<MkPullToRefresh ref="prComponent" :refresher="() => reloadTimeline()"> <MkPullToRefresh ref="prComponent" :refresher="() => reloadTimeline()">
<MkNotes <MkNotes
@ -10,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
ref="tlComponent" ref="tlComponent"
:pagination="paginationQuery" :pagination="paginationQuery"
:noGap="!defaultStore.state.showGapBetweenNotesInTimeline" :noGap="!defaultStore.state.showGapBetweenNotesInTimeline"
:withCw="props.withCw" :withCw="props.withCw"
@queue="emit('queue', $event)" @queue="emit('queue', $event)"
@status="prComponent?.setDisabled($event)" @status="prComponent?.setDisabled($event)"
/> />
@ -39,7 +34,7 @@ const props = withDefaults(defineProps<{
withRenotes?: boolean; withRenotes?: boolean;
withReplies?: boolean; withReplies?: boolean;
onlyFiles?: boolean; onlyFiles?: boolean;
withCw?: boolean; withCw?: boolean;
}>(), { }>(), {
withRenotes: true, withRenotes: true,
withReplies: false, withReplies: false,
@ -55,24 +50,13 @@ const emit = defineEmits<{
provide('inTimeline', true); provide('inTimeline', true);
provide('inChannel', computed(() => props.src === 'channel')); provide('inChannel', computed(() => props.src === 'channel'));
type TimelineQueryType = {
antennaId?: string,
withRenotes?: boolean,
withReplies?: boolean,
withFiles?: boolean,
visibility?: string,
listId?: string,
channelId?: string,
roleId?: string
}
const prComponent = shallowRef<InstanceType<typeof MkPullToRefresh>>(); const prComponent = shallowRef<InstanceType<typeof MkPullToRefresh>>();
const tlComponent = shallowRef<InstanceType<typeof MkNotes>>(); const tlComponent = shallowRef<InstanceType<typeof MkNotes>>();
let tlNotesCount = 0; let tlNotesCount = 0;
function prepend(note) { function prepend(note) {
if (tlComponent.value == null) return; if (!tlComponent.value) return;
tlNotesCount++; tlNotesCount++;
@ -96,11 +80,8 @@ let paginationQuery: Paging | null = null;
const stream = useStream(); const stream = useStream();
function connectChannel() { function connectChannel() {
if (props.src === 'antenna') { if (props.src === 'antenna' && props.antenna) {
if (props.antenna == null) return; connection = stream.useChannel('antenna', { antennaId: props.antenna });
connection = stream.useChannel('antenna', {
antennaId: props.antenna,
});
} else if (props.src === 'home') { } else if (props.src === 'home') {
connection = stream.useChannel('homeTimeline', { connection = stream.useChannel('homeTimeline', {
withRenotes: props.withRenotes, withRenotes: props.withRenotes,
@ -119,15 +100,9 @@ function connectChannel() {
withRenotes: props.withRenotes, withRenotes: props.withRenotes,
withReplies: props.withReplies, withReplies: props.withReplies,
}); });
connection.on('note', prepend); } else if (props.src === 'social' || props.src === 'global') {
} else if (props.src === 'social') { const channel = props.src === 'social' ? 'hybridTimeline' : 'globalTimeline';
connection = stream.useChannel('hybridTimeline', { connection = stream.useChannel(channel, {
withRenotes: props.withRenotes,
withReplies: props.withReplies,
withFiles: props.onlyFiles ? true : undefined,
});
} else if (props.src === 'global') {
connection = stream.useChannel('globalTimeline', {
withRenotes: props.withRenotes, withRenotes: props.withRenotes,
withFiles: props.onlyFiles ? true : undefined, withFiles: props.onlyFiles ? true : undefined,
}); });
@ -136,34 +111,25 @@ function connectChannel() {
connection.on('mention', prepend); connection.on('mention', prepend);
} else if (props.src === 'directs') { } else if (props.src === 'directs') {
const onNote = note => { const onNote = note => {
if (note.visibility === 'specified') { if (note.visibility === 'specified') prepend(note);
prepend(note);
}
}; };
connection = stream.useChannel('main'); connection = stream.useChannel('main');
connection.on('mention', onNote); connection.on('mention', onNote);
} else if (props.src === 'list') { } else if (props.src === 'list' && props.list) {
if (props.list == null) return;
connection = stream.useChannel('userList', { connection = stream.useChannel('userList', {
withRenotes: props.withRenotes, withRenotes: props.withRenotes,
withFiles: props.onlyFiles ? true : undefined, withFiles: props.onlyFiles ? true : undefined,
listId: props.list, listId: props.list,
}); });
} else if (props.src === 'channel') { } else if (props.src === 'channel' && props.channel) {
if (props.channel == null) return; connection = stream.useChannel('channel', { channelId: props.channel });
connection = stream.useChannel('channel', { } else if (props.src === 'role' && props.role) {
channelId: props.channel, connection = stream.useChannel('roleTimeline', { roleId: props.role });
});
} else if (props.src === 'role') {
if (props.role == null) return;
connection = stream.useChannel('roleTimeline', {
roleId: props.role,
});
} }
if (props.src.startsWith('custom-timeline')) {
return; if (props.src !== 'directs' && props.src !== 'mentions') {
connection?.on('note', prepend);
} }
if (props.src !== 'directs' && props.src !== 'mentions') connection?.on('note', prepend);
} }
function disconnectChannel() { function disconnectChannel() {
@ -172,91 +138,47 @@ function disconnectChannel() {
} }
function updatePaginationQuery() { function updatePaginationQuery() {
let endpoint: keyof Misskey.Endpoints | null; const endpoints = {
let query: TimelineQueryType | null; antenna: 'antennas/notes',
home: 'notes/timeline',
local: 'notes/local-timeline',
social: 'notes/hybrid-timeline',
global: 'notes/global-timeline',
media: 'notes/hybrid-timeline',
mentions: 'notes/mentions',
directs: 'notes/mentions',
list: 'notes/user-list-timeline',
channel: 'channels/timeline',
role: 'roles/notes',
};
if (props.src === 'antenna') { const queries = {
endpoint = 'antennas/notes'; antenna: { antennaId: props.antenna },
query = { home: { withRenotes: props.withRenotes, withFiles: props.onlyFiles ? true : undefined },
antennaId: props.antenna, local: { withRenotes: props.withRenotes, withReplies: props.withReplies, withFiles: props.onlyFiles ? true : undefined },
}; social: { withRenotes: props.withRenotes, withReplies: props.withReplies, withFiles: props.onlyFiles ? true : undefined },
} else if (props.src === 'home') { global: { withRenotes: props.withRenotes, withFiles: props.onlyFiles ? true : undefined },
endpoint = 'notes/timeline'; media: { withFiles: true, withRenotes: props.withRenotes, withReplies: false },
query = { mentions: null,
withRenotes: props.withRenotes, directs: { visibility: 'specified' },
withFiles: props.onlyFiles ? true : undefined, list: { withRenotes: props.withRenotes, withFiles: props.onlyFiles ? true : undefined, listId: props.list },
}; channel: { channelId: props.channel },
} else if (props.src === 'local') { role: { roleId: props.role },
endpoint = 'notes/local-timeline'; };
query = {
withRenotes: props.withRenotes,
withReplies: props.withReplies,
withFiles: props.onlyFiles ? true : undefined,
};
} else if (props.src === 'social') {
endpoint = 'notes/hybrid-timeline';
query = {
withRenotes: props.withRenotes,
withReplies: props.withReplies,
withFiles: props.onlyFiles ? true : undefined,
};
} else if (props.src === 'global') {
endpoint = 'notes/global-timeline';
query = {
withRenotes: props.withRenotes,
withFiles: props.onlyFiles ? true : undefined,
};
} else if (props.src === 'media') {
endpoint = 'notes/hybrid-timeline';
query = {
withFiles: true,
withRenotes: props.withRenotes,
withReplies: false,
};
} else if (props.src === 'mentions') {
endpoint = 'notes/mentions';
query = null;
} else if (props.src === 'directs') {
endpoint = 'notes/mentions';
query = {
visibility: 'specified',
};
} else if (props.src === 'list') {
endpoint = 'notes/user-list-timeline';
query = {
withRenotes: props.withRenotes,
withFiles: props.onlyFiles ? true : undefined,
listId: props.list,
};
} else if (props.src === 'channel') {
endpoint = 'channels/timeline';
query = {
channelId: props.channel,
};
} else if (props.src === 'role') {
endpoint = 'roles/notes';
query = {
roleId: props.role,
};
} else if (props.src.startsWith('custom-timeline')) {
endpoint = 'notes/any-local-timeline';
query = {
host: defaultStore.state[`remoteLocalTimelineDomain${props.src.split('-')[2]}`],
remoteToken: defaultStore.state[`remoteLocalTimelineToken${props.src.split('-')[2]}`],
};
} else {
endpoint = null;
query = null;
}
if (endpoint && query) { if (props.src.startsWith('custom-timeline')) {
paginationQuery = { paginationQuery = {
endpoint: endpoint, endpoint: 'notes/any-local-timeline',
limit: 10, limit: 10,
params: query, params: {
host: defaultStore.state[`remoteLocalTimelineDomain${props.src.split('-')[2]}`],
remoteToken: defaultStore.state[`remoteLocalTimelineToken${props.src.split('-')[2]}`],
},
}; };
} else { } else {
paginationQuery = null; const endpoint = endpoints[props.src];
const query = queries[props.src];
paginationQuery = endpoint && query ? { endpoint, limit: 10, params: query } : null;
} }
} }
@ -265,12 +187,9 @@ function refreshEndpointAndChannel() {
disconnectChannel(); disconnectChannel();
connectChannel(); connectChannel();
} }
updatePaginationQuery(); updatePaginationQuery();
} }
// withRenotes
// IDTL
watch(() => [props.list, props.antenna, props.channel, props.role, props.withRenotes], refreshEndpointAndChannel); watch(() => [props.list, props.antenna, props.channel, props.role, props.withRenotes], refreshEndpointAndChannel);
// //
@ -282,13 +201,11 @@ onUnmounted(() => {
function reloadTimeline() { function reloadTimeline() {
return new Promise<void>((res) => { return new Promise<void>((res) => {
if (tlComponent.value == null) return; if (!tlComponent.value) return;
tlNotesCount = 0; tlNotesCount = 0;
tlComponent.value.pagingComponent?.reload().then(() => { tlComponent.value.pagingComponent?.reload().then(() => res());
res();
});
}); });
} }

View File

@ -32,6 +32,8 @@ export const instance: Misskey.entities.MetaDetailed = reactive(cachedMeta ?? {}
export const serverErrorImageUrl = computed(() => instance.serverErrorImageUrl ?? DEFAULT_SERVER_ERROR_IMAGE_URL); export const serverErrorImageUrl = computed(() => instance.serverErrorImageUrl ?? DEFAULT_SERVER_ERROR_IMAGE_URL);
export const googleAnalyticsId = computed(() => instance.googleAnalyticsId ?? null);
export const infoImageUrl = computed(() => instance.infoImageUrl ?? DEFAULT_INFO_IMAGE_URL); export const infoImageUrl = computed(() => instance.infoImageUrl ?? DEFAULT_INFO_IMAGE_URL);
export const notFoundImageUrl = computed(() => instance.notFoundImageUrl ?? DEFAULT_NOT_FOUND_IMAGE_URL); export const notFoundImageUrl = computed(() => instance.notFoundImageUrl ?? DEFAULT_NOT_FOUND_IMAGE_URL);

View File

@ -77,6 +77,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #prefix><i class="ti ti-link"></i></template> <template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts.somethingHappened }}</template> <template #label>{{ i18n.ts.somethingHappened }}</template>
</MkInput> </MkInput>
<MkInput v-model="googleAnalyticsId" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>googleAnal </template>
</MkInput>
<MkColorInput v-model="themeColor"> <MkColorInput v-model="themeColor">
<template #label>{{ i18n.ts.themeColor }}</template> <template #label>{{ i18n.ts.themeColor }}</template>
@ -144,6 +148,8 @@ const themeColor = ref<string | null>(null);
const defaultLightTheme = ref<string | null>(null); const defaultLightTheme = ref<string | null>(null);
const defaultDarkTheme = ref<string | null>(null); const defaultDarkTheme = ref<string | null>(null);
const serverErrorImageUrl = ref<string | null>(null); const serverErrorImageUrl = ref<string | null>(null);
const googleAnalyticsId = ref<string | null>(null);
const infoImageUrl = ref<string | null>(null); const infoImageUrl = ref<string | null>(null);
const notFoundImageUrl = ref<string | null>(null); const notFoundImageUrl = ref<string | null>(null);
const repositoryUrl = ref<string | null>(null); const repositoryUrl = ref<string | null>(null);
@ -189,6 +195,7 @@ function save() {
infoImageUrl: infoImageUrl.value === '' ? null : infoImageUrl.value, infoImageUrl: infoImageUrl.value === '' ? null : infoImageUrl.value,
notFoundImageUrl: notFoundImageUrl.value === '' ? null : notFoundImageUrl.value, notFoundImageUrl: notFoundImageUrl.value === '' ? null : notFoundImageUrl.value,
serverErrorImageUrl: serverErrorImageUrl.value === '' ? null : serverErrorImageUrl.value, serverErrorImageUrl: serverErrorImageUrl.value === '' ? null : serverErrorImageUrl.value,
googleAnalyticsId: googleAnalyticsId.value === '' ? null : googleAnalyticsId.value,
repositoryUrl: repositoryUrl.value === '' ? null : repositoryUrl.value, repositoryUrl: repositoryUrl.value === '' ? null : repositoryUrl.value,
feedbackUrl: feedbackUrl.value === '' ? null : feedbackUrl.value, feedbackUrl: feedbackUrl.value === '' ? null : feedbackUrl.value,
manifestJsonOverride: manifestJsonOverride.value === '' ? '{}' : JSON.stringify(JSON5.parse(manifestJsonOverride.value)), manifestJsonOverride: manifestJsonOverride.value === '' ? '{}' : JSON.stringify(JSON5.parse(manifestJsonOverride.value)),