merge: Fix circular dependency in following feed (!1013)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1013

Approved-by: Marie <github@yuugi.dev>
Approved-by: dakkar <dakkar@thenautilus.net>
This commit is contained in:
Hazelnoot 2025-05-12 09:38:43 +00:00
commit 1eb57201b4
8 changed files with 51 additions and 41 deletions

View file

@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script setup lang="ts"> <script setup lang="ts">
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import { computed, shallowRef } from 'vue'; import { computed, shallowRef } from 'vue';
import type { FollowingFeedTab } from '@/utility/following-feed-utils.js'; import type { FollowingFeedTab } from '@/types/following-feed.js';
import type { Paging } from '@/components/MkPagination.vue'; import type { Paging } from '@/components/MkPagination.vue';
import { infoImageUrl } from '@/instance.js'; import { infoImageUrl } from '@/instance.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';

View file

@ -11,10 +11,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue'; import { computed } from 'vue';
import type { FollowingFeedModel } from '@/utility/following-feed-utils.js'; import type { FollowingFeedModel } from '@/types/following-feed.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import MkInfo from '@/components/MkInfo.vue'; import MkInfo from '@/components/MkInfo.vue';
import { followersTab } from '@/utility/following-feed-utils.js'; import { followersTab } from '@/types/following-feed.js';
const props = defineProps<{ const props = defineProps<{
model: FollowingFeedModel, model: FollowingFeedModel,

View file

@ -33,7 +33,8 @@ import { i18n } from '@/i18n.js';
import MkSwiper from '@/components/MkSwiper.vue'; import MkSwiper from '@/components/MkSwiper.vue';
import MkPageHeader from '@/components/global/MkPageHeader.vue'; import MkPageHeader from '@/components/global/MkPageHeader.vue';
import SkUserRecentNotes from '@/components/SkUserRecentNotes.vue'; import SkUserRecentNotes from '@/components/SkUserRecentNotes.vue';
import { createModel, createHeaderItem, followingFeedTabs, followingTabIcon, followingTabName, followingTab } from '@/utility/following-feed-utils.js'; import { createModel, createHeaderItem, followingTabIcon, followingTabName } from '@/utility/following-feed-utils.js';
import { followingTab, followingFeedTabs } from '@/types/following-feed.js';
import SkFollowingRecentNotes from '@/components/SkFollowingRecentNotes.vue'; import SkFollowingRecentNotes from '@/components/SkFollowingRecentNotes.vue';
import SkRemoteFollowersWarning from '@/components/SkRemoteFollowersWarning.vue'; import SkRemoteFollowersWarning from '@/components/SkRemoteFollowersWarning.vue';
import { useRouter } from '@/router.js'; import { useRouter } from '@/router.js';

View file

@ -11,10 +11,10 @@ import type { Plugin } from '@/plugin.js';
import type { DeviceKind } from '@/utility/device-kind.js'; import type { DeviceKind } from '@/utility/device-kind.js';
import type { DeckProfile } from '@/deck.js'; import type { DeckProfile } from '@/deck.js';
import type { PreferencesDefinition } from './manager.js'; import type { PreferencesDefinition } from './manager.js';
import type { FollowingFeedState } from '@/utility/following-feed-utils.js'; import type { FollowingFeedState } from '@/types/following-feed.js';
import { DEFAULT_DEVICE_KIND } from '@/utility/device-kind.js'; import { DEFAULT_DEVICE_KIND } from '@/utility/device-kind.js';
import { searchEngineMap } from '@/utility/search-engine-map.js'; import { searchEngineMap } from '@/utility/search-engine-map.js';
import { defaultFollowingFeedState } from '@/utility/following-feed-utils.js'; import { defaultFollowingFeedState } from '@/types/following-feed.js';
/** サウンド設定 */ /** サウンド設定 */
export type SoundStore = { export type SoundStore = {

View file

@ -10,11 +10,11 @@ import darkTheme from '@@/themes/d-green-lime.json5';
import { hemisphere } from '@@/js/intl-const.js'; import { hemisphere } from '@@/js/intl-const.js';
import type { DeviceKind } from '@/utility/device-kind.js'; import type { DeviceKind } from '@/utility/device-kind.js';
import type { Plugin } from '@/plugin.js'; import type { Plugin } from '@/plugin.js';
import type { FollowingFeedState } from '@/types/following-feed.js';
import { miLocalStorage } from '@/local-storage.js'; import { miLocalStorage } from '@/local-storage.js';
import { Pizzax } from '@/lib/pizzax.js'; import { Pizzax } from '@/lib/pizzax.js';
import { DEFAULT_DEVICE_KIND } from '@/utility/device-kind.js'; import { DEFAULT_DEVICE_KIND } from '@/utility/device-kind.js';
import { defaultFollowingFeedState } from '@/utility/following-feed-utils.js'; import { defaultFollowingFeedState } from '@/types/following-feed.js';
import type { FollowingFeedState } from '@/utility/following-feed-utils.js';
import { searchEngineMap } from '@/utility/search-engine-map.js'; import { searchEngineMap } from '@/utility/search-engine-map.js';
/** /**

View file

@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { WritableComputedRef } from 'vue';
export const followingTab = 'following' as const;
export const mutualsTab = 'mutuals' as const;
export const followersTab = 'followers' as const;
export const followingFeedTabs = [followingTab, mutualsTab, followersTab] as const;
export type FollowingFeedTab = typeof followingFeedTabs[number];
export type FollowingFeedState = {
withNonPublic: boolean,
withQuotes: boolean,
withBots: boolean,
withReplies: boolean,
onlyFiles: boolean,
userList: FollowingFeedTab,
remoteWarningDismissed: boolean,
};
export type FollowingFeedModel = {
[Key in keyof FollowingFeedState]: WritableComputedRef<FollowingFeedState[Key]>;
};
export const defaultFollowingFeedState: FollowingFeedState = {
withNonPublic: false,
withQuotes: false,
withBots: true,
withReplies: false,
onlyFiles: false,
userList: followingTab,
remoteWarningDismissed: false,
};

View file

@ -19,18 +19,19 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts"> <script lang="ts">
import { computed, shallowRef } from 'vue'; import { computed, shallowRef } from 'vue';
import type { Column } from '@/deck.js'; import type { Column } from '@/deck.js';
import type { FollowingFeedState } from '@/utility/following-feed-utils.js'; import type { FollowingFeedState } from '@/types/following-feed.js';
export type FollowingColumn = Column & Partial<FollowingFeedState>; export type FollowingColumn = Column & Partial<FollowingFeedState>;
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import type { FollowingFeedTab } from '@/utility/following-feed-utils.js'; import type { FollowingFeedTab } from '@/types/following-feed.js';
import type { MenuItem } from '@/types/menu.js'; import type { MenuItem } from '@/types/menu.js';
import { getColumn, updateColumn } from '@/deck.js'; import { getColumn, updateColumn } from '@/deck.js';
import XColumn from '@/ui/deck/column.vue'; import XColumn from '@/ui/deck/column.vue';
import SkFollowingRecentNotes from '@/components/SkFollowingRecentNotes.vue'; import SkFollowingRecentNotes from '@/components/SkFollowingRecentNotes.vue';
import SkRemoteFollowersWarning from '@/components/SkRemoteFollowersWarning.vue'; import SkRemoteFollowersWarning from '@/components/SkRemoteFollowersWarning.vue';
import { createModel, createOptionsMenu, followingTab, followingTabName, followingTabIcon, followingFeedTabs } from '@/utility/following-feed-utils.js'; import { followingTab, followingFeedTabs } from '@/types/following-feed.js';
import { createModel, createOptionsMenu, followingTabName, followingTabIcon } from '@/utility/following-feed-utils.js';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { useRouter } from '@/router.js'; import { useRouter } from '@/router.js';

View file

@ -7,16 +7,12 @@ import { computed } from 'vue';
import type { Ref, WritableComputedRef } from 'vue'; import type { Ref, WritableComputedRef } from 'vue';
import type { PageHeaderItem } from '@/types/page-header.js'; import type { PageHeaderItem } from '@/types/page-header.js';
import type { MenuItem } from '@/types/menu.js'; import type { MenuItem } from '@/types/menu.js';
import type { FollowingFeedTab, FollowingFeedState, FollowingFeedModel } from '@/types/following-feed.js';
import { deepMerge } from '@/utility/merge.js'; import { deepMerge } from '@/utility/merge.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { popupMenu } from '@/os.js'; import { popupMenu } from '@/os.js';
import { prefer } from '@/preferences.js'; import { prefer } from '@/preferences.js';
import { followingTab, followersTab, mutualsTab, defaultFollowingFeedState } from '@/types/following-feed.js';
export const followingTab = 'following' as const;
export const mutualsTab = 'mutuals' as const;
export const followersTab = 'followers' as const;
export const followingFeedTabs = [followingTab, mutualsTab, followersTab] as const;
export type FollowingFeedTab = typeof followingFeedTabs[number];
export function followingTabName(tab: FollowingFeedTab): string; export function followingTabName(tab: FollowingFeedTab): string;
export function followingTabName(tab: FollowingFeedTab | null | undefined): null; export function followingTabName(tab: FollowingFeedTab | null | undefined): null;
@ -33,30 +29,6 @@ export function followingTabIcon(tab: FollowingFeedTab | null | undefined): stri
return 'ph-user-check ph-bold ph-lg'; return 'ph-user-check ph-bold ph-lg';
} }
export type FollowingFeedModel = {
[Key in keyof FollowingFeedState]: WritableComputedRef<FollowingFeedState[Key]>;
};
export type FollowingFeedState = {
withNonPublic: boolean,
withQuotes: boolean,
withBots: boolean,
withReplies: boolean,
onlyFiles: boolean,
userList: FollowingFeedTab,
remoteWarningDismissed: boolean,
};
export const defaultFollowingFeedState: FollowingFeedState = {
withNonPublic: false,
withQuotes: false,
withBots: true,
withReplies: false,
onlyFiles: false,
userList: followingTab,
remoteWarningDismissed: false,
};
interface StorageInterface { interface StorageInterface {
readonly state: Ref<Partial<FollowingFeedState>>; readonly state: Ref<Partial<FollowingFeedState>>;
save(updated: Partial<FollowingFeedState>): void; save(updated: Partial<FollowingFeedState>): void;