Merge branch 'feature/emoji-grid' of https://github.com/samunohito/misskey into pr/13473

This commit is contained in:
syuilo 2024-06-13 10:14:37 +09:00
commit 1bb237126c
5 changed files with 76 additions and 67 deletions

View file

@ -3,6 +3,8 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import seedrandom from 'seedrandom';
/**
* AIで生成した無作為なファーストネーム
*/
@ -30,18 +32,21 @@ export const countryDict = [
'Vietnam', 'Kenya', 'Saudi Arabia', 'Netherlands', 'Colombia', 'Poland', 'Chile', 'Malaysia', 'Ukraine', 'New Zealand', 'Peru',
]
export function text(length: number = 10): string {
export function text(length: number = 10, seed?: string): string {
let result = "";
// シード値を使う場合、同じ数値が羅列されるが、ランダム文字列という意味では満たせていると思うのでこのまま使っておく
const rand = seed ? seedrandom(seed)() : Math.random();
while (result.length < length) {
result += Math.random().toString(36).substring(2);
result += rand.toString(36).substring(2);
}
return result.substring(0, length);
}
export function integer(min: number = 0, max: number = 9999): number {
return Math.floor(Math.random() * (max - min)) + min;
export function integer(min: number = 0, max: number = 9999, seed?: string): number {
const rand = seed ? seedrandom(seed)() : Math.random();
return Math.floor(rand * (max - min)) + min;
}
export function date(params?: {
@ -59,10 +64,10 @@ export function date(params?: {
secondMax?: number,
millisecondMin?: number,
millisecondMax?: number,
}) {
const year = integer(params?.yearMin ?? 1970, params?.yearMax ?? (new Date()).getFullYear());
const month = integer(params?.monthMin ?? 1, params?.monthMax ?? 12);
let day = integer(params?.dayMin ?? 1, params?.dayMax ?? 31);
}, seed?: string): Date {
const year = integer(params?.yearMin ?? 1970, params?.yearMax ?? (new Date()).getFullYear(), seed);
const month = integer(params?.monthMin ?? 1, params?.monthMax ?? 12, seed);
let day = integer(params?.dayMin ?? 1, params?.dayMax ?? 31, seed);
if (month === 2) {
day = Math.min(day, 28);
} else if ([4, 6, 9, 11].includes(month)) {
@ -71,43 +76,45 @@ export function date(params?: {
day = Math.min(day, 31);
}
const hour = integer(params?.hourMin ?? 0, params?.hourMax ?? 23);
const minute = integer(params?.minuteMin ?? 0, params?.minuteMax ?? 59);
const second = integer(params?.secondMin ?? 0, params?.secondMax ?? 59);
const millisecond = integer(params?.millisecondMin ?? 0, params?.millisecondMax ?? 999);
const hour = integer(params?.hourMin ?? 0, params?.hourMax ?? 23, seed);
const minute = integer(params?.minuteMin ?? 0, params?.minuteMax ?? 59, seed);
const second = integer(params?.secondMin ?? 0, params?.secondMax ?? 59, seed);
const millisecond = integer(params?.millisecondMin ?? 0, params?.millisecondMax ?? 999, seed);
return new Date(year, month - 1, day, hour, minute, second, millisecond);
}
export function boolean(): boolean {
return Math.random() < 0.5;
export function boolean(seed?: string): boolean {
const rand = seed ? seedrandom(seed)() : Math.random();
return rand < 0.5;
}
export function choose<T>(array: T[]): T {
return array[Math.floor(Math.random() * array.length)];
export function choose<T>(array: T[], seed?: string): T {
const rand = seed ? seedrandom(seed)() : Math.random();
return array[Math.floor(rand * array.length)];
}
export function firstName(): string {
return choose(firstNameDict);
export function firstName(seed?: string): string {
return choose(firstNameDict, seed);
}
export function lastName(): string {
return choose(lastNameDict);
export function lastName(seed?: string): string {
return choose(lastNameDict, seed);
}
export function country(): string {
return choose(countryDict);
export function country(seed?: string): string {
return choose(countryDict, seed);
}
const TIME2000 = 946684800000;
export function fakeId(): string {
export function fakeId(seed?: string): string {
let time = new Date().getTime();
time = time - TIME2000;
if (time < 0) time = 0;
const timeStr = time.toString(36).padStart(8, '0');
const noiseStr = text(2);
const noiseStr = text(2, seed);
return timeStr + noiseStr;
}
@ -123,7 +130,7 @@ export function imageDataUrl(options?: {
blue?: number,
alpha?: number,
}
}): string {
}, seed?: string): string {
const canvas = document.createElement('canvas');
canvas.width = options?.size?.width ?? 100;
canvas.height = options?.size?.height ?? 100;
@ -135,9 +142,9 @@ export function imageDataUrl(options?: {
ctx.beginPath()
const red = options?.color?.red ?? integer(0, 255);
const green = options?.color?.green ?? integer(0, 255);
const blue = options?.color?.blue ?? integer(0, 255);
const red = options?.color?.red ?? integer(0, 255, seed);
const green = options?.color?.green ?? integer(0, 255, seed);
const blue = options?.color?.blue ?? integer(0, 255, seed);
const alpha = options?.color?.alpha ?? 1;
ctx.arc(canvas.width / 2, canvas.height / 2, canvas.width / 2, 0, Math.PI * 2, true);
ctx.fillStyle = `rgba(${red}, ${green}, ${blue}, ${alpha})`;

View file

@ -4,7 +4,7 @@
*/
import type { entities } from 'misskey-js'
import { imageDataUrl, text } from "./fake-utils.js";
import { date, imageDataUrl, text } from "./fake-utils.js";
export function abuseUserReport() {
return {
@ -232,9 +232,11 @@ export function role(params: {
asBadge?: boolean,
canEditMembersByModerator?: boolean,
usersCount?: number,
}): entities.Role {
}, seed?: string): entities.Role {
const prefix = params.displayOrder ? params.displayOrder.toString().padStart(3, '0') + '-' : '';
const genId = Math.random().toString(36).substring(10);
const genId = text(36, seed);
const createdAt = params.createdAt ?? date({}, seed).toISOString();
const updatedAt = params.updatedAt ?? date({}, seed).toISOString();
return {
id: params.id ?? genId,
@ -245,8 +247,8 @@ export function role(params: {
isModerator: params.isModerator ?? false,
isAdministrator: params.isAdministrator ?? false,
displayOrder: params.displayOrder ?? 0,
createdAt: params.createdAt ?? new Date().toISOString(),
updatedAt: params.updatedAt ?? new Date().toISOString(),
createdAt: createdAt,
updatedAt: updatedAt,
target: params.target ?? 'manual',
isPublic: params.isPublic ?? true,
isExplorable: params.isExplorable ?? true,
@ -277,11 +279,13 @@ export function emoji(params?: {
localOnly?: boolean,
roleIdsThatCanBeUsedThisEmojiAsReaction?: {id:string, name:string}[],
updatedAt?: string,
}): entities.EmojiDetailedAdmin {
const id = params?.id ?? new Date().getTime().toString() + text(5);
const name = params?.name ?? text(8);
}, seed?: string): entities.EmojiDetailedAdmin {
const _seed = seed ?? (params?.id ?? "DEFAULT_SEED");
const id = params?.id ?? text(32, _seed);
const name = params?.name ?? text(8, _seed);
const updatedAt = params?.updatedAt ?? date({}, _seed).toISOString();
const image = imageDataUrl()
const image = imageDataUrl({}, _seed)
return {
id: id,
@ -297,6 +301,6 @@ export function emoji(params?: {
isSensitive: params?.isSensitive ?? false,
localOnly: params?.localOnly ?? false,
roleIdsThatCanBeUsedThisEmojiAsReaction: params?.roleIdsThatCanBeUsedThisEmojiAsReaction ?? [],
updatedAt: params?.updatedAt ?? new Date().toISOString(),
updatedAt: updatedAt,
}
}

View file

@ -11,10 +11,10 @@ import { commonHandlers } from '../../.storybook/mocks.js';
import MkRoleSelectDialog from '@/components/MkRoleSelectDialog.vue';
const roles = [
role({ displayOrder: 1 }), role({ displayOrder: 1 }), role({ displayOrder: 1 }), role({ displayOrder: 1 }),
role({ displayOrder: 2 }), role({ displayOrder: 2 }), role({ displayOrder: 3 }), role({ displayOrder: 3 }),
role({ displayOrder: 4 }), role({ displayOrder: 5 }), role({ displayOrder: 6 }), role({ displayOrder: 7 }),
role({ displayOrder: 999, name: 'privateRole', isPublic: false }),
role({ displayOrder: 1 }, '1'), role({ displayOrder: 1 }, '1'), role({ displayOrder: 1 }, '1'), role({ displayOrder: 1 }, '1'),
role({ displayOrder: 2 }, '2'), role({ displayOrder: 2 }, '2'), role({ displayOrder: 3 }, '3'), role({ displayOrder: 3 }, '3'),
role({ displayOrder: 4 }, '4'), role({ displayOrder: 5 }, '5'), role({ displayOrder: 6 }, '6'), role({ displayOrder: 7 }, '7'),
role({ displayOrder: 999, name: 'privateRole', isPublic: false }, '999'),
];
export const Default = {

View file

@ -12,6 +12,7 @@ import { boolean, choose, country, date, firstName, integer, lastName, text } fr
import MkGrid from './MkGrid.vue';
import { GridContext, GridEvent } from '@/components/grid/grid-event.js';
import { DataSource, GridSetting } from '@/components/grid/grid.js';
import { GridColumnSetting } from '@/components/grid/column.js';
function d(p: {
check?: boolean,
@ -23,23 +24,23 @@ function d(p: {
country?: string,
reportCount?: number,
createdAt?: string,
}) {
const prefix = text(10);
}, seed: string) {
const prefix = text(10, seed);
return {
check: p.check ?? boolean(),
name: p.name ?? `${firstName()} ${lastName()}`,
check: p.check ?? boolean(seed),
name: p.name ?? `${firstName(seed)} ${lastName(seed)}`,
email: p.email ?? `${prefix}@example.com`,
age: p.age ?? integer(20, 80),
birthday: date().toISOString(),
gender: p.gender ?? choose(['male', 'female', 'other', 'unknown']),
country: p.country ?? country(),
reportCount: p.reportCount ?? integer(),
createdAt: p.createdAt ?? date().toISOString(),
age: p.age ?? integer(20, 80, seed),
birthday: date({}, seed).toISOString(),
gender: p.gender ?? choose(['male', 'female', 'other', 'unknown'], seed),
country: p.country ?? country(seed),
reportCount: p.reportCount ?? integer(0, 9999, seed),
createdAt: p.createdAt ?? date({}, seed).toISOString(),
};
}
const defaultCols = [
const defaultCols: GridColumnSetting[] = [
{ bindTo: 'check', icon: 'ti-check', type: 'boolean', width: 50 },
{ bindTo: 'name', title: 'Name', type: 'text', width: 'auto' },
{ bindTo: 'email', title: 'Email', type: 'text', width: 'auto' },
@ -52,13 +53,10 @@ const defaultCols = [
];
function createArgs(overrides?: { settings?: Partial<GridSetting>, data?: DataSource[] }) {
const refData = ref([
d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}),
d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}),
d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}),
d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}),
d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}), d({}),
]);
const refData = ref<ReturnType<typeof d>[]>([]);
for (let i = 0; i < 100; i++) {
refData.value.push(d({}, i.toString()));
}
return {
settings: {
@ -73,7 +71,7 @@ function createArgs(overrides?: { settings?: Partial<GridSetting>, data?: DataSo
};
}
function createRender(params: { settings: Partial<GridSetting>, data: DataSource[] }) {
function createRender(params: { settings: GridSetting, data: DataSource[] }) {
return {
render(args) {
return {
@ -155,7 +153,7 @@ export const AdditionalRowStyle = createRender(createArgs({
row: {
styleRules: [
{
condition: ({ row }) => AdditionalRowStyle.args.data[row.index].check,
condition: ({ row }) => AdditionalRowStyle.args.data[row.index].check as boolean,
applyStyle: {
style: {
backgroundColor: 'lightgray',

View file

@ -89,7 +89,7 @@ function createRender(params: {
});
const driveFile: entities.DriveFile = {
id: fakeId(),
id: fakeId(file.name),
createdAt: new Date().toISOString(),
name: file.name,
type: file.type,
@ -122,7 +122,7 @@ function createRender(params: {
const file = storedDriveFiles.find(f => f.id === fileId)!;
const em = emoji({
id: fakeId(),
id: fakeId(file.name),
name: body.name,
publicUrl: file.url,
originalUrl: file.url,
@ -148,13 +148,13 @@ export const Default = createRender({
});
export const List10 = createRender({
emojis: Array.from({ length: 10 }, (_, i) => emoji({ name: `emoji_${i}` })),
emojis: Array.from({ length: 10 }, (_, i) => emoji({ name: `emoji_${i}` }, i.toString())),
});
export const List100 = createRender({
emojis: Array.from({ length: 100 }, (_, i) => emoji({ name: `emoji_${i}` })),
emojis: Array.from({ length: 100 }, (_, i) => emoji({ name: `emoji_${i}` }, i.toString())),
});
export const List1000 = createRender({
emojis: Array.from({ length: 1000 }, (_, i) => emoji({ name: `emoji_${i}` })),
emojis: Array.from({ length: 1000 }, (_, i) => emoji({ name: `emoji_${i}` }, i.toString())),
});