릴리스: v1.2.71 공개 티어표 복사와 보기 상태 보정
This commit is contained in:
@@ -79,6 +79,9 @@ function mapTierListRow(row) {
|
||||
description: row.description || '',
|
||||
isPublic: !!row.is_public,
|
||||
showCharacterNames: !!row.show_character_names,
|
||||
sourceTierListId: row.source_tierlist_id || '',
|
||||
sourceSnapshotTitle: row.source_snapshot_title || '',
|
||||
sourceSnapshotAuthor: row.source_snapshot_author || '',
|
||||
groups: parseJson(row.groups_json, []),
|
||||
pool: parseJson(row.pool_json, []),
|
||||
createdAt: Number(row.created_at),
|
||||
@@ -228,6 +231,9 @@ async function ensureSchema() {
|
||||
description TEXT NOT NULL,
|
||||
is_public TINYINT(1) NOT NULL DEFAULT 0,
|
||||
show_character_names TINYINT(1) NOT NULL DEFAULT 0,
|
||||
source_tierlist_id VARCHAR(64) NULL DEFAULT NULL,
|
||||
source_snapshot_title VARCHAR(120) NOT NULL DEFAULT '',
|
||||
source_snapshot_author VARCHAR(120) NOT NULL DEFAULT '',
|
||||
groups_json LONGTEXT NOT NULL,
|
||||
pool_json LONGTEXT NOT NULL,
|
||||
created_at BIGINT NOT NULL,
|
||||
@@ -295,6 +301,18 @@ async function ensureSchema() {
|
||||
if (!tierListShowNamesColumns.length) {
|
||||
await query("ALTER TABLE tierlists ADD COLUMN show_character_names TINYINT(1) NOT NULL DEFAULT 0 AFTER is_public")
|
||||
}
|
||||
const tierListSourceIdColumns = await query("SHOW COLUMNS FROM tierlists LIKE 'source_tierlist_id'")
|
||||
if (!tierListSourceIdColumns.length) {
|
||||
await query("ALTER TABLE tierlists ADD COLUMN source_tierlist_id VARCHAR(64) NULL DEFAULT NULL AFTER show_character_names")
|
||||
}
|
||||
const tierListSourceTitleColumns = await query("SHOW COLUMNS FROM tierlists LIKE 'source_snapshot_title'")
|
||||
if (!tierListSourceTitleColumns.length) {
|
||||
await query("ALTER TABLE tierlists ADD COLUMN source_snapshot_title VARCHAR(120) NOT NULL DEFAULT '' AFTER source_tierlist_id")
|
||||
}
|
||||
const tierListSourceAuthorColumns = await query("SHOW COLUMNS FROM tierlists LIKE 'source_snapshot_author'")
|
||||
if (!tierListSourceAuthorColumns.length) {
|
||||
await query("ALTER TABLE tierlists ADD COLUMN source_snapshot_author VARCHAR(120) NOT NULL DEFAULT '' AFTER source_snapshot_title")
|
||||
}
|
||||
|
||||
await query(
|
||||
`
|
||||
@@ -894,6 +912,9 @@ async function listFavoriteTierLists(userId, { queryText = '', sort = 'favorited
|
||||
t.description,
|
||||
t.is_public,
|
||||
t.show_character_names,
|
||||
t.source_tierlist_id,
|
||||
t.source_snapshot_title,
|
||||
t.source_snapshot_author,
|
||||
t.groups_json,
|
||||
t.pool_json,
|
||||
t.created_at,
|
||||
@@ -1024,6 +1045,9 @@ async function listAdminTierLists({ queryText = '', page = 1, limit = 50, curren
|
||||
t.description,
|
||||
t.is_public,
|
||||
t.show_character_names,
|
||||
t.source_tierlist_id,
|
||||
t.source_snapshot_title,
|
||||
t.source_snapshot_author,
|
||||
t.groups_json,
|
||||
t.pool_json,
|
||||
t.created_at,
|
||||
@@ -1080,6 +1104,9 @@ async function findTierListById(id, currentUserId = '') {
|
||||
t.description,
|
||||
t.is_public,
|
||||
t.show_character_names,
|
||||
t.source_tierlist_id,
|
||||
t.source_snapshot_title,
|
||||
t.source_snapshot_author,
|
||||
t.groups_json,
|
||||
t.pool_json,
|
||||
t.created_at,
|
||||
@@ -1277,7 +1304,21 @@ async function deleteCustomItems(ids) {
|
||||
await query(`DELETE FROM custom_items WHERE id IN (${placeholders})`, ids)
|
||||
}
|
||||
|
||||
async function saveTierList({ id, authorId, gameId, title, thumbnailSrc = '', description, isPublic, showCharacterNames = false, groups, pool }) {
|
||||
async function saveTierList({
|
||||
id,
|
||||
authorId,
|
||||
gameId,
|
||||
title,
|
||||
thumbnailSrc = '',
|
||||
description,
|
||||
isPublic,
|
||||
showCharacterNames = false,
|
||||
sourceTierListId = '',
|
||||
sourceSnapshotTitle = '',
|
||||
sourceSnapshotAuthor = '',
|
||||
groups,
|
||||
pool,
|
||||
}) {
|
||||
const existing = id ? await findTierListById(id, authorId) : null
|
||||
await syncOwnedCustomItemLabels({ ownerId: authorId, items: pool })
|
||||
const nextThumbnailSrc = (thumbnailSrc || '').trim() || getAutoThumbnailSrc(groups, pool)
|
||||
@@ -1286,10 +1327,10 @@ async function saveTierList({ id, authorId, gameId, title, thumbnailSrc = '', de
|
||||
await query(
|
||||
`
|
||||
UPDATE tierlists
|
||||
SET title = ?, thumbnail_src = ?, description = ?, is_public = ?, show_character_names = ?, groups_json = ?, pool_json = ?, updated_at = ?
|
||||
SET title = ?, thumbnail_src = ?, description = ?, is_public = ?, show_character_names = ?, source_tierlist_id = ?, source_snapshot_title = ?, source_snapshot_author = ?, groups_json = ?, pool_json = ?, updated_at = ?
|
||||
WHERE id = ?
|
||||
`,
|
||||
[title, nextThumbnailSrc, description || '', isPublic ? 1 : 0, showCharacterNames ? 1 : 0, serializeJson(groups), serializeJson(pool), now(), existing.id]
|
||||
[title, nextThumbnailSrc, description || '', isPublic ? 1 : 0, showCharacterNames ? 1 : 0, sourceTierListId || null, sourceSnapshotTitle || '', sourceSnapshotAuthor || '', serializeJson(groups), serializeJson(pool), now(), existing.id]
|
||||
)
|
||||
return findTierListById(existing.id, authorId)
|
||||
}
|
||||
@@ -1298,15 +1339,37 @@ async function saveTierList({ id, authorId, gameId, title, thumbnailSrc = '', de
|
||||
await query(
|
||||
`
|
||||
INSERT INTO tierlists (
|
||||
id, author_id, game_id, title, thumbnail_src, description, is_public, show_character_names, groups_json, pool_json, created_at, updated_at
|
||||
id, author_id, game_id, title, thumbnail_src, description, is_public, show_character_names, source_tierlist_id, source_snapshot_title, source_snapshot_author, groups_json, pool_json, created_at, updated_at
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`,
|
||||
[id, authorId, gameId, title, nextThumbnailSrc, description || '', isPublic ? 1 : 0, showCharacterNames ? 1 : 0, serializeJson(groups), serializeJson(pool), createdAt, createdAt]
|
||||
[id, authorId, gameId, title, nextThumbnailSrc, description || '', isPublic ? 1 : 0, showCharacterNames ? 1 : 0, sourceTierListId || null, sourceSnapshotTitle || '', sourceSnapshotAuthor || '', serializeJson(groups), serializeJson(pool), createdAt, createdAt]
|
||||
)
|
||||
return findTierListById(id, authorId)
|
||||
}
|
||||
|
||||
async function duplicateTierListForUser({ tierList, targetUserId }) {
|
||||
const { nanoid } = require('nanoid')
|
||||
const duplicateId = nanoid()
|
||||
const baseTitle = (tierList.title || '티어표').trim() || '티어표'
|
||||
const copyTitle = baseTitle.endsWith(' 복사본') ? baseTitle : `${baseTitle} 복사본`
|
||||
return saveTierList({
|
||||
id: duplicateId,
|
||||
authorId: targetUserId,
|
||||
gameId: tierList.gameId,
|
||||
title: copyTitle,
|
||||
thumbnailSrc: tierList.thumbnailSrc || '',
|
||||
description: tierList.description || '',
|
||||
isPublic: false,
|
||||
showCharacterNames: !!tierList.showCharacterNames,
|
||||
sourceTierListId: tierList.id,
|
||||
sourceSnapshotTitle: tierList.title || '',
|
||||
sourceSnapshotAuthor: tierList.authorName || tierList.authorAccountName || '',
|
||||
groups: JSON.parse(JSON.stringify(tierList.groups || [])),
|
||||
pool: JSON.parse(JSON.stringify(tierList.pool || [])),
|
||||
})
|
||||
}
|
||||
|
||||
async function favoriteTierList({ userId, tierListId }) {
|
||||
await query('INSERT IGNORE INTO favorite_tierlists (user_id, tierlist_id, created_at) VALUES (?, ?, ?)', [userId, tierListId, now()])
|
||||
}
|
||||
@@ -1363,6 +1426,7 @@ module.exports = {
|
||||
findCustomItemsByIds,
|
||||
deleteCustomItems,
|
||||
saveTierList,
|
||||
duplicateTierListForUser,
|
||||
createTemplateRequest,
|
||||
findTemplateRequestById,
|
||||
listAdminTemplateRequests,
|
||||
|
||||
@@ -15,6 +15,7 @@ const {
|
||||
findUserById,
|
||||
favoriteTierList,
|
||||
unfavoriteTierList,
|
||||
duplicateTierListForUser,
|
||||
} = require('../db')
|
||||
const { requireAuth } = require('../middleware/auth')
|
||||
|
||||
@@ -84,6 +85,9 @@ const tierListUpsertSchema = z.object({
|
||||
description: z.string().max(1000).optional().default(''),
|
||||
isPublic: z.boolean().default(false),
|
||||
showCharacterNames: z.boolean().optional().default(false),
|
||||
sourceTierListId: z.string().max(64).optional().default(''),
|
||||
sourceSnapshotTitle: z.string().max(120).optional().default(''),
|
||||
sourceSnapshotAuthor: z.string().max(120).optional().default(''),
|
||||
groups: z.array(
|
||||
z.object({
|
||||
id: z.string().min(1),
|
||||
@@ -131,6 +135,15 @@ router.get('/:id', async (req, res) => {
|
||||
res.json({ tierList: normalizeTierList(t) })
|
||||
})
|
||||
|
||||
router.post('/:id/duplicate', requireAuth, async (req, res) => {
|
||||
const tierList = await findTierListById(req.params.id, req.session.userId)
|
||||
if (!tierList) return res.status(404).json({ error: 'not_found' })
|
||||
if (!tierList.isPublic && tierList.authorId !== req.session.userId) return res.status(403).json({ error: 'forbidden' })
|
||||
|
||||
const duplicated = await duplicateTierListForUser({ tierList, targetUserId: req.session.userId })
|
||||
res.json({ tierList: normalizeTierList(duplicated) })
|
||||
})
|
||||
|
||||
router.delete('/:id', requireAuth, async (req, res) => {
|
||||
const tierList = await findTierListById(req.params.id, req.session.userId)
|
||||
if (!tierList) return res.status(404).json({ error: 'not_found' })
|
||||
@@ -245,6 +258,9 @@ router.post('/', requireAuth, async (req, res) => {
|
||||
description: payload.description || '',
|
||||
isPublic: !!payload.isPublic,
|
||||
showCharacterNames: !!payload.showCharacterNames,
|
||||
sourceTierListId: payload.sourceTierListId || existing.sourceTierListId || '',
|
||||
sourceSnapshotTitle: payload.sourceSnapshotTitle || existing.sourceSnapshotTitle || '',
|
||||
sourceSnapshotAuthor: payload.sourceSnapshotAuthor || existing.sourceSnapshotAuthor || '',
|
||||
groups: payload.groups,
|
||||
pool: normalizedPool,
|
||||
})
|
||||
@@ -260,6 +276,9 @@ router.post('/', requireAuth, async (req, res) => {
|
||||
description: payload.description || '',
|
||||
isPublic: !!payload.isPublic,
|
||||
showCharacterNames: !!payload.showCharacterNames,
|
||||
sourceTierListId: payload.sourceTierListId || '',
|
||||
sourceSnapshotTitle: payload.sourceSnapshotTitle || '',
|
||||
sourceSnapshotAuthor: payload.sourceSnapshotAuthor || '',
|
||||
groups: payload.groups,
|
||||
pool: normalizedPool,
|
||||
})
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# 업데이트 로그
|
||||
|
||||
## 2026-03-31 v1.2.71
|
||||
- 게임 허브 공개 티어표 카드는 자동 폭 그리드와 2줄 제목/유연한 메타 배치로 보정해, 브라우저 폭이 줄어들어도 썸네일과 텍스트가 카드 밖으로 넘치지 않도록 정리함.
|
||||
- 공개 티어표 상세에서는 다른 사용자의 티어표를 복사해 내 작업본으로 가져오는 기능을 추가하고, 복사본에는 원본 제목/작성자 정보를 작은 출처 메모로 남기도록 확장함.
|
||||
- 보기 전용 티어표의 미배치 아이템은 더 어둡고 흐리게 표시하고 `미배치` 상태를 붙여, 내 보드처럼 조작 가능한 인상을 줄이도록 보정함.
|
||||
|
||||
## 2026-03-31 v1.2.70
|
||||
- 관리자 게임 관리의 썸네일 드롭존을 카드 안 카드 구조 대신, 썸네일 전체 위에 하단 오버레이 문구를 얹는 단일 미디어 영역으로 정리함.
|
||||
- 게임 관리 본문 상단 안내 패널과 과한 설명 문구를 제거하고, 비선택 상태는 `게임을 선택해 주세요.` 한 줄 중심의 empty 상태로 단순화함.
|
||||
|
||||
@@ -90,6 +90,7 @@ export const api = {
|
||||
favoriteTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}/favorite`, { method: 'POST' }),
|
||||
unfavoriteTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}/favorite`, { method: 'DELETE' }),
|
||||
deleteTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}`, { method: 'DELETE' }),
|
||||
duplicateTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}/duplicate`, { method: 'POST' }),
|
||||
requestTierListTemplate: (id, payload) => request(`/api/tierlists/${encodeURIComponent(id)}/template-request`, { method: 'POST', body: payload }),
|
||||
saveTierList: (payload) => request('/api/tierlists', { method: 'POST', body: payload }),
|
||||
uploadTierListThumbnail: async (file) => {
|
||||
|
||||
@@ -213,8 +213,9 @@ function submitSearch() {
|
||||
}
|
||||
.list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 320px));
|
||||
gap: 18px;
|
||||
justify-content: start;
|
||||
}
|
||||
.boardCard {
|
||||
border-radius: 22px;
|
||||
@@ -271,25 +272,34 @@ function submitSearch() {
|
||||
min-width: 0;
|
||||
font-size: 18px;
|
||||
line-height: 1.35;
|
||||
white-space: nowrap;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.boardCard__head {
|
||||
min-width: 0;
|
||||
padding: 16px 18px 18px;
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
gap: 8px;
|
||||
}
|
||||
.boardCard__titleRow,
|
||||
.boardCard__metaRow {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.boardCard__titleRow {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.boardCard__metaRow {
|
||||
align-items: flex-end;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.boardCard__author {
|
||||
min-width: 0;
|
||||
@@ -323,6 +333,7 @@ function submitSearch() {
|
||||
.boardCard__date,
|
||||
.favoriteStat {
|
||||
flex: 0 0 auto;
|
||||
min-width: 0;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.64);
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -49,6 +49,9 @@ const ownerId = ref('')
|
||||
const authorName = ref('')
|
||||
const authorAccountName = ref('')
|
||||
const updatedAt = ref(0)
|
||||
const sourceTierListId = ref('')
|
||||
const sourceSnapshotTitle = ref('')
|
||||
const sourceSnapshotAuthor = ref('')
|
||||
const isDragActive = ref(false)
|
||||
const isThumbnailDragActive = ref(false)
|
||||
const iconSize = ref(80)
|
||||
@@ -95,6 +98,14 @@ const untitledWarning = computed(
|
||||
'제목 없이 저장된 티어표는 무분별한 도배 방지를 위해 관리자에 의해 임의 삭제될 수 있어요.'
|
||||
)
|
||||
const canFavorite = computed(() => !!auth.user && !isNewTierList.value && !canEdit.value)
|
||||
const canDuplicate = computed(() => !!auth.user && !isNewTierList.value && !canEdit.value)
|
||||
const copiedFromLabel = computed(() => {
|
||||
if (!sourceTierListId.value) return ''
|
||||
const parts = []
|
||||
if (sourceSnapshotTitle.value) parts.push(`원본 ${sourceSnapshotTitle.value}`)
|
||||
if (sourceSnapshotAuthor.value) parts.push(sourceSnapshotAuthor.value)
|
||||
return parts.join(' · ') || '복사해 온 티어표'
|
||||
})
|
||||
const customItems = computed(() =>
|
||||
Object.values(itemsById.value)
|
||||
.filter((item) => item?.origin === 'custom')
|
||||
@@ -473,6 +484,9 @@ function buildPayload(existingId) {
|
||||
description: (description.value || '').trim(),
|
||||
isPublic: !!isPublic.value,
|
||||
showCharacterNames: !!showCharacterNames.value,
|
||||
sourceTierListId: sourceTierListId.value || '',
|
||||
sourceSnapshotTitle: sourceSnapshotTitle.value || '',
|
||||
sourceSnapshotAuthor: sourceSnapshotAuthor.value || '',
|
||||
groups: groups.value.map((g) => ({ id: g.id, name: g.name, itemIds: g.itemIds })),
|
||||
pool: Object.values(itemsById.value),
|
||||
}
|
||||
@@ -561,6 +575,19 @@ async function confirmDeleteTierList() {
|
||||
}
|
||||
}
|
||||
|
||||
async function duplicateCurrentTierList() {
|
||||
if (!canDuplicate.value) return
|
||||
try {
|
||||
const data = await api.duplicateTierList(tierListId.value)
|
||||
const duplicatedId = data.tierList?.id
|
||||
if (!duplicatedId) throw new Error('duplicate_failed')
|
||||
toast.success('티어표를 복사해 내 작업으로 가져왔어요.')
|
||||
router.push(`/editor/${gameId.value}/${duplicatedId}`)
|
||||
} catch (e) {
|
||||
error.value = '티어표 복사에 실패했어요.'
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleFavorite() {
|
||||
if (!canFavorite.value || isFavoriteBusy.value) return
|
||||
try {
|
||||
@@ -653,6 +680,9 @@ onMounted(() => {
|
||||
authorName.value = t.authorName || ''
|
||||
authorAccountName.value = t.authorAccountName || ''
|
||||
updatedAt.value = Number(t.updatedAt || 0)
|
||||
sourceTierListId.value = t.sourceTierListId || ''
|
||||
sourceSnapshotTitle.value = t.sourceSnapshotTitle || ''
|
||||
sourceSnapshotAuthor.value = t.sourceSnapshotAuthor || ''
|
||||
favoriteCount.value = Number(t.favoriteCount || 0)
|
||||
isFavorited.value = !!t.isFavorited
|
||||
groups.value = t.groups
|
||||
@@ -699,7 +729,7 @@ onUnmounted(() => {
|
||||
<div v-if="pool.length" class="previewOnly__pool">
|
||||
<div class="previewOnly__poolTitle">남은 아이템</div>
|
||||
<div class="previewOnly__poolGrid">
|
||||
<div v-for="id in pool" :key="id" class="previewOnly__poolItem">
|
||||
<div v-for="id in pool" :key="id" class="previewOnly__poolItem previewOnly__poolItem--inactive">
|
||||
<img :src="resolveItemSrc(itemsById[id])" class="thumb" :alt="itemsById[id]?.label || id" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -816,6 +846,10 @@ onUnmounted(() => {
|
||||
공개된 티어표를 보는 중입니다. 로그인한 작성자만 수정할 수 있어요.
|
||||
</template>
|
||||
</div>
|
||||
<div v-if="sourceTierListId" class="editorMain__sourceNote">
|
||||
<span>복사본</span>
|
||||
<button class="editorMain__sourceLink" type="button" @click="router.push(`/editor/${gameId}/${sourceTierListId}`)">{{ copiedFromLabel }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -911,9 +945,10 @@ onUnmounted(() => {
|
||||
{{ canEdit ? '등록된 아이템 리스트입니다. 드래그해서 표에 넣을 수 있습니다.' : '공개 티어표는 보기 전용입니다.' }}
|
||||
</div>
|
||||
<div ref="poolEl" class="pool" data-list-type="pool">
|
||||
<div v-for="id in pool" :key="id" class="poolItem" :data-item-id="id">
|
||||
<div v-for="id in pool" :key="id" class="poolItem" :class="{ 'poolItem--readonly': !canEdit }" :data-item-id="id">
|
||||
<img :src="resolveItemSrc(itemsById[id])" class="thumb" :alt="itemsById[id]?.label || id" />
|
||||
<div class="poolItem__label">{{ itemsById[id]?.label || id }}</div>
|
||||
<div v-if="!canEdit" class="poolItem__state">미배치</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1005,6 +1040,7 @@ onUnmounted(() => {
|
||||
</div>
|
||||
<div class="editorSidebar__utilityLinks">
|
||||
<button v-if="canEdit && !isNewTierList" class="editorSidebar__utilityLink editorSidebar__utilityLink--danger" @click="openDeleteModal">삭제하기</button>
|
||||
<button v-if="canDuplicate" class="editorSidebar__utilityLink" @click="duplicateCurrentTierList">복사해서 내 티어표로 가져오기</button>
|
||||
<button
|
||||
v-if="canRequestTemplateCreate"
|
||||
class="editorSidebar__utilityLink"
|
||||
@@ -1055,6 +1091,23 @@ onUnmounted(() => {
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.editorMain__sourceNote {
|
||||
margin-top: 4px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.62);
|
||||
}
|
||||
.editorMain__sourceLink {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: rgba(191, 219, 254, 0.94);
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
.previewOnly {
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
@@ -1133,6 +1186,10 @@ onUnmounted(() => {
|
||||
display: inline-flex;
|
||||
position: relative;
|
||||
}
|
||||
.previewOnly__poolItem--inactive {
|
||||
opacity: 0.52;
|
||||
filter: grayscale(0.22) brightness(0.78);
|
||||
}
|
||||
.toggleSwitch {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -1845,6 +1902,10 @@ onUnmounted(() => {
|
||||
border: 1px solid rgba(255, 255, 255, 0.10);
|
||||
background: rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
.poolItem--readonly {
|
||||
opacity: 0.58;
|
||||
filter: grayscale(0.25) brightness(0.78);
|
||||
}
|
||||
.poolItem .thumb {
|
||||
width: 100%;
|
||||
max-width: var(--thumb-size, 80px);
|
||||
@@ -1863,6 +1924,13 @@ onUnmounted(() => {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.poolItem__state {
|
||||
font-size: 10px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
color: rgba(255, 255, 255, 0.58);
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user