mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-03 23:14:13 +00:00 
			
		
		
		
	refactor(frontend): remove redundant class names (#12618)
This commit is contained in:
		
							parent
							
								
									4c135a5ca1
								
							
						
					
					
						commit
						2217d0c050
					
				
					 9 changed files with 222 additions and 29 deletions
				
			
		| 
						 | 
				
			
			@ -180,7 +180,7 @@ import './photoswipe-!~{003}~.js';
 | 
			
		|||
const _hoisted_1 = createBaseVNode("i", {
 | 
			
		||||
  class: "ti ti-photo"
 | 
			
		||||
}, null, -1);
 | 
			
		||||
const _sfc_main = defineComponent({
 | 
			
		||||
const index_photos = defineComponent({
 | 
			
		||||
  __name: "index.photos",
 | 
			
		||||
  props: {
 | 
			
		||||
    user: {}
 | 
			
		||||
| 
						 | 
				
			
			@ -261,7 +261,6 @@ const style0 = {
 | 
			
		|||
const cssModules = {
 | 
			
		||||
  "$style": style0
 | 
			
		||||
};
 | 
			
		||||
const index_photos = _sfc_main;
 | 
			
		||||
export {index_photos as default};
 | 
			
		||||
`.slice(1));
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,13 +13,13 @@ function isFalsyIdentifier(identifier: estree.Identifier): boolean {
 | 
			
		|||
	return identifier.name === 'undefined' || identifier.name === 'NaN';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function normalizeClassWalker(tree: estree.Node): string | null {
 | 
			
		||||
function normalizeClassWalker(tree: estree.Node, stack: string | undefined): string | null {
 | 
			
		||||
	if (tree.type === 'Identifier') return isFalsyIdentifier(tree) ? '' : null;
 | 
			
		||||
	if (tree.type === 'Literal') return typeof tree.value === 'string' ? tree.value : '';
 | 
			
		||||
	if (tree.type === 'BinaryExpression') {
 | 
			
		||||
		if (tree.operator !== '+') return null;
 | 
			
		||||
		const left = normalizeClassWalker(tree.left);
 | 
			
		||||
		const right = normalizeClassWalker(tree.right);
 | 
			
		||||
		const left = normalizeClassWalker(tree.left, stack);
 | 
			
		||||
		const right = normalizeClassWalker(tree.right, stack);
 | 
			
		||||
		if (left === null || right === null) return null;
 | 
			
		||||
		return `${left}${right}`;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -33,15 +33,15 @@ function normalizeClassWalker(tree: estree.Node): string | null {
 | 
			
		|||
	if (tree.type === 'ArrayExpression') {
 | 
			
		||||
		const values = tree.elements.map((treeNode) => {
 | 
			
		||||
			if (treeNode === null) return '';
 | 
			
		||||
			if (treeNode.type === 'SpreadElement') return normalizeClassWalker(treeNode.argument);
 | 
			
		||||
			return normalizeClassWalker(treeNode);
 | 
			
		||||
			if (treeNode.type === 'SpreadElement') return normalizeClassWalker(treeNode.argument, stack);
 | 
			
		||||
			return normalizeClassWalker(treeNode, stack);
 | 
			
		||||
		});
 | 
			
		||||
		if (values.some((x) => x === null)) return null;
 | 
			
		||||
		return values.join(' ');
 | 
			
		||||
	}
 | 
			
		||||
	if (tree.type === 'ObjectExpression') {
 | 
			
		||||
		const values = tree.properties.map((treeNode) => {
 | 
			
		||||
			if (treeNode.type === 'SpreadElement') return normalizeClassWalker(treeNode.argument);
 | 
			
		||||
			if (treeNode.type === 'SpreadElement') return normalizeClassWalker(treeNode.argument, stack);
 | 
			
		||||
			let x = treeNode.value;
 | 
			
		||||
			let inveted = false;
 | 
			
		||||
			while (x.type === 'UnaryExpression' && x.operator === '!') {
 | 
			
		||||
| 
						 | 
				
			
			@ -67,18 +67,26 @@ function normalizeClassWalker(tree: estree.Node): string | null {
 | 
			
		|||
		if (values.some((x) => x === null)) return null;
 | 
			
		||||
		return values.join(' ');
 | 
			
		||||
	}
 | 
			
		||||
	console.error(`Unexpected node type: ${tree.type}`);
 | 
			
		||||
	if (
 | 
			
		||||
		tree.type !== 'CallExpression' &&
 | 
			
		||||
		tree.type !== 'ChainExpression' &&
 | 
			
		||||
		tree.type !== 'ConditionalExpression' &&
 | 
			
		||||
		tree.type !== 'LogicalExpression' &&
 | 
			
		||||
		tree.type !== 'MemberExpression') {
 | 
			
		||||
		console.error(stack ? `Unexpected node type: ${tree.type} (in ${stack})` : `Unexpected node type: ${tree.type}`);
 | 
			
		||||
	}
 | 
			
		||||
	return null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function normalizeClass(tree: estree.Node): string | null {
 | 
			
		||||
	const walked = normalizeClassWalker(tree);
 | 
			
		||||
export function normalizeClass(tree: estree.Node, stack?: string): string | null {
 | 
			
		||||
	const walked = normalizeClassWalker(tree, stack);
 | 
			
		||||
	return walked && walked.replace(/^\s+|\s+(?=\s)|\s+$/g, '');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function unwindCssModuleClassName(ast: estree.Node): void {
 | 
			
		||||
	(walk as typeof estreeWalker.walk)(ast, {
 | 
			
		||||
		enter(node, parent): void {
 | 
			
		||||
			//#region
 | 
			
		||||
			if (parent?.type !== 'Program') return;
 | 
			
		||||
			if (node.type !== 'VariableDeclaration') return;
 | 
			
		||||
			if (node.declarations.length !== 1) return;
 | 
			
		||||
| 
						 | 
				
			
			@ -102,6 +110,14 @@ export function unwindCssModuleClassName(ast: estree.Node): void {
 | 
			
		|||
				return true;
 | 
			
		||||
			});
 | 
			
		||||
			if (!~__cssModulesIndex) return;
 | 
			
		||||
			/* This region assumeed that the entered node looks like the following code.
 | 
			
		||||
			 *
 | 
			
		||||
			 * ```ts
 | 
			
		||||
			 * const SomeComponent = _export_sfc(_sfc_main, [["foo", bar], ["__cssModules", cssModules]]);
 | 
			
		||||
			 * ```
 | 
			
		||||
			 */
 | 
			
		||||
			//#endregion
 | 
			
		||||
			//#region
 | 
			
		||||
			const cssModuleForestName = ((node.declarations[0].init.arguments[1].elements[__cssModulesIndex] as estree.ArrayExpression).elements[1] as estree.Identifier).name;
 | 
			
		||||
			const cssModuleForestNode = parent.body.find((x) => {
 | 
			
		||||
				if (x.type !== 'VariableDeclaration') return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -117,6 +133,16 @@ export function unwindCssModuleClassName(ast: estree.Node): void {
 | 
			
		|||
				if (property.value.type !== 'Identifier') return [];
 | 
			
		||||
				return [[property.key.value as string, property.value.name as string]];
 | 
			
		||||
			}));
 | 
			
		||||
			/* This region collected a VariableDeclaration node in the module that looks like the following code.
 | 
			
		||||
			 *
 | 
			
		||||
			 * ```ts
 | 
			
		||||
			 * const cssModules = {
 | 
			
		||||
			 *   "$style": style0,
 | 
			
		||||
			 * };
 | 
			
		||||
			 * ```
 | 
			
		||||
			 */
 | 
			
		||||
			//#endregion
 | 
			
		||||
			//#region
 | 
			
		||||
			const sfcMain = parent.body.find((x) => {
 | 
			
		||||
				if (x.type !== 'VariableDeclaration') return false;
 | 
			
		||||
				if (x.declarations.length !== 1) return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +172,22 @@ export function unwindCssModuleClassName(ast: estree.Node): void {
 | 
			
		|||
			if (ctx.type !== 'Identifier') return;
 | 
			
		||||
			if (ctx.name !== '_ctx') return;
 | 
			
		||||
			if (render.argument.body.type !== 'BlockStatement') return;
 | 
			
		||||
			/* This region assumed that `sfcMain` looks like the following code.
 | 
			
		||||
			 *
 | 
			
		||||
			 * ```ts
 | 
			
		||||
			 * const _sfc_main = defineComponent({
 | 
			
		||||
			 *   setup(_props) {
 | 
			
		||||
			 *     ...
 | 
			
		||||
			 *     return (_ctx, _cache) => {
 | 
			
		||||
			 *       ...
 | 
			
		||||
			 *     };
 | 
			
		||||
			 *   },
 | 
			
		||||
			 * });
 | 
			
		||||
			 * ```
 | 
			
		||||
			 */
 | 
			
		||||
			//#endregion
 | 
			
		||||
			for (const [key, value] of moduleForest) {
 | 
			
		||||
				//#region
 | 
			
		||||
				const cssModuleTreeNode = parent.body.find((x) => {
 | 
			
		||||
					if (x.type !== 'VariableDeclaration') return false;
 | 
			
		||||
					if (x.declarations.length !== 1) return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -172,6 +213,19 @@ export function unwindCssModuleClassName(ast: estree.Node): void {
 | 
			
		|||
					if (actualValue.declarations[0].init?.type !== 'Literal') return [];
 | 
			
		||||
					return [[actualKey, actualValue.declarations[0].init.value as string]];
 | 
			
		||||
				}));
 | 
			
		||||
				/* This region collected VariableDeclaration nodes in the module that looks like the following code.
 | 
			
		||||
				 *
 | 
			
		||||
				 * ```ts
 | 
			
		||||
				 * const foo = "bar";
 | 
			
		||||
				 * const baz = "qux";
 | 
			
		||||
				 * const style0 = {
 | 
			
		||||
				 *   foo: foo,
 | 
			
		||||
				 *   baz: baz,
 | 
			
		||||
				 * };
 | 
			
		||||
				 * ```
 | 
			
		||||
				 */
 | 
			
		||||
				//#endregion
 | 
			
		||||
				//#region
 | 
			
		||||
				(walk as typeof estreeWalker.walk)(render.argument.body, {
 | 
			
		||||
					enter(childNode) {
 | 
			
		||||
						if (childNode.type !== 'MemberExpression') return;
 | 
			
		||||
| 
						 | 
				
			
			@ -189,6 +243,39 @@ export function unwindCssModuleClassName(ast: estree.Node): void {
 | 
			
		|||
						});
 | 
			
		||||
					},
 | 
			
		||||
				});
 | 
			
		||||
				/* This region inlined the reference identifier of the class name in the render function into the actual literal, as in the following code.
 | 
			
		||||
				 *
 | 
			
		||||
				 * ```ts
 | 
			
		||||
				 * const _sfc_main = defineComponent({
 | 
			
		||||
				 *   setup(_props) {
 | 
			
		||||
				 *     ...
 | 
			
		||||
				 *     return (_ctx, _cache) => {
 | 
			
		||||
				 *       ...
 | 
			
		||||
				 *       return openBlock(), createElementBlock("div", {
 | 
			
		||||
				 *         class: normalizeClass(_ctx.$style.foo),
 | 
			
		||||
				 *       }, null);
 | 
			
		||||
				 *     };
 | 
			
		||||
				 *   },
 | 
			
		||||
				 * });
 | 
			
		||||
				 * ```
 | 
			
		||||
				 *
 | 
			
		||||
				 * ↓
 | 
			
		||||
				 *
 | 
			
		||||
				 * ```ts
 | 
			
		||||
				 * const _sfc_main = defineComponent({
 | 
			
		||||
				 *   setup(_props) {
 | 
			
		||||
				 *     ...
 | 
			
		||||
				 *     return (_ctx, _cache) => {
 | 
			
		||||
				 *       ...
 | 
			
		||||
				 *       return openBlock(), createElementBlock("div", {
 | 
			
		||||
				 *         class: normalizeClass("bar"),
 | 
			
		||||
				 *       }, null);
 | 
			
		||||
				 *     };
 | 
			
		||||
				 *   },
 | 
			
		||||
				 * });
 | 
			
		||||
				 */
 | 
			
		||||
				//#endregion
 | 
			
		||||
				//#region
 | 
			
		||||
				(walk as typeof estreeWalker.walk)(render.argument.body, {
 | 
			
		||||
					enter(childNode) {
 | 
			
		||||
						if (childNode.type !== 'MemberExpression') return;
 | 
			
		||||
| 
						 | 
				
			
			@ -205,13 +292,47 @@ export function unwindCssModuleClassName(ast: estree.Node): void {
 | 
			
		|||
						});
 | 
			
		||||
					},
 | 
			
		||||
				});
 | 
			
		||||
				/* This region replaced the reference identifier of missing class names in the render function with `undefined`, as in the following code.
 | 
			
		||||
				 *
 | 
			
		||||
				 * ```ts
 | 
			
		||||
				 * const _sfc_main = defineComponent({
 | 
			
		||||
				 *   setup(_props) {
 | 
			
		||||
				 *     ...
 | 
			
		||||
				 *     return (_ctx, _cache) => {
 | 
			
		||||
				 *       ...
 | 
			
		||||
				 *       return openBlock(), createElementBlock("div", {
 | 
			
		||||
				 *         class: normalizeClass(_ctx.$style.hoge),
 | 
			
		||||
				 *       }, null);
 | 
			
		||||
				 *     };
 | 
			
		||||
				 *   },
 | 
			
		||||
				 * });
 | 
			
		||||
				 * ```
 | 
			
		||||
				 *
 | 
			
		||||
				 * ↓
 | 
			
		||||
				 *
 | 
			
		||||
				 * ```ts
 | 
			
		||||
				 * const _sfc_main = defineComponent({
 | 
			
		||||
				 *   setup(_props) {
 | 
			
		||||
				 *     ...
 | 
			
		||||
				 *     return (_ctx, _cache) => {
 | 
			
		||||
				 *       ...
 | 
			
		||||
				 *       return openBlock(), createElementBlock("div", {
 | 
			
		||||
				 *         class: normalizeClass(undefined),
 | 
			
		||||
				 *       }, null);
 | 
			
		||||
				 *     };
 | 
			
		||||
				 *   },
 | 
			
		||||
				 * });
 | 
			
		||||
				 * ```
 | 
			
		||||
				 */
 | 
			
		||||
				//#endregion
 | 
			
		||||
				//#region
 | 
			
		||||
				(walk as typeof estreeWalker.walk)(render.argument.body, {
 | 
			
		||||
					enter(childNode) {
 | 
			
		||||
						if (childNode.type !== 'CallExpression') return;
 | 
			
		||||
						if (childNode.callee.type !== 'Identifier') return;
 | 
			
		||||
						if (childNode.callee.name !== 'normalizeClass') return;
 | 
			
		||||
						if (childNode.arguments.length !== 1) return;
 | 
			
		||||
						const normalized = normalizeClass(childNode.arguments[0]);
 | 
			
		||||
						const normalized = normalizeClass(childNode.arguments[0], name);
 | 
			
		||||
						if (normalized === null) return;
 | 
			
		||||
						this.replace({
 | 
			
		||||
							type: 'Literal',
 | 
			
		||||
| 
						 | 
				
			
			@ -219,8 +340,60 @@ export function unwindCssModuleClassName(ast: estree.Node): void {
 | 
			
		|||
						});
 | 
			
		||||
					},
 | 
			
		||||
				});
 | 
			
		||||
				/* This region compiled the `normalizeClass` call into a pseudo-AOT compilation, as in the following code.
 | 
			
		||||
				 *
 | 
			
		||||
				 * ```ts
 | 
			
		||||
				 * const _sfc_main = defineComponent({
 | 
			
		||||
				 *   setup(_props) {
 | 
			
		||||
				 *     ...
 | 
			
		||||
				 *     return (_ctx, _cache) => {
 | 
			
		||||
				 *       ...
 | 
			
		||||
				 *       return openBlock(), createElementBlock("div", {
 | 
			
		||||
				 *         class: normalizeClass("bar"),
 | 
			
		||||
				 *       }, null);
 | 
			
		||||
				 *     };
 | 
			
		||||
				 *   },
 | 
			
		||||
				 * });
 | 
			
		||||
				 * ```
 | 
			
		||||
				 *
 | 
			
		||||
				 * ↓
 | 
			
		||||
				 *
 | 
			
		||||
				 * ```ts
 | 
			
		||||
				 * const _sfc_main = defineComponent({
 | 
			
		||||
				 *   setup(_props) {
 | 
			
		||||
				 *     ...
 | 
			
		||||
				 *     return (_ctx, _cache) => {
 | 
			
		||||
				 *       ...
 | 
			
		||||
				 *       return openBlock(), createElementBlock("div", {
 | 
			
		||||
				 *         class: "bar",
 | 
			
		||||
				 *       }, null);
 | 
			
		||||
				 *     };
 | 
			
		||||
				 *   },
 | 
			
		||||
				 * });
 | 
			
		||||
				 * ```
 | 
			
		||||
				 */
 | 
			
		||||
				//#endregion
 | 
			
		||||
			}
 | 
			
		||||
			//#region
 | 
			
		||||
			if (node.declarations[0].init.arguments[1].elements.length === 1) {
 | 
			
		||||
				(walk as typeof estreeWalker.walk)(ast, {
 | 
			
		||||
					enter(childNode) {
 | 
			
		||||
						if (childNode.type !== 'Identifier') return;
 | 
			
		||||
						if (childNode.name !== ident) return;
 | 
			
		||||
						this.replace({
 | 
			
		||||
							type: 'Identifier',
 | 
			
		||||
							name: node.declarations[0].id.name,
 | 
			
		||||
						});
 | 
			
		||||
					},
 | 
			
		||||
				});
 | 
			
		||||
				this.remove();
 | 
			
		||||
				/* NOTE: The above logic is valid as long as the following two conditions are met.
 | 
			
		||||
				 *
 | 
			
		||||
				 * - the uniqueness of `ident` is kept throughout the module
 | 
			
		||||
				 * - `_export_sfc` is noop when the second argument is an empty array
 | 
			
		||||
				 *
 | 
			
		||||
				 * Otherwise, the below logic should be used instead.
 | 
			
		||||
 | 
			
		||||
				this.replace({
 | 
			
		||||
					type: 'VariableDeclaration',
 | 
			
		||||
					declarations: [{
 | 
			
		||||
| 
						 | 
				
			
			@ -236,6 +409,7 @@ export function unwindCssModuleClassName(ast: estree.Node): void {
 | 
			
		|||
					}],
 | 
			
		||||
					kind: 'const',
 | 
			
		||||
				});
 | 
			
		||||
				 */
 | 
			
		||||
			} else {
 | 
			
		||||
				this.replace({
 | 
			
		||||
					type: 'VariableDeclaration',
 | 
			
		||||
| 
						 | 
				
			
			@ -263,6 +437,35 @@ export function unwindCssModuleClassName(ast: estree.Node): void {
 | 
			
		|||
					kind: 'const',
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
			/* This region removed the `__cssModules` reference from the second argument of `_export_sfc`, as in the following code.
 | 
			
		||||
			 *
 | 
			
		||||
			 * ```ts
 | 
			
		||||
			 * const SomeComponent = _export_sfc(_sfc_main, [["foo", bar], ["__cssModules", cssModules]]);
 | 
			
		||||
			 * ```
 | 
			
		||||
			 *
 | 
			
		||||
			 * ↓
 | 
			
		||||
			 *
 | 
			
		||||
			 * ```ts
 | 
			
		||||
			 * const SomeComponent = _export_sfc(_sfc_main, [["foo", bar]]);
 | 
			
		||||
			 * ```
 | 
			
		||||
			 *
 | 
			
		||||
			 * When the declaration becomes noop, it is removed as follows.
 | 
			
		||||
			 *
 | 
			
		||||
			 * ```ts
 | 
			
		||||
			 * const _sfc_main = defineComponent({
 | 
			
		||||
			 *   ...
 | 
			
		||||
			 * });
 | 
			
		||||
			 * const SomeComponent = _export_sfc(_sfc_main, []);
 | 
			
		||||
			 * ```
 | 
			
		||||
			 *
 | 
			
		||||
			 * ↓
 | 
			
		||||
			 *
 | 
			
		||||
			 * ```ts
 | 
			
		||||
			 * const SomeComponent = defineComponent({
 | 
			
		||||
			 *   ...
 | 
			
		||||
			 * });
 | 
			
		||||
			 */
 | 
			
		||||
			//#endregion
 | 
			
		||||
		},
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		|||
-->
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
<div :class="[$style.codeEditorRoot, { [$style.disabled]: disabled, [$style.focused]: focused }]">
 | 
			
		||||
<div :class="[$style.codeEditorRoot, { [$style.focused]: focused }]">
 | 
			
		||||
	<div :class="$style.codeEditorScroller">
 | 
			
		||||
		<textarea
 | 
			
		||||
			ref="inputEl"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -145,7 +145,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		|||
		<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'reactions' }]" @click="tab = 'reactions'"><i class="ti ti-icons"></i> {{ i18n.ts.reactions }}</button>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div>
 | 
			
		||||
		<div v-if="tab === 'replies'" :class="$style.tab_replies">
 | 
			
		||||
		<div v-if="tab === 'replies'">
 | 
			
		||||
			<div v-if="!repliesLoaded" style="padding: 16px">
 | 
			
		||||
				<MkButton style="margin: 0 auto;" primary rounded @click="loadReplies">{{ i18n.ts.loadReplies }}</MkButton>
 | 
			
		||||
			</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		|||
-->
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
<div :class="[$style.root, { [$style.disabled]: disabled, [$style.checked]: checked }]">
 | 
			
		||||
<div :class="[$style.root, { [$style.disabled]: disabled }]">
 | 
			
		||||
	<input
 | 
			
		||||
		ref="input"
 | 
			
		||||
		type="checkbox"
 | 
			
		||||
| 
						 | 
				
			
			@ -64,9 +64,6 @@ const toggle = () => {
 | 
			
		|||
		opacity: 0.6;
 | 
			
		||||
		cursor: not-allowed;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//&.checked {
 | 
			
		||||
	//}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.input {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -134,10 +134,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		|||
			<div v-else-if="tab === 'roles'" class="_gaps">
 | 
			
		||||
				<MkButton v-if="user.host == null" primary rounded @click="assignRole"><i class="ti ti-plus"></i> {{ i18n.ts.assign }}</MkButton>
 | 
			
		||||
 | 
			
		||||
				<div v-for="role in info.roles" :key="role.id" :class="$style.roleItem">
 | 
			
		||||
				<div v-for="role in info.roles" :key="role.id">
 | 
			
		||||
					<div :class="$style.roleItemMain">
 | 
			
		||||
						<MkRolePreview :class="$style.role" :role="role" :forModeration="true"/>
 | 
			
		||||
						<button class="_button" :class="$style.roleToggle" @click="toggleRoleItem(role)"><i class="ti ti-chevron-down"></i></button>
 | 
			
		||||
						<button class="_button" @click="toggleRoleItem(role)"><i class="ti ti-chevron-down"></i></button>
 | 
			
		||||
						<button v-if="role.target === 'manual'" class="_button" :class="$style.roleUnassign" @click="unassignRole(role, $event)"><i class="ti ti-x"></i></button>
 | 
			
		||||
						<button v-else class="_button" :class="$style.roleUnassign" disabled><i class="ti ti-ban"></i></button>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -621,9 +621,6 @@ definePageMetadata(computed(() => ({
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.roleItem {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.roleItemMain {
 | 
			
		||||
	display: flex;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		|||
		<MkTime :time="log.createdAt"/>
 | 
			
		||||
	</template>
 | 
			
		||||
 | 
			
		||||
	<div :class="$style.root">
 | 
			
		||||
	<div>
 | 
			
		||||
		<div style="display: flex; gap: var(--margin); flex-wrap: wrap;">
 | 
			
		||||
			<div style="flex: 1;">{{ i18n.ts.moderator }}: <MkA :to="`/admin/user/${log.userId}`" class="_link">@{{ log.user?.username }}</MkA></div>
 | 
			
		||||
			<div style="flex: 1;">{{ i18n.ts.dateAndTime }}: <MkTime :time="log.createdAt" mode="detail"/></div>
 | 
			
		||||
| 
						 | 
				
			
			@ -134,9 +134,6 @@ const props = defineProps<{
 | 
			
		|||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" module>
 | 
			
		||||
.root {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.avatar {
 | 
			
		||||
	width: 18px;
 | 
			
		||||
	height: 18px;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		|||
	<XSidebar v-if="!isMobile"/>
 | 
			
		||||
 | 
			
		||||
	<div :class="$style.main">
 | 
			
		||||
		<XAnnouncements v-if="$i" :class="$style.announcements"/>
 | 
			
		||||
		<XAnnouncements v-if="$i"/>
 | 
			
		||||
		<XStatusBars/>
 | 
			
		||||
		<div ref="columnsEl" :class="[$style.sections, { [$style.center]: deckStore.reactiveState.columnAlign.value === 'center', [$style.snapScroll]: snapScroll }]" @contextmenu.self.prevent="onContextmenu" @wheel.self="onWheel">
 | 
			
		||||
			<!-- sectionを利用しているのは、deck.vue側でcolumnに対してfirst-of-typeを効かせるため -->
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		|||
	<MkStickyContainer ref="contents" :class="$style.contents" style="container-type: inline-size;" @contextmenu.stop="onContextmenu">
 | 
			
		||||
		<template #header>
 | 
			
		||||
			<div>
 | 
			
		||||
				<XAnnouncements v-if="$i" :class="$style.announcements"/>
 | 
			
		||||
				<XAnnouncements v-if="$i"/>
 | 
			
		||||
				<XStatusBars :class="$style.statusbars"/>
 | 
			
		||||
			</div>
 | 
			
		||||
		</template>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue