Frontend: List-based bookmarks deck column
This commit is contained in:
parent
43a9342e08
commit
acea6c2434
|
@ -9,12 +9,13 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
|
import { User } from "calckey-js/built/entities";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
userIds: string[];
|
userIds: string[];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const users = ref([]);
|
const users = ref<User[]>([]);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
users.value = await os.api("users/show", {
|
users.value = await os.api("users/show", {
|
||||||
|
|
|
@ -167,35 +167,28 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {
|
import { computed, defineAsyncComponent, ref, watch } from "vue";
|
||||||
computed,
|
|
||||||
defineAsyncComponent,
|
|
||||||
onMounted,
|
|
||||||
provide,
|
|
||||||
ref,
|
|
||||||
watch,
|
|
||||||
} from "vue";
|
|
||||||
import { v4 as uuid } from "uuid";
|
import { v4 as uuid } from "uuid";
|
||||||
import XCommon from "./_common_/common.vue";
|
import XCommon from "./_common_/common.vue";
|
||||||
import {
|
import {
|
||||||
deckStore,
|
|
||||||
addColumn as addColumnToStore,
|
addColumn as addColumnToStore,
|
||||||
loadDeck,
|
deckStore,
|
||||||
getProfiles,
|
|
||||||
renameProfile as renameProfile_,
|
|
||||||
deleteProfile as deleteProfile_,
|
deleteProfile as deleteProfile_,
|
||||||
|
getProfiles,
|
||||||
|
loadDeck,
|
||||||
|
renameProfile as renameProfile_,
|
||||||
} from "./deck/deck-store";
|
} from "./deck/deck-store";
|
||||||
import DeckColumnCore from "@/ui/deck/column-core.vue";
|
import DeckColumnCore from "@/ui/deck/column-core.vue";
|
||||||
import XSidebar from "@/ui/_common_/navbar.vue";
|
import XSidebar from "@/ui/_common_/navbar.vue";
|
||||||
import XDrawerMenu from "@/ui/_common_/navbar-for-mobile.vue";
|
import XDrawerMenu from "@/ui/_common_/navbar-for-mobile.vue";
|
||||||
import MkButton from "@/components/MkButton.vue";
|
import MkButton from "@/components/MkButton.vue";
|
||||||
import { getScrollContainer } from "@/scripts/scroll";
|
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
import { navbarItemDef } from "@/navbar";
|
import { navbarItemDef } from "@/navbar";
|
||||||
import { $i } from "@/account";
|
import { $i } from "@/account";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
import { mainRouter } from "@/router";
|
import { mainRouter } from "@/router";
|
||||||
import { unisonReload } from "@/scripts/unison-reload";
|
import { unisonReload } from "@/scripts/unison-reload";
|
||||||
|
|
||||||
const XStatusBars = defineAsyncComponent(
|
const XStatusBars = defineAsyncComponent(
|
||||||
() => import("@/ui/_common_/statusbars.vue")
|
() => import("@/ui/_common_/statusbars.vue")
|
||||||
);
|
);
|
||||||
|
@ -250,6 +243,7 @@ const addColumn = async (ev) => {
|
||||||
"list",
|
"list",
|
||||||
"mentions",
|
"mentions",
|
||||||
"direct",
|
"direct",
|
||||||
|
"bookmarks",
|
||||||
];
|
];
|
||||||
|
|
||||||
const { canceled, result: column } = await os.select({
|
const { canceled, result: column } = await os.select({
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
<template>
|
||||||
|
<XColumn
|
||||||
|
:menu="menu"
|
||||||
|
:column="column"
|
||||||
|
:is-stacked="isStacked"
|
||||||
|
@parent-focus="($event) => emit('parent-focus', $event)"
|
||||||
|
>
|
||||||
|
<template #header>
|
||||||
|
<i class="ph-list-bullets ph-bold ph-lg"></i
|
||||||
|
><span style="margin-left: 8px">{{ column.name }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<MkAvatars :key="userList" :userIds="userList" />
|
||||||
|
</XColumn>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import XColumn from "./column.vue";
|
||||||
|
import { Column, updateColumn } from "./deck-store";
|
||||||
|
import * as os from "@/os";
|
||||||
|
import { i18n } from "@/i18n";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import { User } from "calckey-js/built/entities";
|
||||||
|
import MkAvatars from "@/components/MkAvatars.vue";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
column: Column;
|
||||||
|
isStacked: boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(ev: "loaded"): void;
|
||||||
|
(ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const userList = ref<User["id"][]>([]);
|
||||||
|
|
||||||
|
async function fetchUserList() {
|
||||||
|
userList.value = (
|
||||||
|
await os.api("users/lists/show", {
|
||||||
|
listId: props.column.listId!,
|
||||||
|
})
|
||||||
|
).userIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
watch($$(props.column.listId), () => {
|
||||||
|
if (props.column.listId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchUserList();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (props.column.listId == null) {
|
||||||
|
setList();
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.column.listId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchUserList();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function setList() {
|
||||||
|
const lists = await os.api("users/lists/list");
|
||||||
|
const { canceled, result: list } = await os.select({
|
||||||
|
title: i18n.ts.selectList,
|
||||||
|
items: lists.map((x) => ({
|
||||||
|
value: x,
|
||||||
|
text: x.name,
|
||||||
|
})),
|
||||||
|
default: props.column.listId,
|
||||||
|
});
|
||||||
|
if (canceled) return;
|
||||||
|
updateColumn(props.column.id, {
|
||||||
|
name: list.name,
|
||||||
|
listId: list.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const menu = [
|
||||||
|
{
|
||||||
|
icon: "ph-pencil ph-bold ph-lg",
|
||||||
|
text: i18n.ts.selectList,
|
||||||
|
action: setList,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
|
@ -49,10 +49,15 @@
|
||||||
:is-stacked="isStacked"
|
:is-stacked="isStacked"
|
||||||
@parent-focus="emit('parent-focus', $event)"
|
@parent-focus="emit('parent-focus', $event)"
|
||||||
/>
|
/>
|
||||||
|
<XBookmarksColumn
|
||||||
|
v-else-if="column.type === 'bookmarks'"
|
||||||
|
:column="column"
|
||||||
|
:is-stacked="isStacked"
|
||||||
|
@parent-focus="emit('parent-focus', $event)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {} from "vue";
|
|
||||||
import XMainColumn from "./main-column.vue";
|
import XMainColumn from "./main-column.vue";
|
||||||
import XTlColumn from "./tl-column.vue";
|
import XTlColumn from "./tl-column.vue";
|
||||||
import XAntennaColumn from "./antenna-column.vue";
|
import XAntennaColumn from "./antenna-column.vue";
|
||||||
|
@ -61,6 +66,7 @@ import XNotificationsColumn from "./notifications-column.vue";
|
||||||
import XWidgetsColumn from "./widgets-column.vue";
|
import XWidgetsColumn from "./widgets-column.vue";
|
||||||
import XMentionsColumn from "./mentions-column.vue";
|
import XMentionsColumn from "./mentions-column.vue";
|
||||||
import XDirectColumn from "./direct-column.vue";
|
import XDirectColumn from "./direct-column.vue";
|
||||||
|
import XBookmarksColumn from "./bookmarks-column.vue";
|
||||||
import { Column } from "./deck-store";
|
import { Column } from "./deck-store";
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { throttle } from "throttle-debounce";
|
||||||
import { markRaw } from "vue";
|
import { markRaw } from "vue";
|
||||||
import { notificationTypes } from "calckey-js";
|
import { notificationTypes } from "calckey-js";
|
||||||
import { Storage } from "../../pizzax";
|
import { Storage } from "../../pizzax";
|
||||||
import { i18n } from "@/i18n";
|
|
||||||
import { api } from "@/os";
|
import { api } from "@/os";
|
||||||
import { deepClone } from "@/scripts/clone";
|
import { deepClone } from "@/scripts/clone";
|
||||||
|
|
||||||
|
@ -22,7 +21,8 @@ export type Column = {
|
||||||
| "antenna"
|
| "antenna"
|
||||||
| "list"
|
| "list"
|
||||||
| "mentions"
|
| "mentions"
|
||||||
| "direct";
|
| "direct"
|
||||||
|
| "bookmarks";
|
||||||
name: string | null;
|
name: string | null;
|
||||||
width: number;
|
width: number;
|
||||||
widgets?: ColumnWidget[];
|
widgets?: ColumnWidget[];
|
||||||
|
|
|
@ -945,6 +945,7 @@ _deck:
|
||||||
antenna: "Antény"
|
antenna: "Antény"
|
||||||
list: "Seznamy"
|
list: "Seznamy"
|
||||||
mentions: "Zmínění"
|
mentions: "Zmínění"
|
||||||
|
bookmarks: "Záložky uživatelů"
|
||||||
noteDeleteConfirm: Chcete opravdu smazat tento příspěvek?
|
noteDeleteConfirm: Chcete opravdu smazat tento příspěvek?
|
||||||
defaultValueIs: 'Výchozí: {value}'
|
defaultValueIs: 'Výchozí: {value}'
|
||||||
lookup: Hledat
|
lookup: Hledat
|
||||||
|
|
|
@ -2063,6 +2063,7 @@ _deck:
|
||||||
channel: "Channel"
|
channel: "Channel"
|
||||||
mentions: "Mentions"
|
mentions: "Mentions"
|
||||||
direct: "Direct messages"
|
direct: "Direct messages"
|
||||||
|
bookmarks: "User Bookmarks"
|
||||||
_experiments:
|
_experiments:
|
||||||
title: "Experiments"
|
title: "Experiments"
|
||||||
enablePostEditing: "Enable post editing"
|
enablePostEditing: "Enable post editing"
|
||||||
|
|
Loading…
Reference in New Issue