add community profile section to sidebar and improve icons
This commit is contained in:
parent
d5e5cadc10
commit
7692dd0808
13 changed files with 215 additions and 97 deletions
|
@ -7,7 +7,6 @@
|
||||||
"dev": "rollup -c -w"
|
"dev": "rollup -c -w"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@fontsource/material-icons-outlined": "^4.5.4",
|
|
||||||
"@rollup/plugin-commonjs": "^23.0.4",
|
"@rollup/plugin-commonjs": "^23.0.4",
|
||||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||||
"@rollup/plugin-terser": "^0.1.0",
|
"@rollup/plugin-terser": "^0.1.0",
|
||||||
|
@ -18,6 +17,7 @@
|
||||||
"svelte": "^4.0.0"
|
"svelte": "^4.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fontsource-variable/material-symbols-outlined": "^5.0.7",
|
||||||
"@fontsource-variable/open-sans": "^5.0.6"
|
"@fontsource-variable/open-sans": "^5.0.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ export default {
|
||||||
// Copy fonts
|
// Copy fonts
|
||||||
copy({
|
copy({
|
||||||
targets: [
|
targets: [
|
||||||
{ src: "node_modules/@fontsource/material-icons-outlined/files/material-icons-outlined-all-400-normal.woff2", dest: "public/build/files" },
|
{ src: "node_modules/@fontsource-variable/material-symbols-outlined/files/material-symbols-outlined-latin-opsz-normal.woff2", dest: "public/build/files" },
|
||||||
{ src: "node_modules/@fontsource-variable/open-sans/files/open-sans-latin-wght-*", dest: "public/build/files" },
|
{ src: "node_modules/@fontsource-variable/open-sans/files/open-sans-latin-wght-*", dest: "public/build/files" },
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -2,10 +2,24 @@
|
||||||
export let options = [];
|
export let options = [];
|
||||||
export let selectedOptionId = null;
|
export let selectedOptionId = null;
|
||||||
export let onSelect = (_) => {};
|
export let onSelect = (_) => {};
|
||||||
|
export let smaller = false;
|
||||||
|
export let doHighlight = false;
|
||||||
|
|
||||||
if (selectedOptionId) {
|
if (selectedOptionId) {
|
||||||
onSelect(selectedOptionId);
|
onSelect(selectedOptionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const optionClick = (option) => {
|
||||||
|
if (option) {
|
||||||
|
if (doHighlight) {
|
||||||
|
selectedOptionId = option.id;
|
||||||
|
}
|
||||||
|
onSelect(selectedOptionId);
|
||||||
|
if (option.handle) {
|
||||||
|
option.handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -23,9 +37,11 @@
|
||||||
color: var(--foreground-color-2);
|
color: var(--foreground-color-2);
|
||||||
background-color: var(--background-color-2);
|
background-color: var(--background-color-2);
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
|
padding-left: 0.65em;
|
||||||
|
padding-right: 0.65em;
|
||||||
margin-top: var(--space-xs);
|
margin-top: var(--space-xs);
|
||||||
margin-right: var(--space-sm);
|
margin-right: var(--space-sm);
|
||||||
border-radius: 0.65em;
|
border-radius: 9999px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,19 +58,31 @@
|
||||||
color: var(--background-color-2);
|
color: var(--background-color-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.material-icons-outlined {
|
.button:not(.has-text) {
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.has-text .material-icons-outlined {
|
||||||
margin-right: var(--space-xxs);
|
margin-right: var(--space-xxs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.smaller button {
|
||||||
|
font-size: 0.85em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<div>
|
<div class:smaller={smaller}>
|
||||||
{#each options as option (option.id)}
|
{#each options as option (option.id)}
|
||||||
<button class="button" class:selected={ selectedOptionId === option.id } on:click={ () => { selectedOptionId = option.id; onSelect(selectedOptionId); } }>
|
{#if !option.hidden}
|
||||||
|
<button class="button" class:selected={ selectedOptionId === option.id } class:has-text={!!option.text} on:click={ optionClick(option) }>
|
||||||
{#if option.icon}
|
{#if option.icon}
|
||||||
<span class="material-icons-outlined">{ option.icon }</span>
|
<span class="material-icons-outlined">{ option.icon }</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if option.text}
|
||||||
{ option.text }
|
{ option.text }
|
||||||
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
|
@ -96,7 +96,7 @@
|
||||||
{:else if renderAs === AttachmentRenderAs.DownloadableFile}
|
{:else if renderAs === AttachmentRenderAs.DownloadableFile}
|
||||||
<div class="attachment attachment-card">
|
<div class="attachment attachment-card">
|
||||||
<div class="attachment-filename">{ attachment.file_name }</div>
|
<div class="attachment-filename">{ attachment.file_name }</div>
|
||||||
<a class="icon-button material-icons-outlined download" href="{ attachmentUrl(attachment.file) }" target="_blank">download</a>
|
<a class="icon-button material-icons-outlined small download" href="{ attachmentUrl(attachment.file) }" target="_blank">download</a>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="attachment attachment-card">Couldn't render attachment</div>
|
<div class="attachment attachment-card">Couldn't render attachment</div>
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import { maybeFly, maybeFlyIf } from "../animations";
|
import { maybeFly, maybeFlyIf } from "../animations";
|
||||||
import { avatarUrl } from "../storage";
|
import { avatarUrl } from "../storage";
|
||||||
import { gatewayStatus, overlayStore, selectedChannel, showSidebar, smallViewport, userInfoStore, unreadStore, OverlayType, communities, selectedCommunity, filteredChannelsStore } from "../stores";
|
import { gatewayStatus, overlayStore, selectedChannel, showSidebar, smallViewport, userInfoStore, unreadStore, OverlayType, communities, selectedCommunity, filteredChannelsStore } from "../stores";
|
||||||
|
import SidebarCommunity from "./SidebarCommunity.svelte";
|
||||||
|
|
||||||
const selectChannel = (channel) => {
|
const selectChannel = (channel) => {
|
||||||
if ($smallViewport) {
|
if ($smallViewport) {
|
||||||
|
@ -45,11 +46,7 @@
|
||||||
margin: var(--space-sm);
|
margin: var(--space-sm);
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
transition-duration: 200ms;
|
transition-duration: 200ms;
|
||||||
transition-property: border-radius background;
|
transition-property: border-radius background color;
|
||||||
}
|
|
||||||
|
|
||||||
.theme--light .communities .button:hover, .theme--light .communities .button.selected {
|
|
||||||
color: var(--background-color-3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.communities .button:hover, .communities .button.selected {
|
.communities .button:hover, .communities .button.selected {
|
||||||
|
@ -58,6 +55,18 @@
|
||||||
color: var(--foreground-color-1);
|
color: var(--foreground-color-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme--light .communities .button.selected .material-icons-outlined,
|
||||||
|
.theme--light .communities .button:hover .material-icons-outlined,
|
||||||
|
.theme--light .communities .button:hover, .theme--light .communities .button.selected {
|
||||||
|
color: var(--background-color-3);
|
||||||
|
}
|
||||||
|
.theme--dark .communities .button .material-icons-outlined {
|
||||||
|
color: var(--foreground-color-2);
|
||||||
|
}
|
||||||
|
.theme--dark .communities .button.selected .material-icons-outlined {
|
||||||
|
color: var(--foreground-color-1);
|
||||||
|
}
|
||||||
|
|
||||||
.communities .button span {
|
.communities .button span {
|
||||||
margin: 0.45em;
|
margin: 0.45em;
|
||||||
}
|
}
|
||||||
|
@ -71,11 +80,7 @@
|
||||||
<div class="sidebar-container" in:maybeFly="{{ duration: 175, easing: quadInOut, x: -10 }}" out:maybeFlyIf="{{ _condition: !smallViewport.value, duration: 175, easing: quadInOut, x: -10 }}">
|
<div class="sidebar-container" in:maybeFly="{{ duration: 175, easing: quadInOut, x: -10 }}" out:maybeFlyIf="{{ _condition: !smallViewport.value, duration: 175, easing: quadInOut, x: -10 }}">
|
||||||
<div class="communities">
|
<div class="communities">
|
||||||
<button class="button" on:click={() => selectedCommunity.clear()} class:selected={ $selectedCommunity.id === -1 }>
|
<button class="button" on:click={() => selectedCommunity.clear()} class:selected={ $selectedCommunity.id === -1 }>
|
||||||
{#if $userInfoStore && $userInfoStore.avatar}
|
<span class="material-icons-outlined">home</span>
|
||||||
<img src={avatarUrl($userInfoStore.avatar, 64)} alt=" ">
|
|
||||||
{:else}
|
|
||||||
<span>{ $userInfoStore ? $userInfoStore.username[0] || "" : "" }</span>
|
|
||||||
{/if}
|
|
||||||
</button>
|
</button>
|
||||||
{#each $communities as community (community.id)}
|
{#each $communities as community (community.id)}
|
||||||
<button class="button" on:click={() => $selectedCommunity = community} class:selected={ $selectedCommunity.id === community.id }>
|
<button class="button" on:click={() => $selectedCommunity = community} class:selected={ $selectedCommunity.id === community.id }>
|
||||||
|
@ -94,13 +99,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar round-left">
|
<div class="sidebar round-left">
|
||||||
<div class="top-bar text-small text-bold">
|
<SidebarCommunity communityLike={ $selectedCommunity.id === -1 ? $userInfoStore : $selectedCommunity } isUser={ $selectedCommunity.id === -1 } />
|
||||||
{#if $selectedCommunity.id !== -1}
|
|
||||||
{$selectedCommunity.name || ""}
|
|
||||||
{:else}
|
|
||||||
{$userInfoStore ? $userInfoStore.username || "" : ""}
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="sidebar-buttons">
|
<div class="sidebar-buttons">
|
||||||
{#each $filteredChannelsStore as channel (channel.id)}
|
{#each $filteredChannelsStore as channel (channel.id)}
|
||||||
<button on:click="{ selectChannel(channel) }" class="sidebar-button" class:selected={ channel.id === $selectedChannel.id }>
|
<button on:click="{ selectChannel(channel) }" class="sidebar-button" class:selected={ channel.id === $selectedChannel.id }>
|
||||||
|
@ -118,12 +117,6 @@
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
{#if $userInfoStore && $userInfoStore.permissions.create_channel}
|
|
||||||
<button on:click="{ () => overlayStore.push(OverlayType.CreateChannel, { community: selectedCommunity.value }) }" class="sidebar-button">
|
|
||||||
<span class="material-icons-outlined">add</span>
|
|
||||||
<span class="sidebar-button-text">Create Channel</span>
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
{#if !$gatewayStatus.ready}
|
{#if !$gatewayStatus.ready}
|
||||||
<div class="top-bar darker">
|
<div class="top-bar darker">
|
||||||
|
|
88
frontend/src/components/SidebarCommunity.svelte
Normal file
88
frontend/src/components/SidebarCommunity.svelte
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
<script>
|
||||||
|
import { avatarUrl } from "../storage";
|
||||||
|
import { OverlayType, overlayStore, userInfoStore } from "../stores";
|
||||||
|
import ChipBar from "./ChipBar.svelte";
|
||||||
|
|
||||||
|
export let communityLike;
|
||||||
|
export let isUser = false;
|
||||||
|
|
||||||
|
$: options = [
|
||||||
|
{
|
||||||
|
id: "SETTINGS",
|
||||||
|
icon: "settings",
|
||||||
|
hidden: !isUser,
|
||||||
|
handle() {
|
||||||
|
overlayStore.push(OverlayType.Settings);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "EDIT_COMMUNITY",
|
||||||
|
icon: "edit",
|
||||||
|
hidden: !(!isUser && communityLike && $userInfoStore && communityLike.owner_id === $userInfoStore.id),
|
||||||
|
handle() {
|
||||||
|
overlayStore.push(OverlayType.EditCommunity, { community: communityLike });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "NEW_CHANNEL",
|
||||||
|
icon: "add",
|
||||||
|
hidden: (!$userInfoStore || !$userInfoStore.permissions.create_channel),
|
||||||
|
handle() {
|
||||||
|
overlayStore.push(OverlayType.CreateChannel, { community: isUser ? { id: -1 } : communityLike });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
let heading = "";
|
||||||
|
$: if (communityLike) {
|
||||||
|
heading = communityLike.username || communityLike.name || "";
|
||||||
|
} else {
|
||||||
|
heading = "";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
margin: var(--space-sm);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .avatar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 18px;
|
||||||
|
position: relative;
|
||||||
|
background-color: var(--background-color-3);
|
||||||
|
margin-top: -24px;
|
||||||
|
margin-left: 12px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner {
|
||||||
|
background-color: var(--background-color-0);
|
||||||
|
height: 90px;
|
||||||
|
border-radius: var(--radius-norm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .text-bold {
|
||||||
|
position: relative;
|
||||||
|
margin: 12px;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="banner"></div>
|
||||||
|
{#if communityLike && communityLike.avatar}
|
||||||
|
<img class="avatar" src={avatarUrl(communityLike.avatar, 64)} alt=" ">
|
||||||
|
{:else}
|
||||||
|
<div class="avatar">{heading && heading[0] ? heading[0] : ""}</div>
|
||||||
|
{/if}
|
||||||
|
<div class="text-bold">{ heading }</div>
|
||||||
|
<ChipBar options={options} smaller={true} />
|
||||||
|
</div>
|
55
frontend/src/components/overlays/EditCommunity.svelte
Normal file
55
frontend/src/components/overlays/EditCommunity.svelte
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<script>
|
||||||
|
import { overlayStore } from "../../stores";
|
||||||
|
import { getMessageFromResponse, methods, remoteSignal, responseOk } from "../../request";
|
||||||
|
import Modal from "./Modal.svelte";
|
||||||
|
import RpcErrorDisplay from "../rpc/RpcErrorDisplay.svelte";
|
||||||
|
|
||||||
|
export let community;
|
||||||
|
|
||||||
|
let communityName = community.name;
|
||||||
|
let buttonsEnabled = true;
|
||||||
|
let response;
|
||||||
|
export let close = () => {};
|
||||||
|
|
||||||
|
const save = async () => {
|
||||||
|
buttonsEnabled = false;
|
||||||
|
response = await remoteSignal(methods.updateCommunityName, community.id, communityName);
|
||||||
|
buttonsEnabled = true;
|
||||||
|
if (responseOk(response)) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const deleteCommunity = async () => {
|
||||||
|
buttonsEnabled = false;
|
||||||
|
const res = await remoteSignal(methods.deleteCommunity, community.id);
|
||||||
|
if (!responseOk(res)) {
|
||||||
|
overlayStore.toast(`Couldn't delete community: ${getMessageFromResponse(res)}`);
|
||||||
|
}
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.delete-button {
|
||||||
|
color: var(--red-2);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<Modal {close} enter={save}>
|
||||||
|
<span class="h4" slot="header">Edit Community</span>
|
||||||
|
|
||||||
|
<svelte:fragment slot="content">
|
||||||
|
<RpcErrorDisplay response={response} />
|
||||||
|
<RpcErrorDisplay validationIndex={1} response={response} />
|
||||||
|
<label class="input-label">
|
||||||
|
<span>Community Name</span>
|
||||||
|
<input class="input full-width" minlength="1" maxlength="32" bind:value={ communityName } />
|
||||||
|
</label>
|
||||||
|
</svelte:fragment>
|
||||||
|
|
||||||
|
<svelte:fragment slot="footer">
|
||||||
|
<button class="button modal-secondary-action" on:click="{ close }">Cancel</button>
|
||||||
|
<button class="button modal-secondary-action delete-button" on:click="{ deleteCommunity }" disabled="{ !buttonsEnabled }">Delete</button>
|
||||||
|
<button class="button button-accent modal-primary-action" on:click="{ save }" disabled="{ !buttonsEnabled }">Save</button>
|
||||||
|
</svelte:fragment>
|
||||||
|
</Modal>
|
|
@ -11,6 +11,7 @@
|
||||||
import Prompt from "./Prompt.svelte";
|
import Prompt from "./Prompt.svelte";
|
||||||
import UserInfo from "./UserInfo.svelte";
|
import UserInfo from "./UserInfo.svelte";
|
||||||
import AddCommunity from "./AddCommunity.svelte";
|
import AddCommunity from "./AddCommunity.svelte";
|
||||||
|
import EditCommunity from "./EditCommunity.svelte";
|
||||||
|
|
||||||
const OverlayComponent = {
|
const OverlayComponent = {
|
||||||
0: CreateChannel,
|
0: CreateChannel,
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
7: Prompt,
|
7: Prompt,
|
||||||
8: UserInfo,
|
8: UserInfo,
|
||||||
9: AddCommunity,
|
9: AddCommunity,
|
||||||
|
10: EditCommunity,
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@
|
||||||
<span class="h4" slot="header">Settings</span>
|
<span class="h4" slot="header">Settings</span>
|
||||||
|
|
||||||
<svelte:fragment slot="content">
|
<svelte:fragment slot="content">
|
||||||
<ChipBar selectedOptionId="ACCOUNT" onSelect={ (tab) => selectedTab = tab } options={[
|
<ChipBar selectedOptionId="ACCOUNT" onSelect={ (tab) => selectedTab = tab } doHighlight={true} options={[
|
||||||
{ id: "ACCOUNT", text: "Account", icon: "person" },
|
{ id: "ACCOUNT", text: "Account", icon: "person" },
|
||||||
{ id: "PRIVACY", text: "Privacy", icon: "lock" },
|
{ id: "PRIVACY", text: "Privacy", icon: "lock" },
|
||||||
{ id: "APPEARANCE", text: "Appearance", icon: "palette" },
|
{ id: "APPEARANCE", text: "Appearance", icon: "palette" },
|
||||||
|
|
|
@ -6,7 +6,8 @@ import { useDebuggingApi } from './debuggingapi';
|
||||||
import gateway, { GatewayEventType } from './gateway';
|
import gateway, { GatewayEventType } from './gateway';
|
||||||
import { pluginStore } from './stores';
|
import { pluginStore } from './stores';
|
||||||
|
|
||||||
import "@fontsource/material-icons-outlined"
|
import "@fontsource-variable/material-symbols-outlined/opsz.css";
|
||||||
|
import "@fontsource-variable/open-sans";
|
||||||
import "./styles/global.css";
|
import "./styles/global.css";
|
||||||
import { timeline } from './timeline';
|
import { timeline } from './timeline';
|
||||||
|
|
||||||
|
|
|
@ -401,7 +401,8 @@ export const OverlayType = {
|
||||||
Settings: 6,
|
Settings: 6,
|
||||||
Prompt: 7,
|
Prompt: 7,
|
||||||
UserInfo: 8,
|
UserInfo: 8,
|
||||||
AddCommunity: 9
|
AddCommunity: 9,
|
||||||
|
EditCommunity: 10
|
||||||
};
|
};
|
||||||
class OverlayStore extends Store {
|
class OverlayStore extends Store {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -1,56 +1,3 @@
|
||||||
/* fonts */
|
|
||||||
/* FIXME: fonts greatly increase payload size */
|
|
||||||
|
|
||||||
/* open-sans-latin-ext-wght-normal */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Open Sans Variable';
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
font-weight: 300 800;
|
|
||||||
src: url(./files/open-sans-latin-ext-wght-normal.woff2) format('woff2-variations');
|
|
||||||
unicode-range: U+0100-02AF,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open-sans-latin-wght-normal */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Open Sans Variable';
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
font-weight: 300 800;
|
|
||||||
src: url(./files/open-sans-latin-wght-normal.woff2) format('woff2-variations');
|
|
||||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Iosevka Waffle Web";
|
|
||||||
font-display: swap;
|
|
||||||
font-weight: 400;
|
|
||||||
font-stretch: normal;
|
|
||||||
font-style: normal;
|
|
||||||
src: url("/assets/woff2/iosevka-waffle-regular.woff2") format("woff2");
|
|
||||||
font-display: fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Iosevka Waffle Web";
|
|
||||||
font-display: swap;
|
|
||||||
font-weight: 700;
|
|
||||||
font-stretch: normal;
|
|
||||||
font-style: normal;
|
|
||||||
src: url("/assets/woff2/iosevka-waffle-bold.woff2") format("woff2");
|
|
||||||
font-display: fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Iosevka Waffle Web";
|
|
||||||
font-display: swap;
|
|
||||||
font-weight: 300;
|
|
||||||
font-stretch: normal;
|
|
||||||
font-style: normal;
|
|
||||||
src: url("/assets/woff2/iosevka-waffle-light.woff2") format("woff2");
|
|
||||||
font-display: fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* top-level */
|
/* top-level */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
@ -243,7 +190,6 @@ body {
|
||||||
background-color: var(--background-color-2);
|
background-color: var(--background-color-2);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
contain: content;
|
contain: content;
|
||||||
box-shadow: 0px 0px 8px rgba(91, 91, 97, 0.144);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-header {
|
.modal-header {
|
||||||
|
@ -549,6 +495,10 @@ body {
|
||||||
|
|
||||||
|
|
||||||
.material-icons-outlined, .material-icons {
|
.material-icons-outlined, .material-icons {
|
||||||
|
font-family: "Material Symbols Outlined Variable";
|
||||||
|
font-variation-settings: 'opsz' 20;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 20px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
color: var(--foreground-special-color-1);
|
color: var(--foreground-special-color-1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,16 +10,16 @@
|
||||||
"@jridgewell/gen-mapping" "^0.3.0"
|
"@jridgewell/gen-mapping" "^0.3.0"
|
||||||
"@jridgewell/trace-mapping" "^0.3.9"
|
"@jridgewell/trace-mapping" "^0.3.9"
|
||||||
|
|
||||||
|
"@fontsource-variable/material-symbols-outlined@^5.0.7":
|
||||||
|
version "5.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@fontsource-variable/material-symbols-outlined/-/material-symbols-outlined-5.0.7.tgz#9a114edbf2eb8de9527eab0eafc9d7495ca2c83e"
|
||||||
|
integrity sha512-44V8EQez2d7H305mwHPOu4b6vpVhcklhA8MN7hO5jnfuSeIS3zEzzRS4/4wnHk80F3GFuqgROh2GJg631PmGvQ==
|
||||||
|
|
||||||
"@fontsource-variable/open-sans@^5.0.6":
|
"@fontsource-variable/open-sans@^5.0.6":
|
||||||
version "5.0.6"
|
version "5.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/@fontsource-variable/open-sans/-/open-sans-5.0.6.tgz#d92c5de9843b999d914e444afda54c39a752d949"
|
resolved "https://registry.yarnpkg.com/@fontsource-variable/open-sans/-/open-sans-5.0.6.tgz#d92c5de9843b999d914e444afda54c39a752d949"
|
||||||
integrity sha512-ZEbqIsXo84fQeQwU2CPyI3W+8QMdbTVBS+CRbWBDA8nPbV9pyRCBy3UceyPrA7l1MJx4qaz5wv5hHQXDadgCzg==
|
integrity sha512-ZEbqIsXo84fQeQwU2CPyI3W+8QMdbTVBS+CRbWBDA8nPbV9pyRCBy3UceyPrA7l1MJx4qaz5wv5hHQXDadgCzg==
|
||||||
|
|
||||||
"@fontsource/material-icons-outlined@^4.5.4":
|
|
||||||
version "4.5.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/@fontsource/material-icons-outlined/-/material-icons-outlined-4.5.4.tgz#23ce468b7c569d1c717061cb8c5a69b3cb3fba12"
|
|
||||||
integrity sha512-2SLQe/pAlOzoE2Kd5cBxqTgI9U63hf3a7RrCF8GFvgPkYhF6WOcIzFzsLc1Fdf+UhcYS+Hgpp6o8peguwZGK9Q==
|
|
||||||
|
|
||||||
"@jridgewell/gen-mapping@^0.3.0":
|
"@jridgewell/gen-mapping@^0.3.0":
|
||||||
version "0.3.2"
|
version "0.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
|
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
|
||||||
|
|
Loading…
Reference in a new issue