summaryrefslogtreecommitdiff
path: root/packages/client/src/scripts
diff options
context:
space:
mode:
authortamaina <tamaina@hotmail.co.jp>2022-01-11 16:03:25 +0900
committertamaina <tamaina@hotmail.co.jp>2022-01-11 16:03:25 +0900
commit4219b4dd62aec5ed051a478d24eefb1cf65bded7 (patch)
tree5c38c35d2c0e8b4d0abb7805360d90e8e3384da0 /packages/client/src/scripts
parent初期値にデフォルト値を挿入する & JSON.parse/stringify操作を... (diff)
parentMerge branch 'develop' of https://github.com/misskey-dev/misskey into develop (diff)
downloadmisskey-4219b4dd62aec5ed051a478d24eefb1cf65bded7.tar.gz
misskey-4219b4dd62aec5ed051a478d24eefb1cf65bded7.tar.bz2
misskey-4219b4dd62aec5ed051a478d24eefb1cf65bded7.zip
Merge branch 'develop' into pizzax-indexeddb
Diffstat (limited to 'packages/client/src/scripts')
-rw-r--r--packages/client/src/scripts/form.ts30
-rw-r--r--packages/client/src/scripts/paging.ts246
2 files changed, 29 insertions, 247 deletions
diff --git a/packages/client/src/scripts/form.ts b/packages/client/src/scripts/form.ts
index 7bf6cec452..7f321cc0ae 100644
--- a/packages/client/src/scripts/form.ts
+++ b/packages/client/src/scripts/form.ts
@@ -23,9 +23,37 @@ export type FormItem = {
enum: string[];
} | {
label?: string;
+ type: 'radio';
+ default: unknown | null;
+ hidden?: boolean;
+ options: {
+ label: string;
+ value: unknown;
+ }[];
+} | {
+ label?: string;
+ type: 'object';
+ default: Record<string, unknown> | null;
+ hidden: true;
+} | {
+ label?: string;
type: 'array';
default: unknown[] | null;
- hidden?: boolean;
+ hidden: true;
};
export type Form = Record<string, FormItem>;
+
+type GetItemType<Item extends FormItem> =
+ Item['type'] extends 'string' ? string :
+ Item['type'] extends 'number' ? number :
+ Item['type'] extends 'boolean' ? boolean :
+ Item['type'] extends 'radio' ? unknown :
+ Item['type'] extends 'enum' ? string :
+ Item['type'] extends 'array' ? unknown[] :
+ Item['type'] extends 'object' ? Record<string, unknown>
+ : never;
+
+export type GetFormResultType<F extends Form> = {
+ [P in keyof F]: GetItemType<F[P]>;
+};
diff --git a/packages/client/src/scripts/paging.ts b/packages/client/src/scripts/paging.ts
deleted file mode 100644
index ef63ecc450..0000000000
--- a/packages/client/src/scripts/paging.ts
+++ /dev/null
@@ -1,246 +0,0 @@
-import { markRaw } from 'vue';
-import * as os from '@/os';
-import { onScrollTop, isTopVisible, getScrollPosition, getScrollContainer } from './scroll';
-
-const SECOND_FETCH_LIMIT = 30;
-
-// reversed: items 配列の中身を逆順にする(新しい方が最後)
-
-export default (opts) => ({
- emits: ['queue'],
-
- data() {
- return {
- items: [],
- queue: [],
- offset: 0,
- fetching: true,
- moreFetching: false,
- inited: false,
- more: false,
- backed: false, // 遡り中か否か
- isBackTop: false,
- };
- },
-
- computed: {
- empty(): boolean {
- return this.items.length === 0 && !this.fetching && this.inited;
- },
-
- error(): boolean {
- return !this.fetching && !this.inited;
- },
- },
-
- watch: {
- pagination: {
- handler() {
- this.init();
- },
- deep: true
- },
-
- queue: {
- handler(a, b) {
- if (a.length === 0 && b.length === 0) return;
- this.$emit('queue', this.queue.length);
- },
- deep: true
- }
- },
-
- created() {
- opts.displayLimit = opts.displayLimit || 30;
- this.init();
- },
-
- activated() {
- this.isBackTop = false;
- },
-
- deactivated() {
- this.isBackTop = window.scrollY === 0;
- },
-
- methods: {
- reload() {
- this.items = [];
- this.init();
- },
-
- replaceItem(finder, data) {
- const i = this.items.findIndex(finder);
- this.items[i] = data;
- },
-
- removeItem(finder) {
- const i = this.items.findIndex(finder);
- this.items.splice(i, 1);
- },
-
- async init() {
- this.queue = [];
- this.fetching = true;
- if (opts.before) opts.before(this);
- let params = typeof this.pagination.params === 'function' ? this.pagination.params(true) : this.pagination.params;
- if (params && params.then) params = await params;
- if (params === null) return;
- const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint;
- await os.api(endpoint, {
- ...params,
- limit: this.pagination.noPaging ? (this.pagination.limit || 10) : (this.pagination.limit || 10) + 1,
- }).then(items => {
- for (let i = 0; i < items.length; i++) {
- const item = items[i];
- markRaw(item);
- if (this.pagination.reversed) {
- if (i === items.length - 2) item._shouldInsertAd_ = true;
- } else {
- if (i === 3) item._shouldInsertAd_ = true;
- }
- }
- if (!this.pagination.noPaging && (items.length > (this.pagination.limit || 10))) {
- items.pop();
- this.items = this.pagination.reversed ? [...items].reverse() : items;
- this.more = true;
- } else {
- this.items = this.pagination.reversed ? [...items].reverse() : items;
- this.more = false;
- }
- this.offset = items.length;
- this.inited = true;
- this.fetching = false;
- if (opts.after) opts.after(this, null);
- }, e => {
- this.fetching = false;
- if (opts.after) opts.after(this, e);
- });
- },
-
- async fetchMore() {
- if (!this.more || this.fetching || this.moreFetching || this.items.length === 0) return;
- this.moreFetching = true;
- this.backed = true;
- let params = typeof this.pagination.params === 'function' ? this.pagination.params(false) : this.pagination.params;
- if (params && params.then) params = await params;
- const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint;
- await os.api(endpoint, {
- ...params,
- limit: SECOND_FETCH_LIMIT + 1,
- ...(this.pagination.offsetMode ? {
- offset: this.offset,
- } : {
- untilId: this.pagination.reversed ? this.items[0].id : this.items[this.items.length - 1].id,
- }),
- }).then(items => {
- for (let i = 0; i < items.length; i++) {
- const item = items[i];
- markRaw(item);
- if (this.pagination.reversed) {
- if (i === items.length - 9) item._shouldInsertAd_ = true;
- } else {
- if (i === 10) item._shouldInsertAd_ = true;
- }
- }
- if (items.length > SECOND_FETCH_LIMIT) {
- items.pop();
- this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items);
- this.more = true;
- } else {
- this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items);
- this.more = false;
- }
- this.offset += items.length;
- this.moreFetching = false;
- }, e => {
- this.moreFetching = false;
- });
- },
-
- async fetchMoreFeature() {
- if (!this.more || this.fetching || this.moreFetching || this.items.length === 0) return;
- this.moreFetching = true;
- let params = typeof this.pagination.params === 'function' ? this.pagination.params(false) : this.pagination.params;
- if (params && params.then) params = await params;
- const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint;
- await os.api(endpoint, {
- ...params,
- limit: SECOND_FETCH_LIMIT + 1,
- ...(this.pagination.offsetMode ? {
- offset: this.offset,
- } : {
- sinceId: this.pagination.reversed ? this.items[0].id : this.items[this.items.length - 1].id,
- }),
- }).then(items => {
- for (const item of items) {
- markRaw(item);
- }
- if (items.length > SECOND_FETCH_LIMIT) {
- items.pop();
- this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items);
- this.more = true;
- } else {
- this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items);
- this.more = false;
- }
- this.offset += items.length;
- this.moreFetching = false;
- }, e => {
- this.moreFetching = false;
- });
- },
-
- prepend(item) {
- if (this.pagination.reversed) {
- const container = getScrollContainer(this.$el);
- const pos = getScrollPosition(this.$el);
- const viewHeight = container.clientHeight;
- const height = container.scrollHeight;
- const isBottom = (pos + viewHeight > height - 32);
- if (isBottom) {
- // オーバーフローしたら古いアイテムは捨てる
- if (this.items.length >= opts.displayLimit) {
- // このやり方だとVue 3.2以降アニメーションが動かなくなる
- //this.items = this.items.slice(-opts.displayLimit);
- while (this.items.length >= opts.displayLimit) {
- this.items.shift();
- }
- this.more = true;
- }
- }
- this.items.push(item);
- // TODO
- } else {
- const isTop = this.isBackTop || (document.body.contains(this.$el) && isTopVisible(this.$el));
-
- if (isTop) {
- // Prepend the item
- this.items.unshift(item);
-
- // オーバーフローしたら古いアイテムは捨てる
- if (this.items.length >= opts.displayLimit) {
- // このやり方だとVue 3.2以降アニメーションが動かなくなる
- //this.items = this.items.slice(0, opts.displayLimit);
- while (this.items.length >= opts.displayLimit) {
- this.items.pop();
- }
- this.more = true;
- }
- } else {
- this.queue.push(item);
- onScrollTop(this.$el, () => {
- for (const item of this.queue) {
- this.prepend(item);
- }
- this.queue = [];
- });
- }
- }
- },
-
- append(item) {
- this.items.push(item);
- },
- }
-});