mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 04:56:49 +00:00
feat(dashboard): add tiny list view
This commit is contained in:
parent
65044c1012
commit
5083a181de
6 changed files with 184 additions and 2 deletions
71
dashboard/src/components/group/TinyGroupView.svelte
Normal file
71
dashboard/src/components/group/TinyGroupView.svelte
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<script lang="ts">
|
||||
import { Card, CardImg, CardBody, Tooltip } from "sveltestrap"
|
||||
import type { Group } from "../../api/types"
|
||||
import resizeMedia from "../../api/resize-media";
|
||||
import default_avatar from '../../assets/default_avatar.png';
|
||||
import { useLocation } from "svelte-navigator";
|
||||
import FaLock from "svelte-icons/fa/FaLock.svelte";
|
||||
import FaUsers from "svelte-icons/fa/FaUserCircle.svelte"
|
||||
|
||||
export let group: Group
|
||||
|
||||
let location = useLocation()
|
||||
let pathName = $location.pathname;
|
||||
|
||||
function getGroupPageUrl() {
|
||||
let str: string;
|
||||
if (pathName.startsWith("/dash")) str = "/dash";
|
||||
else str = "/profile";
|
||||
|
||||
str += `/g/${group.id}`;
|
||||
|
||||
return str;
|
||||
}
|
||||
</script>
|
||||
|
||||
<a href={getGroupPageUrl()} class="card-link rounded flex-1 mb-3" >
|
||||
<Card style={`border: 3px solid #${group.color}`} class="h-100" >
|
||||
<CardImg style="border-bottom-right-radius: 0; border-bottom-left-radius: 0;" src={group.icon ? resizeMedia(group.icon, [256, 256], "webp") : default_avatar} />
|
||||
<CardBody class="text-center p-2 d-flex flex-col align-items-center justify-content-center">
|
||||
<h3>
|
||||
<button class="button-reset" style="width: auto; height: 1em; cursor: pointer; margin-right: 0.25em;" id={`m-copy-${group.uuid}`} >
|
||||
{#if group.privacy && group.privacy.visibility === "private"}
|
||||
<FaLock />
|
||||
{:else}
|
||||
<FaUsers />
|
||||
{/if}
|
||||
</button>
|
||||
{group.name} <span class="unbold">({group.id})</span>
|
||||
</h3>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
a.card-link, a.card-link:hover {
|
||||
color: unset;
|
||||
text-decoration: unset;
|
||||
display: inline-block;
|
||||
word-wrap: break-word;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a.card-link:hover {
|
||||
border: 4px solid var(--bs-primary);
|
||||
transform: scale(96%);
|
||||
}
|
||||
|
||||
.unbold {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.button-reset {
|
||||
background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
outline: inherit;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
import api from '../../api';
|
||||
import type { ListOptions, PageOptions } from './types';
|
||||
import { createShortList, filterList, getPageAmount, paginateList } from './functions';
|
||||
import TinyView from './TinyView.svelte';
|
||||
|
||||
$: memberList = getContext<Writable<Member[]>>("members")
|
||||
$: groupList = getContext<Writable<Group[]>>("groups")
|
||||
|
|
@ -36,6 +37,7 @@
|
|||
// set the default items per page based on settings and view
|
||||
// this probably should be moved to it's own function
|
||||
if (pageOptions.view === "card") pageOptions.itemsPerPage = 24;
|
||||
else if (pageOptions.view === "tiny") pageOptions.itemsPerPage = 36;
|
||||
else if (settings && settings.accessibility && settings.accessibility.expandedcards) pageOptions.itemsPerPage = 10;
|
||||
else pageOptions.itemsPerPage = 25;
|
||||
|
||||
|
|
@ -86,7 +88,7 @@
|
|||
{#if pageOptions.view === "card"}
|
||||
<CardView {pageOptions} currentList={currentGroups} />
|
||||
{:else if pageOptions.view === "tiny"}
|
||||
tiny!
|
||||
<TinyView {pageOptions} currentList={currentGroups} />
|
||||
{:else}
|
||||
<ListView currentList={currentGroups} {pageOptions} {options} fullListLength={groups.length} />
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ let itemsPerPageSelection = {
|
|||
$: { if (pageOptions.view === "card") itemsPerPageSelection = {
|
||||
small: 12,
|
||||
default: 24,
|
||||
large: 48
|
||||
}
|
||||
else if (pageOptions.view === "tiny") itemsPerPageSelection = {
|
||||
small: 18,
|
||||
default: 36,
|
||||
large: 60
|
||||
}
|
||||
else {
|
||||
|
|
@ -173,6 +178,7 @@ function resetPage() {
|
|||
<Input bind:value={pageOptions.view} type="select" aria-label="view mode" on:change={(e) => onViewChange(e)} >
|
||||
<option value="list">List</option>
|
||||
<option value="card">Cards</option>
|
||||
<option value="tiny">Tiny</option>
|
||||
</Input>
|
||||
</InputGroup>
|
||||
</Col>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
import api from '../../api';
|
||||
import type { ListOptions, List, PageOptions } from './types';
|
||||
import { createShortList, filterList, getPageAmount, paginateList } from './functions';
|
||||
import TinyView from './TinyView.svelte';
|
||||
|
||||
$: memberList = getContext<Writable<Member[]>>("members")
|
||||
$: groupList = getContext<Writable<Group[]>>("groups")
|
||||
|
|
@ -36,6 +37,7 @@
|
|||
// set the default items per page based on settings and view
|
||||
// this probably should be moved to it's own function
|
||||
if (pageOptions.view === "card") pageOptions.itemsPerPage = 24;
|
||||
else if (pageOptions.view === "tiny") pageOptions.itemsPerPage = 36;
|
||||
else if (settings && settings.accessibility && settings.accessibility.expandedcards) pageOptions.itemsPerPage = 10;
|
||||
else pageOptions.itemsPerPage = 25;
|
||||
|
||||
|
|
@ -86,7 +88,7 @@
|
|||
{#if pageOptions.view === "card"}
|
||||
<CardView {pageOptions} currentList={currentMembers} />
|
||||
{:else if pageOptions.view === "tiny"}
|
||||
tiny!
|
||||
<TinyView {pageOptions} currentList={currentMembers} />
|
||||
{:else}
|
||||
<ListView currentList={currentMembers} {pageOptions} {options} fullListLength={members.length} />
|
||||
{/if}
|
||||
|
|
|
|||
30
dashboard/src/components/list/TinyView.svelte
Normal file
30
dashboard/src/components/list/TinyView.svelte
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<script lang="ts">
|
||||
import { Card, CardImg, Row, Col } from "sveltestrap";
|
||||
import type { Group, Member } from "../../api/types";
|
||||
import type { PageOptions } from "./types";
|
||||
import default_avatar from '../../assets/default_avatar.png';
|
||||
import resizeMedia from "../../api/resize-media";
|
||||
import TinyMemberView from "../member/TinyMemberView.svelte";
|
||||
import TinyGroupView from "../group/TinyGroupView.svelte";
|
||||
|
||||
export let pageOptions: PageOptions;
|
||||
export let currentList: Member[]|Group[];
|
||||
$: memberList = currentList as Member[]
|
||||
$: groupList = currentList as Group[]
|
||||
</script>
|
||||
|
||||
<Row class="mx-4 mx-sm-5 mx-md-0">
|
||||
{#if pageOptions.type === "member"}
|
||||
{#each memberList as item (item.uuid)}
|
||||
<Col xs={6} md={4} lg={3} xl={2} class="d-flex flex-col">
|
||||
<TinyMemberView member={item} />
|
||||
</Col>
|
||||
{/each}
|
||||
{:else if pageOptions.type === "group"}
|
||||
{#each groupList as item (item.uuid)}
|
||||
<Col xs={6} md={4} lg={3} xl={2} class="d-flex flex-col">
|
||||
<TinyGroupView group={item} />
|
||||
</Col>
|
||||
{/each}
|
||||
{/if}
|
||||
</Row>
|
||||
71
dashboard/src/components/member/TinyMemberView.svelte
Normal file
71
dashboard/src/components/member/TinyMemberView.svelte
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<script lang="ts">
|
||||
import { Card, CardImg, CardBody, Tooltip } from "sveltestrap"
|
||||
import type { Member } from "../../api/types"
|
||||
import resizeMedia from "../../api/resize-media";
|
||||
import default_avatar from '../../assets/default_avatar.png';
|
||||
import { useLocation } from "svelte-navigator";
|
||||
import FaLock from "svelte-icons/fa/FaLock.svelte";
|
||||
import FaUserCircle from "svelte-icons/fa/FaUserCircle.svelte"
|
||||
|
||||
export let member: Member
|
||||
|
||||
let location = useLocation()
|
||||
let pathName = $location.pathname;
|
||||
|
||||
function getMemberPageUrl() {
|
||||
let str: string;
|
||||
if (pathName.startsWith("/dash")) str = "/dash";
|
||||
else str = "/profile";
|
||||
|
||||
str += `/m/${member.id}`;
|
||||
|
||||
return str;
|
||||
}
|
||||
</script>
|
||||
|
||||
<a href={getMemberPageUrl()} class="card-link rounded flex-1 mb-3" >
|
||||
<Card style={`border: 3px solid #${member.color}`} class="h-100" >
|
||||
<CardImg style="border-bottom-right-radius: 0; border-bottom-left-radius: 0;" src={member.avatar_url ? resizeMedia(member.avatar_url, [256, 256], "webp") : default_avatar} />
|
||||
<CardBody class="text-center p-2 d-flex flex-col align-items-center justify-content-center">
|
||||
<h3>
|
||||
<button class="button-reset" style="width: auto; height: 1em; cursor: pointer; margin-right: 0.25em;" id={`m-copy-${member.uuid}`} >
|
||||
{#if member.privacy && member.privacy.visibility === "private"}
|
||||
<FaLock />
|
||||
{:else}
|
||||
<FaUserCircle />
|
||||
{/if}
|
||||
</button>
|
||||
{member.name} <span class="unbold">({member.id})</span>
|
||||
</h3>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
a.card-link, a.card-link:hover {
|
||||
color: unset;
|
||||
text-decoration: unset;
|
||||
display: inline-block;
|
||||
word-wrap: break-word;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a.card-link:hover {
|
||||
border: 4px solid var(--bs-primary);
|
||||
transform: scale(96%);
|
||||
}
|
||||
|
||||
.unbold {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.button-reset {
|
||||
background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
outline: inherit;
|
||||
}
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue