summaryrefslogtreecommitdiff
path: root/packages/frontend/src/ui/deck/following-column.vue
blob: ed24d119d3f0a0ef306d85f83d73f444ed1ef544 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<!--
SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
SPDX-License-Identifier: AGPL-3.0-only
-->

<!-- based on list-column.vue -->

<template>
<XColumn :menu="menu" :column="column" :isStacked="isStacked" :refresher="reload">
	<template #header>
		<i :class="columnIcon" aria-hidden="true"/><span style="margin-left: 8px;">{{ (column.name || column.userList) ?? i18n.ts._deck._columns.following }}</span>
	</template>

	<SkRemoteFollowersWarning :class="$style.followersWarning" :model="model"/>
	<SkFollowingRecentNotes ref="latestNotes" :userList="userList" :withNonPublic="withNonPublic" :withQuotes="withQuotes" :withReplies="withReplies" :withBots="withBots" :onlyFiles="onlyFiles" @userSelected="userSelected"/>
</XColumn>
</template>

<script lang="ts">
import { computed, shallowRef } from 'vue';
import type { Column } from '@/deck.js';
import type { FollowingFeedState } from '@/types/following-feed.js';
export type FollowingColumn = Column & Partial<FollowingFeedState>;
</script>

<script setup lang="ts">
import type { FollowingFeedTab } from '@/types/following-feed.js';
import type { MenuItem } from '@/types/menu.js';
import { getColumn, updateColumn } from '@/deck.js';
import XColumn from '@/ui/deck/column.vue';
import SkFollowingRecentNotes from '@/components/SkFollowingRecentNotes.vue';
import SkRemoteFollowersWarning from '@/components/SkRemoteFollowersWarning.vue';
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 { i18n } from '@/i18n.js';
import { useRouter } from '@/router.js';

const props = defineProps<{
	column: FollowingColumn;
	isStacked: boolean;
}>();

const columnIcon = computed(() => followingTabIcon(props.column.userList));

async function selectList(): Promise<void> {
	const { canceled, result: newList } = await os.select<FollowingFeedTab>({
		title: i18n.ts.selectFollowRelationship,
		items: followingFeedTabs.map(t => ({
			value: t,
			text: followingTabName(t),
		})),
		default: props.column.userList ?? followingTab,
	});

	if (canceled) return;

	updateColumn(props.column.id, {
		name: getNewColumnName(newList),
		userList: newList,
	} as Partial<FollowingColumn>);
}

function getNewColumnName(newList: FollowingFeedTab) {
	// If the user has renamed the column, then we need to keep that name.
	// If no list is specified, then the column is newly created and the user *can't* have renamed it.
	if (props.column.userList && props.column.name === followingTabName(props.column.userList)) {
		return props.column.name;
	}

	// Otherwise, we should match the name to the selected list.
	return followingTabName(newList);
}

if (!props.column.userList) {
	await selectList();
}

// Redirects the Following Feed logic into column-specific storage.
// This allows multiple columns to exist with different settings.
const columnStorage = computed(() => ({
	state: getColumn<FollowingColumn>(props.column.id),
	save(updated: FollowingColumn) {
		updateColumn(props.column.id, updated);
	},
}));

const model = createModel(columnStorage);
const {
	userList,
	withNonPublic,
	withQuotes,
	withReplies,
	withBots,
	onlyFiles,
} = model;

const menu: MenuItem[] = [
	{
		icon: columnIcon.value,
		text: i18n.ts.selectFollowRelationship,
		action: selectList,
	},
	...createOptionsMenu(columnStorage),
];

const latestNotes = shallowRef<InstanceType<typeof SkFollowingRecentNotes>>();

async function reload() {
	await latestNotes.value?.reload();
}

const router = useRouter();

function userSelected(userId: string) {
	router.push(`/following-feed/${userId}`);
}
</script>

<style lang="scss" module>
.followersWarning {
	margin-bottom: 8px;
	border-radius: 0;
}
</style>