improve performance (merge deepClone from Misskey dev)
This commit is contained in:
parent
8bb4714edb
commit
eb9d50ec70
12 changed files with 85 additions and 44 deletions
18
packages/backend/src/misc/clone.ts
Normal file
18
packages/backend/src/misc/clone.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// structredCloneが遅いため
|
||||||
|
// SEE: http://var.blog.jp/archives/86038606.html
|
||||||
|
|
||||||
|
type Cloneable = string | number | boolean | null | { [key: string]: Cloneable } | Cloneable[];
|
||||||
|
|
||||||
|
export function deepClone<T extends Cloneable>(x: T): T {
|
||||||
|
if (typeof x === 'object') {
|
||||||
|
if (x === null) return x;
|
||||||
|
if (Array.isArray(x)) return x.map(deepClone) as T;
|
||||||
|
const obj = {} as Record<string, Cloneable>;
|
||||||
|
for (const [k, v] of Object.entries(x)) {
|
||||||
|
obj[k] = deepClone(v);
|
||||||
|
}
|
||||||
|
return obj as T;
|
||||||
|
} else {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,8 @@ import { query, appendQuery } from '@/prelude/url.js';
|
||||||
import { Meta } from '@/models/entities/meta.js';
|
import { Meta } from '@/models/entities/meta.js';
|
||||||
import { fetchMeta } from '@/misc/fetch-meta.js';
|
import { fetchMeta } from '@/misc/fetch-meta.js';
|
||||||
import { Users, DriveFolders } from '../index.js';
|
import { Users, DriveFolders } from '../index.js';
|
||||||
|
import { deepClone } from '@/misc/clone.js';
|
||||||
|
|
||||||
|
|
||||||
type PackOptions = {
|
type PackOptions = {
|
||||||
detail?: boolean,
|
detail?: boolean,
|
||||||
|
@ -29,9 +31,7 @@ export const DriveFileRepository = db.getRepository(DriveFile).extend({
|
||||||
|
|
||||||
getPublicProperties(file: DriveFile): DriveFile['properties'] {
|
getPublicProperties(file: DriveFile): DriveFile['properties'] {
|
||||||
if (file.properties.orientation != null) {
|
if (file.properties.orientation != null) {
|
||||||
// TODO
|
const properties = deepClone(file.properties);
|
||||||
//const properties = structuredClone(file.properties);
|
|
||||||
const properties = JSON.parse(JSON.stringify(file.properties));
|
|
||||||
if (file.properties.orientation >= 5) {
|
if (file.properties.orientation >= 5) {
|
||||||
[properties.width, properties.height] = [properties.height, properties.width];
|
[properties.width, properties.height] = [properties.height, properties.width];
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,7 @@ import { i18n } from '@/i18n';
|
||||||
import { getNoteMenu } from '@/scripts/get-note-menu';
|
import { getNoteMenu } from '@/scripts/get-note-menu';
|
||||||
import { useNoteCapture } from '@/scripts/use-note-capture';
|
import { useNoteCapture } from '@/scripts/use-note-capture';
|
||||||
import { notePage } from '@/filters/note';
|
import { notePage } from '@/filters/note';
|
||||||
|
import { deepClone } from '@/scripts/clone';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
@ -145,12 +146,12 @@ const props = defineProps<{
|
||||||
|
|
||||||
const inChannel = inject('inChannel', null);
|
const inChannel = inject('inChannel', null);
|
||||||
|
|
||||||
let note = $ref(JSON.parse(JSON.stringify(props.note)));
|
let note = $ref(deepClone(props.note));
|
||||||
|
|
||||||
// plugin
|
// plugin
|
||||||
if (noteViewInterruptors.length > 0) {
|
if (noteViewInterruptors.length > 0) {
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
let result = JSON.parse(JSON.stringify(note));
|
let result = deepClone(note);
|
||||||
for (const interruptor of noteViewInterruptors) {
|
for (const interruptor of noteViewInterruptors) {
|
||||||
result = await interruptor.handler(result);
|
result = await interruptor.handler(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,7 @@ import { $i } from '@/account';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { getNoteMenu } from '@/scripts/get-note-menu';
|
import { getNoteMenu } from '@/scripts/get-note-menu';
|
||||||
import { useNoteCapture } from '@/scripts/use-note-capture';
|
import { useNoteCapture } from '@/scripts/use-note-capture';
|
||||||
|
import { deepClone } from '@/scripts/clone';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
@ -153,12 +154,12 @@ const props = defineProps<{
|
||||||
|
|
||||||
const inChannel = inject('inChannel', null);
|
const inChannel = inject('inChannel', null);
|
||||||
|
|
||||||
let note = $ref(JSON.parse(JSON.stringify(props.note)));
|
let note = $ref(deepClone(props.note));
|
||||||
|
|
||||||
// plugin
|
// plugin
|
||||||
if (noteViewInterruptors.length > 0) {
|
if (noteViewInterruptors.length > 0) {
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
let result = JSON.parse(JSON.stringify(note));
|
let result = deepClone(note);
|
||||||
for (const interruptor of noteViewInterruptors) {
|
for (const interruptor of noteViewInterruptors) {
|
||||||
result = await interruptor.handler(result);
|
result = await interruptor.handler(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,7 @@ import { i18n } from '@/i18n';
|
||||||
import { instance } from '@/instance';
|
import { instance } from '@/instance';
|
||||||
import { $i, getAccounts, openAccountMenu as openAccountMenu_ } from '@/account';
|
import { $i, getAccounts, openAccountMenu as openAccountMenu_ } from '@/account';
|
||||||
import { uploadFile } from '@/scripts/upload';
|
import { uploadFile } from '@/scripts/upload';
|
||||||
|
import { deepClone } from '@/scripts/clone';
|
||||||
|
|
||||||
const modal = inject('modal');
|
const modal = inject('modal');
|
||||||
|
|
||||||
|
@ -575,7 +576,7 @@ async function post() {
|
||||||
// plugin
|
// plugin
|
||||||
if (notePostInterruptors.length > 0) {
|
if (notePostInterruptors.length > 0) {
|
||||||
for (const interruptor of notePostInterruptors) {
|
for (const interruptor of notePostInterruptors) {
|
||||||
postData = await interruptor.handler(JSON.parse(JSON.stringify(postData)));
|
postData = await interruptor.handler(deepClone(postData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,9 @@ import * as os from '@/os';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
|
import { deepClone } from '@/scripts/clone';
|
||||||
|
|
||||||
let reactions = $ref(JSON.parse(JSON.stringify(defaultStore.state.reactions)));
|
let reactions = $ref(deepClone(defaultStore.state.reactions));
|
||||||
|
|
||||||
const reactionPickerSize = $computed(defaultStore.makeGetterSetter('reactionPickerSize'));
|
const reactionPickerSize = $computed(defaultStore.makeGetterSetter('reactionPickerSize'));
|
||||||
const reactionPickerWidth = $computed(defaultStore.makeGetterSetter('reactionPickerWidth'));
|
const reactionPickerWidth = $computed(defaultStore.makeGetterSetter('reactionPickerWidth'));
|
||||||
|
@ -101,7 +102,7 @@ async function setDefault() {
|
||||||
});
|
});
|
||||||
if (canceled) return;
|
if (canceled) return;
|
||||||
|
|
||||||
reactions = JSON.parse(JSON.stringify(defaultStore.def.reactions.default));
|
reactions = deepClone(defaultStore.def.reactions.default);
|
||||||
}
|
}
|
||||||
|
|
||||||
function chooseEmoji(ev: MouseEvent) {
|
function chooseEmoji(ev: MouseEvent) {
|
||||||
|
|
|
@ -91,13 +91,14 @@ import FormRange from '@/components/form/range.vue';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
|
import { deepClone } from '@/scripts/clone';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
_id: string;
|
_id: string;
|
||||||
userLists: any[] | null;
|
userLists: any[] | null;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const statusbar = reactive(JSON.parse(JSON.stringify(defaultStore.state.statusbars.find(x => x.id === props._id))));
|
const statusbar = reactive(deepClone(defaultStore.state.statusbars.find(x => x.id === props._id)));
|
||||||
|
|
||||||
watch(() => statusbar.type, () => {
|
watch(() => statusbar.type, () => {
|
||||||
if (statusbar.type === 'rss') {
|
if (statusbar.type === 'rss') {
|
||||||
|
@ -128,8 +129,8 @@ watch(statusbar, save);
|
||||||
|
|
||||||
async function save() {
|
async function save() {
|
||||||
const i = defaultStore.state.statusbars.findIndex(x => x.id === props._id);
|
const i = defaultStore.state.statusbars.findIndex(x => x.id === props._id);
|
||||||
const statusbars = JSON.parse(JSON.stringify(defaultStore.state.statusbars));
|
const statusbars = deepClone(defaultStore.state.statusbars);
|
||||||
statusbars[i] = JSON.parse(JSON.stringify(statusbar));
|
statusbars[i] = deepClone(statusbar);
|
||||||
defaultStore.set('statusbars', statusbars);
|
defaultStore.set('statusbars', statusbars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
18
packages/client/src/scripts/clone.ts
Normal file
18
packages/client/src/scripts/clone.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// structredCloneが遅いため
|
||||||
|
// SEE: http://var.blog.jp/archives/86038606.html
|
||||||
|
|
||||||
|
type Cloneable = string | number | boolean | null | { [key: string]: Cloneable } | Cloneable[];
|
||||||
|
|
||||||
|
export function deepClone<T extends Cloneable>(x: T): T {
|
||||||
|
if (typeof x === 'object') {
|
||||||
|
if (x === null) return x;
|
||||||
|
if (Array.isArray(x)) return x.map(deepClone) as T;
|
||||||
|
const obj = {} as Record<string, Cloneable>;
|
||||||
|
for (const [k, v] of Object.entries(x)) {
|
||||||
|
obj[k] = deepClone(v);
|
||||||
|
}
|
||||||
|
return obj as T;
|
||||||
|
} else {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ export type Theme = {
|
||||||
|
|
||||||
import lightTheme from '@/themes/_light.json5';
|
import lightTheme from '@/themes/_light.json5';
|
||||||
import darkTheme from '@/themes/_dark.json5';
|
import darkTheme from '@/themes/_dark.json5';
|
||||||
|
import { deepClone } from './clone';
|
||||||
|
|
||||||
export const themeProps = Object.keys(lightTheme.props).filter(key => !key.startsWith('X'));
|
export const themeProps = Object.keys(lightTheme.props).filter(key => !key.startsWith('X'));
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ export function applyTheme(theme: Theme, persist = true) {
|
||||||
const colorSchema = theme.base === 'dark' ? 'dark' : 'light';
|
const colorSchema = theme.base === 'dark' ? 'dark' : 'light';
|
||||||
|
|
||||||
// Deep copy
|
// Deep copy
|
||||||
const _theme = JSON.parse(JSON.stringify(theme));
|
const _theme = deepClone(theme);
|
||||||
|
|
||||||
if (_theme.base) {
|
if (_theme.base) {
|
||||||
const base = [lightTheme, darkTheme].find(x => x.id === _theme.base);
|
const base = [lightTheme, darkTheme].find(x => x.id === _theme.base);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { notificationTypes } from 'misskey-js';
|
||||||
import { Storage } from '../../pizzax';
|
import { Storage } from '../../pizzax';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { api } from '@/os';
|
import { api } from '@/os';
|
||||||
|
import { deepClone } from '@/scripts/clone';
|
||||||
|
|
||||||
type ColumnWidget = {
|
type ColumnWidget = {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -25,10 +26,6 @@ export type Column = {
|
||||||
tl?: 'home' | 'local' | 'social' | 'global';
|
tl?: 'home' | 'local' | 'social' | 'global';
|
||||||
};
|
};
|
||||||
|
|
||||||
function copy<T>(x: T): T {
|
|
||||||
return JSON.parse(JSON.stringify(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
export const deckStore = markRaw(new Storage('deck', {
|
export const deckStore = markRaw(new Storage('deck', {
|
||||||
profile: {
|
profile: {
|
||||||
where: 'deviceAccount',
|
where: 'deviceAccount',
|
||||||
|
@ -128,7 +125,7 @@ export function swapColumn(a: Column['id'], b: Column['id']) {
|
||||||
const aY = deckStore.state.layout[aX].findIndex(id => id === a);
|
const aY = deckStore.state.layout[aX].findIndex(id => id === a);
|
||||||
const bX = deckStore.state.layout.findIndex(ids => ids.indexOf(b) !== -1);
|
const bX = deckStore.state.layout.findIndex(ids => ids.indexOf(b) !== -1);
|
||||||
const bY = deckStore.state.layout[bX].findIndex(id => id === b);
|
const bY = deckStore.state.layout[bX].findIndex(id => id === b);
|
||||||
const layout = copy(deckStore.state.layout);
|
const layout = deepClone(deckStore.state.layout);
|
||||||
layout[aX][aY] = b;
|
layout[aX][aY] = b;
|
||||||
layout[bX][bY] = a;
|
layout[bX][bY] = a;
|
||||||
deckStore.set('layout', layout);
|
deckStore.set('layout', layout);
|
||||||
|
@ -136,7 +133,7 @@ export function swapColumn(a: Column['id'], b: Column['id']) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function swapLeftColumn(id: Column['id']) {
|
export function swapLeftColumn(id: Column['id']) {
|
||||||
const layout = copy(deckStore.state.layout);
|
const layout = deepClone(deckStore.state.layout);
|
||||||
deckStore.state.layout.some((ids, i) => {
|
deckStore.state.layout.some((ids, i) => {
|
||||||
if (ids.includes(id)) {
|
if (ids.includes(id)) {
|
||||||
const left = deckStore.state.layout[i - 1];
|
const left = deckStore.state.layout[i - 1];
|
||||||
|
@ -152,7 +149,7 @@ export function swapLeftColumn(id: Column['id']) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function swapRightColumn(id: Column['id']) {
|
export function swapRightColumn(id: Column['id']) {
|
||||||
const layout = copy(deckStore.state.layout);
|
const layout = deepClone(deckStore.state.layout);
|
||||||
deckStore.state.layout.some((ids, i) => {
|
deckStore.state.layout.some((ids, i) => {
|
||||||
if (ids.includes(id)) {
|
if (ids.includes(id)) {
|
||||||
const right = deckStore.state.layout[i + 1];
|
const right = deckStore.state.layout[i + 1];
|
||||||
|
@ -168,9 +165,9 @@ export function swapRightColumn(id: Column['id']) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function swapUpColumn(id: Column['id']) {
|
export function swapUpColumn(id: Column['id']) {
|
||||||
const layout = copy(deckStore.state.layout);
|
const layout = deepClone(deckStore.state.layout);
|
||||||
const idsIndex = deckStore.state.layout.findIndex(ids => ids.includes(id));
|
const idsIndex = deckStore.state.layout.findIndex(ids => ids.includes(id));
|
||||||
const ids = copy(deckStore.state.layout[idsIndex]);
|
const ids = deepClone(deckStore.state.layout[idsIndex]);
|
||||||
ids.some((x, i) => {
|
ids.some((x, i) => {
|
||||||
if (x === id) {
|
if (x === id) {
|
||||||
const up = ids[i - 1];
|
const up = ids[i - 1];
|
||||||
|
@ -188,9 +185,9 @@ export function swapUpColumn(id: Column['id']) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function swapDownColumn(id: Column['id']) {
|
export function swapDownColumn(id: Column['id']) {
|
||||||
const layout = copy(deckStore.state.layout);
|
const layout = deepClone(deckStore.state.layout);
|
||||||
const idsIndex = deckStore.state.layout.findIndex(ids => ids.includes(id));
|
const idsIndex = deckStore.state.layout.findIndex(ids => ids.includes(id));
|
||||||
const ids = copy(deckStore.state.layout[idsIndex]);
|
const ids = deepClone(deckStore.state.layout[idsIndex]);
|
||||||
ids.some((x, i) => {
|
ids.some((x, i) => {
|
||||||
if (x === id) {
|
if (x === id) {
|
||||||
const down = ids[i + 1];
|
const down = ids[i + 1];
|
||||||
|
@ -208,7 +205,7 @@ export function swapDownColumn(id: Column['id']) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stackLeftColumn(id: Column['id']) {
|
export function stackLeftColumn(id: Column['id']) {
|
||||||
let layout = copy(deckStore.state.layout);
|
let layout = deepClone(deckStore.state.layout);
|
||||||
const i = deckStore.state.layout.findIndex(ids => ids.includes(id));
|
const i = deckStore.state.layout.findIndex(ids => ids.includes(id));
|
||||||
layout = layout.map(ids => ids.filter(_id => _id !== id));
|
layout = layout.map(ids => ids.filter(_id => _id !== id));
|
||||||
layout[i - 1].push(id);
|
layout[i - 1].push(id);
|
||||||
|
@ -218,7 +215,7 @@ export function stackLeftColumn(id: Column['id']) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function popRightColumn(id: Column['id']) {
|
export function popRightColumn(id: Column['id']) {
|
||||||
let layout = copy(deckStore.state.layout);
|
let layout = deepClone(deckStore.state.layout);
|
||||||
const i = deckStore.state.layout.findIndex(ids => ids.includes(id));
|
const i = deckStore.state.layout.findIndex(ids => ids.includes(id));
|
||||||
const affected = layout[i];
|
const affected = layout[i];
|
||||||
layout = layout.map(ids => ids.filter(_id => _id !== id));
|
layout = layout.map(ids => ids.filter(_id => _id !== id));
|
||||||
|
@ -226,7 +223,7 @@ export function popRightColumn(id: Column['id']) {
|
||||||
layout = layout.filter(ids => ids.length > 0);
|
layout = layout.filter(ids => ids.length > 0);
|
||||||
deckStore.set('layout', layout);
|
deckStore.set('layout', layout);
|
||||||
|
|
||||||
const columns = copy(deckStore.state.columns);
|
const columns = deepClone(deckStore.state.columns);
|
||||||
for (const column of columns) {
|
for (const column of columns) {
|
||||||
if (affected.includes(column.id)) {
|
if (affected.includes(column.id)) {
|
||||||
column.active = true;
|
column.active = true;
|
||||||
|
@ -238,9 +235,9 @@ export function popRightColumn(id: Column['id']) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addColumnWidget(id: Column['id'], widget: ColumnWidget) {
|
export function addColumnWidget(id: Column['id'], widget: ColumnWidget) {
|
||||||
const columns = copy(deckStore.state.columns);
|
const columns = deepClone(deckStore.state.columns);
|
||||||
const columnIndex = deckStore.state.columns.findIndex(c => c.id === id);
|
const columnIndex = deckStore.state.columns.findIndex(c => c.id === id);
|
||||||
const column = copy(deckStore.state.columns[columnIndex]);
|
const column = deepClone(deckStore.state.columns[columnIndex]);
|
||||||
if (column == null) return;
|
if (column == null) return;
|
||||||
if (column.widgets == null) column.widgets = [];
|
if (column.widgets == null) column.widgets = [];
|
||||||
column.widgets.unshift(widget);
|
column.widgets.unshift(widget);
|
||||||
|
@ -250,9 +247,9 @@ export function addColumnWidget(id: Column['id'], widget: ColumnWidget) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeColumnWidget(id: Column['id'], widget: ColumnWidget) {
|
export function removeColumnWidget(id: Column['id'], widget: ColumnWidget) {
|
||||||
const columns = copy(deckStore.state.columns);
|
const columns = deepClone(deckStore.state.columns);
|
||||||
const columnIndex = deckStore.state.columns.findIndex(c => c.id === id);
|
const columnIndex = deckStore.state.columns.findIndex(c => c.id === id);
|
||||||
const column = copy(deckStore.state.columns[columnIndex]);
|
const column = deepClone(deckStore.state.columns[columnIndex]);
|
||||||
if (column == null) return;
|
if (column == null) return;
|
||||||
column.widgets = column.widgets.filter(w => w.id !== widget.id);
|
column.widgets = column.widgets.filter(w => w.id !== widget.id);
|
||||||
columns[columnIndex] = column;
|
columns[columnIndex] = column;
|
||||||
|
@ -261,9 +258,9 @@ export function removeColumnWidget(id: Column['id'], widget: ColumnWidget) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setColumnWidgets(id: Column['id'], widgets: ColumnWidget[]) {
|
export function setColumnWidgets(id: Column['id'], widgets: ColumnWidget[]) {
|
||||||
const columns = copy(deckStore.state.columns);
|
const columns = deepClone(deckStore.state.columns);
|
||||||
const columnIndex = deckStore.state.columns.findIndex(c => c.id === id);
|
const columnIndex = deckStore.state.columns.findIndex(c => c.id === id);
|
||||||
const column = copy(deckStore.state.columns[columnIndex]);
|
const column = deepClone(deckStore.state.columns[columnIndex]);
|
||||||
if (column == null) return;
|
if (column == null) return;
|
||||||
column.widgets = widgets;
|
column.widgets = widgets;
|
||||||
columns[columnIndex] = column;
|
columns[columnIndex] = column;
|
||||||
|
@ -272,9 +269,9 @@ export function setColumnWidgets(id: Column['id'], widgets: ColumnWidget[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateColumnWidget(id: Column['id'], widgetId: string, widgetData: any) {
|
export function updateColumnWidget(id: Column['id'], widgetId: string, widgetData: any) {
|
||||||
const columns = copy(deckStore.state.columns);
|
const columns = deepClone(deckStore.state.columns);
|
||||||
const columnIndex = deckStore.state.columns.findIndex(c => c.id === id);
|
const columnIndex = deckStore.state.columns.findIndex(c => c.id === id);
|
||||||
const column = copy(deckStore.state.columns[columnIndex]);
|
const column = deepClone(deckStore.state.columns[columnIndex]);
|
||||||
if (column == null) return;
|
if (column == null) return;
|
||||||
column.widgets = column.widgets.map(w => w.id === widgetId ? {
|
column.widgets = column.widgets.map(w => w.id === widgetId ? {
|
||||||
...w,
|
...w,
|
||||||
|
@ -286,9 +283,9 @@ export function updateColumnWidget(id: Column['id'], widgetId: string, widgetDat
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateColumn(id: Column['id'], column: Partial<Column>) {
|
export function updateColumn(id: Column['id'], column: Partial<Column>) {
|
||||||
const columns = copy(deckStore.state.columns);
|
const columns = deepClone(deckStore.state.columns);
|
||||||
const columnIndex = deckStore.state.columns.findIndex(c => c.id === id);
|
const columnIndex = deckStore.state.columns.findIndex(c => c.id === id);
|
||||||
const currentColumn = copy(deckStore.state.columns[columnIndex]);
|
const currentColumn = deepClone(deckStore.state.columns[columnIndex]);
|
||||||
if (currentColumn == null) return;
|
if (currentColumn == null) return;
|
||||||
for (const [k, v] of Object.entries(column)) {
|
for (const [k, v] of Object.entries(column)) {
|
||||||
currentColumn[k] = v;
|
currentColumn[k] = v;
|
||||||
|
|
|
@ -47,12 +47,13 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||||
import { GetFormResultType } from '@/scripts/form';
|
|
||||||
import { useWidgetPropsManager, Widget, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget';
|
import { useWidgetPropsManager, Widget, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget';
|
||||||
|
import { GetFormResultType } from '@/scripts/form';
|
||||||
import { stream } from '@/stream';
|
import { stream } from '@/stream';
|
||||||
import number from '@/filters/number';
|
import number from '@/filters/number';
|
||||||
import * as sound from '@/scripts/sound';
|
import * as sound from '@/scripts/sound';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
import { deepClone } from '@/scripts/clone';
|
||||||
|
|
||||||
const name = 'jobQueue';
|
const name = 'jobQueue';
|
||||||
|
|
||||||
|
@ -100,12 +101,12 @@ const prev = reactive({} as typeof current);
|
||||||
const jammedSound = sound.setVolume(sound.getAudio('syuilo/queue-jammed'), 1);
|
const jammedSound = sound.setVolume(sound.getAudio('syuilo/queue-jammed'), 1);
|
||||||
|
|
||||||
for (const domain of ['inbox', 'deliver']) {
|
for (const domain of ['inbox', 'deliver']) {
|
||||||
prev[domain] = JSON.parse(JSON.stringify(current[domain]));
|
prev[domain] = deepClone(current[domain]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const onStats = (stats) => {
|
const onStats = (stats) => {
|
||||||
for (const domain of ['inbox', 'deliver']) {
|
for (const domain of ['inbox', 'deliver']) {
|
||||||
prev[domain] = JSON.parse(JSON.stringify(current[domain]));
|
prev[domain] = deepClone(current[domain]);
|
||||||
current[domain].activeSincePrevTick = stats[domain].activeSincePrevTick;
|
current[domain].activeSincePrevTick = stats[domain].activeSincePrevTick;
|
||||||
current[domain].active = stats[domain].active;
|
current[domain].active = stats[domain].active;
|
||||||
current[domain].waiting = stats[domain].waiting;
|
current[domain].waiting = stats[domain].waiting;
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { reactive, watch } from 'vue';
|
||||||
import { throttle } from 'throttle-debounce';
|
import { throttle } from 'throttle-debounce';
|
||||||
import { Form, GetFormResultType } from '@/scripts/form';
|
import { Form, GetFormResultType } from '@/scripts/form';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
import { deepClone } from '@/scripts/clone';
|
||||||
|
|
||||||
export type Widget<P extends Record<string, unknown>> = {
|
export type Widget<P extends Record<string, unknown>> = {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -32,7 +33,7 @@ export const useWidgetPropsManager = <F extends Form & Record<string, { default:
|
||||||
save: () => void;
|
save: () => void;
|
||||||
configure: () => void;
|
configure: () => void;
|
||||||
} => {
|
} => {
|
||||||
const widgetProps = reactive(props.widget ? JSON.parse(JSON.stringify(props.widget.data)) : {});
|
const widgetProps = reactive(props.widget ? deepClone(props.widget.data) : {});
|
||||||
|
|
||||||
const mergeProps = () => {
|
const mergeProps = () => {
|
||||||
for (const prop of Object.keys(propsDef)) {
|
for (const prop of Object.keys(propsDef)) {
|
||||||
|
@ -43,14 +44,14 @@ export const useWidgetPropsManager = <F extends Form & Record<string, { default:
|
||||||
};
|
};
|
||||||
watch(widgetProps, () => {
|
watch(widgetProps, () => {
|
||||||
mergeProps();
|
mergeProps();
|
||||||
}, { deep: true, immediate: true, });
|
}, { deep: true, immediate: true });
|
||||||
|
|
||||||
const save = throttle(3000, () => {
|
const save = throttle(3000, () => {
|
||||||
emit('updateProps', widgetProps);
|
emit('updateProps', widgetProps);
|
||||||
});
|
});
|
||||||
|
|
||||||
const configure = async () => {
|
const configure = async () => {
|
||||||
const form = JSON.parse(JSON.stringify(propsDef));
|
const form = deepClone(propsDef);
|
||||||
for (const item of Object.keys(form)) {
|
for (const item of Object.keys(form)) {
|
||||||
form[item].default = widgetProps[item];
|
form[item].default = widgetProps[item];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue