Compare commits

...

2 commits

Author SHA1 Message Date
hippoz
64b8e1eafa
greatly improve ui 2022-11-12 21:39:21 +02:00
hippoz
64478b5804
remove third party notice 2022-11-12 17:43:44 +02:00
7 changed files with 80 additions and 199 deletions

View file

@ -25,10 +25,11 @@
--background-color-1: hsl(180, 11%, 7%); --background-color-1: hsl(180, 11%, 7%);
--background-color-2: hsl(180, 11%, 10%); --background-color-2: hsl(180, 11%, 10%);
--background-color-3: hsl(180, 11%, 12%); --background-color-3: hsl(180, 11%, 12%);
--foreground-color-1: rgb(253, 254, 255); --foreground-color-1: hsl(210, 100%, 100%);
--foreground-color-2: rgb(218, 219, 220); --foreground-color-2: hsl(63, 10%, 82%);
--foreground-color-3: rgb(153, 154, 155); --foreground-color-3: hsl(63, 2%, 60%);
--foreground-color-4: rgb(123, 124, 125); --foreground-color-4: hsl(63, 2%, 49%);
--foreground-special-color-1: hsl(180, 18%, 70%);
--colored-element-text-color: var(--foreground-color-1); --colored-element-text-color: var(--foreground-color-1);
--purple-1: hsl(280, 78%, 50%); --purple-1: hsl(280, 78%, 50%);
@ -88,7 +89,6 @@ body {
background-color: var(--background-color-1); background-color: var(--background-color-1);
font-size: 100%; font-size: 100%;
font-family: "Iosevka Waffle Web", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; font-family: "Iosevka Waffle Web", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
font-weight: 400;
line-height: 1.75; line-height: 1.75;
display: flex; display: flex;
@ -264,6 +264,8 @@ body {
background-color: var(--red-2); background-color: var(--red-2);
} }
/* icon buttons */
.icon-button { .icon-button {
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -276,6 +278,11 @@ body {
font: inherit; font: inherit;
} }
.icon-button .material-icons,
.icon-button .material-icons-outlined {
color: currentColor;
}
.icon-button-auto { .icon-button-auto {
margin-left: auto; margin-left: auto;
} }
@ -286,29 +293,12 @@ body {
/* text */ /* text */
.h1 { .h1 {font-size: 1.802rem;}
font-size: 2.488rem; .h2 {font-size: 1.602rem;}
} .h3 {font-size: 1.424rem;}
.h4 {font-size: 1.266rem;}
.h2 { .h5 {font-size: 1.125rem;}
font-size: 2.074rem; .text-small {font-size: 0.889rem;}
}
.h3 {
font-size: 1.728rem;
}
.h4 {
font-size: 1.44rem;
}
.h5 {
font-size: 1.2rem;
}
.text-small {
font-size: 0.833rem;
}
/* sidebar */ /* sidebar */
@ -347,11 +337,10 @@ body {
background-color: var(--background-color-0); background-color: var(--background-color-0);
padding: var(--space-xs); padding: var(--space-xs);
margin-bottom: var(--space-xxs); margin-bottom: var(--space-xxs);
color: currentColor; color: var(--foreground-special-color-1);
font: inherit; font: inherit;
border-radius: var(--radius-md); border-radius: var(--radius-md);
width: 100%; width: 100%;
max-height: 3.4em;
} }
.sidebar-button .sidebar-button-text { .sidebar-button .sidebar-button-text {
@ -375,16 +364,17 @@ body {
} }
.sidebar-button.selected { .sidebar-button.selected {
color: var(--colored-element-text-color); color: var(--foreground-color-1);
background-color: var(--purple-2); background-color: var(--background-color-3);
} }
.sidebar-button.selected .icon-button { .sidebar-button.selected .icon-button {
color: var(--colored-element-text-color); color: var(--foreground-color-1);
} }
.material-icons-outlined, .material-icons { .material-icons-outlined, .material-icons {
user-select: none; user-select: none;
color: var(--foreground-special-color-1);
} }
/* badges */ /* badges */

View file

@ -19,29 +19,17 @@
<style> <style>
.message { .message {
display: flex; position: relative;
align-items: flex-start;
overflow-x: hidden; overflow-x: hidden;
word-wrap: break-word; word-wrap: break-word;
padding: var(--space-xs) var(--space-xs) var(--space-xs) var(--space-normplus); padding: 3px 3px 3px var(--space-normplus);
margin-top: 16px;
} }
.message.pinged { .message:hover, .message.pinged {
background-color: var(--background-color-2); background-color: var(--background-color-2);
} }
.message .edit-message {
visibility: hidden;
}
.message:hover {
background-color: var(--background-color-3);
}
.message:hover .edit-message {
visibility: visible;
}
.message-content { .message-content {
color: var(--foreground-color-2); color: var(--foreground-color-2);
white-space: pre-wrap; white-space: pre-wrap;
@ -52,12 +40,12 @@
} }
.author { .author {
display: inline-flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex-shrink: 0; flex-shrink: 0;
font-weight: bold; font-weight: bold;
margin-right: var(--space-xs); color: var(--foreground-color-2);
} }
.author-more { .author-more {
@ -65,84 +53,70 @@
} }
.author-group { .author-group {
display: inline-flex; display: flex;
align-items: center; align-items: center;
flex-shrink: 0; flex-shrink: 0;
} }
.edit-message { .message-author-date {
flex-shrink: 0; color: var(--foreground-color-3);
float: right; font-size: 0.7rem;
margin-left: var(--space-sm);
} }
.date { .message.clumped {
display: inline-flex; margin-top: 0;
justify-content: center;
align-items: center;
background-color: var(--background-color-2);
padding-top: 1px;
padding-bottom: 1px;
padding-left: 0.375rem;
padding-right: 0.375rem;
border-radius: 9999px;
font-size: small;
visibility: hidden;
margin-left: auto;
flex-shrink: 0;
user-select: none;
}
.message.clumped .author-group {
visibility: hidden;
}
.message:hover .date,
.message.clumped:hover .author-group {
visibility: visible;
}
@media (max-width: 768px) {
.message {
padding: var(--space-xxs) var(--space-xxs) var(--space-xxs) var(--space-normplus);
}
.message .message-extra {
display: none;
}
.message:hover .message-extra {
display: inline-flex;
}
}
.message.clumped {
padding: 2px 2px 2px var(--space-normplus);
} }
.via-badge { .via-badge {
background-color: var(--background-color-3);
margin-left: var(--space-xs); margin-left: var(--space-xs);
margin-right: var(--space-md);
cursor: default; cursor: default;
flex-shrink: 0; flex-shrink: 0;
} }
.message-actions {
display: flex;
position: absolute;
top: 3px;
right: 12px;
z-index: 1;
}
.message-actions .icon-button {
margin: 0;
padding: 0;
}
.message .message-actions {
display: none;
}
.message:hover .message-actions {
display: flex;
}
</style> </style>
<div class="message" class:clumped={ message._clumped } class:pinged={ message._mentions }> <div class="message" class:clumped={ message._clumped } class:has-children={ message._hasChildren } class:pinged={ message._mentions }>
<div class="author-group"> {#if !message._clumped}
<span class="author" class:author-more={message._viaBadge}>{ message._effectiveAuthor }</span> <div class="author-group">
{#if message._viaBadge} <span class="author" class:author-more={message._viaBadge}>{ message._effectiveAuthor }</span>
<span class="user-badge via-badge">via { message._viaBadge }</span> {#if message._viaBadge}
{/if} <span class="user-badge via-badge">via { message._viaBadge }</span>
</div> {/if}
<span class="message-author-date">{ message._createdAtTimeString }</span>
</div>
{/if}
<span class="message-content" class:pending={ message._isPending }>{ message.content }</span> <span class="message-content" class:pending={ message._isPending }>{ message.content }</span>
<span class="date message-extra">{ message._createdAtTimeString }</span> <div class="message-actions">
<button class="icon-button edit-message message-extra material-icons-outlined" on:click="{ reply }" aria-label="Reply to Message"> <button class="icon-button material-icons-outlined" on:click="{ reply }" aria-label="Reply to Message">
reply reply
</button>
{#if message._editable}
<button class="icon-button edit-message message-extra material-icons-outlined" on:click="{ () => overlayStore.push(OverlayType.EditMessage, { message }) }" aria-label="Edit Message">
edit
</button> </button>
{/if} {#if message._editable}
<button class="icon-button material-icons-outlined" on:click="{ () => overlayStore.push(OverlayType.EditMessage, { message }) }" aria-label="Edit Message">
edit
</button>
{/if}
</div>
</div> </div>

View file

@ -1,9 +1,7 @@
<script> <script>
import { quadInOut } from "svelte/easing"; import { quadInOut } from "svelte/easing";
import { maybeFly, maybeFlyIf } from "../animations"; import { maybeFly, maybeFlyIf } from "../animations";
import { getItem } from "../storage"; import { channels, gatewayStatus, overlayStore, selectedChannel, showSidebar, smallViewport, userInfoStore, unreadStore, OverlayType } from "../stores";
import { channels, gatewayStatus, overlayStore, selectedChannel, showSidebar, smallViewport, userInfoStore, unreadStore, OverlayType, thirdPartyServicePresenceStore } from "../stores";
import ThirdPartyNotice from "./overlays/ThirdPartyNotice.svelte";
import UserTopBar from "./UserTopBar.svelte"; import UserTopBar from "./UserTopBar.svelte";
const selectChannel = (channel) => { const selectChannel = (channel) => {
@ -45,13 +43,6 @@
<span class="sidebar-button-text">Settings</span> <span class="sidebar-button-text">Settings</span>
</button> </button>
</div> </div>
{#if $thirdPartyServicePresenceStore && getItem("ui:showThirdPartyNotice")}
<div class="top-bar darker">
<span class="material-icons-outlined">cloud</span>
<span class="text-small top-bar-heading">some third party services may have additional terms</span>
<button class="button" on:click={ () => overlayStore.push(OverlayType.ThirdPartyNotice) }>Review</button>
</div>
{/if}
{#if !$gatewayStatus.ready} {#if !$gatewayStatus.ready}
<div class="top-bar darker"> <div class="top-bar darker">
<span class="material-icons-outlined">cloud</span> <span class="material-icons-outlined">cloud</span>

View file

@ -10,7 +10,6 @@
import Settings from "./Settings.svelte"; import Settings from "./Settings.svelte";
import Prompt from "./Prompt.svelte"; import Prompt from "./Prompt.svelte";
import UserInfo from "./UserInfo.svelte"; import UserInfo from "./UserInfo.svelte";
import ThirdPartyNotice from "./ThirdPartyNotice.svelte";
const OverlayComponent = { const OverlayComponent = {
0: CreateChannel, 0: CreateChannel,
@ -22,7 +21,6 @@
6: Settings, 6: Settings,
7: Prompt, 7: Prompt,
8: UserInfo, 8: UserInfo,
9: ThirdPartyNotice,
}; };
</script> </script>

View file

@ -1,53 +0,0 @@
<script>
import { maybeModalFade, maybeModalScale } from "../../animations";
import { overlayStore, OverlayType, presenceStore } from "../../stores";
export let close = () => {};
</script>
<style>
.info-modal {
max-width: 560px;
}
.notice-user-card {
display: flex;
align-items: center;
justify-content: left;
padding: var(--space-md);
}
.notice-user-card-buttons {
margin-left: auto;
}
.full-width {
width: 100%;
}
</style>
<div class="modal-backdrop" transition:maybeModalFade on:click="{ close }">
<div class="modal info-modal" transition:maybeModalScale on:click|stopPropagation>
<div class="modal-header">
<span class="h4">Third Party Services</span>
</div>
<p>Certain third-party services on this server may have different data processing, data usage, and data collection policies, as well as Terms of Service or similar. Please carefully review each service in the list below. If you do not agree with any of these policies, you may be able to ask the user to opt out, or make an account deletion request to the server owner. The server owner may be able to aid you in the process of opting out.</p>
{#each $presenceStore as entry (entry.user.id)}
{#if entry.bridgesTo || entry.terms || entry.privacy}
<div class="notice-user-card full-width">
<span class="material-icons-outlined">alternate_email</span>
<span class="h5 top-bar-heading">{ entry.user.username }</span>
<div class="notice-user-card-buttons">
<button class="button" on:click="{ () => overlayStore.push(OverlayType.UserInfo, { presenceEntry: entry }) }">View Info</button>
</div>
</div>
{/if}
{/each}
<div class="modal-footer">
<button class="button modal-secondary-action" on:click="{ close }">Cancel</button>
</div>
</div>
</div>

View file

@ -11,7 +11,6 @@ const defaults = {
"ui:stateful:presistSelectedChannel": true, "ui:stateful:presistSelectedChannel": true,
"ui:showSidebarToggle": false, "ui:showSidebarToggle": false,
"ui:alwaysUseMobileChatBar": false, "ui:alwaysUseMobileChatBar": false,
"ui:showThirdPartyNotice": true,
"ui:online:processRemoteTypingEvents": true, "ui:online:processRemoteTypingEvents": true,
"ui:online:processRemotePresenceEvents": true, "ui:online:processRemotePresenceEvents": true,
"ui:online:loadMessageHistory": true, "ui:online:loadMessageHistory": true,

View file

@ -247,6 +247,7 @@ class MessageStore extends Store {
} }
if (previous && (message._createdAtDate.getTime() - previous._createdAtDate.getTime()) <= 100 * 1000 && message.author_id === previous.author_id && message._effectiveAuthor === previous._effectiveAuthor && message._viaBadge === previous._viaBadge) { if (previous && (message._createdAtDate.getTime() - previous._createdAtDate.getTime()) <= 100 * 1000 && message.author_id === previous.author_id && message._effectiveAuthor === previous._effectiveAuthor && message._viaBadge === previous._viaBadge) {
message._clumped = true; message._clumped = true;
previous._hasChildren = true;
} }
if (!previous || (previous._createdAtDateString !== message._createdAtDateString && !message._aboveDateMarker)) { if (!previous || (previous._createdAtDateString !== message._createdAtDateString && !message._aboveDateMarker)) {
message._aboveDateMarker = new Intl.DateTimeFormat(getItem("ui:locale"), { month: "long", day: "numeric", year: "numeric" }).format(message._createdAtDate); message._aboveDateMarker = new Intl.DateTimeFormat(getItem("ui:locale"), { month: "long", day: "numeric", year: "numeric" }).format(message._createdAtDate);
@ -407,8 +408,7 @@ export const OverlayType = {
EditMessage: 5, EditMessage: 5,
Settings: 6, Settings: 6,
Prompt: 7, Prompt: 7,
UserInfo: 8, UserInfo: 8
ThirdPartyNotice: 9
}; };
class OverlayStore extends Store { class OverlayStore extends Store {
constructor() { constructor() {
@ -658,23 +658,6 @@ class PluginStore extends Store {
} }
} }
class ThirdPartyServicePresenceStore extends Store {
constructor() {
super(false, "ThirdPartyServicePresenceStore");
presenceStore.subscribe((value) => {
let hasService = false;
value.forEach(e => {
if (e.bridgesTo || e.privacy || e.terms) {
hasService = true;
return;
}
});
this.set(hasService);
});
}
}
export const selectedChannel = new Store({ id: -1, name: "none", creator_id: -1 }, "selectedChannel"); export const selectedChannel = new Store({ id: -1, name: "none", creator_id: -1 }, "selectedChannel");
export const showSidebar = new Store(true, "showSidebar"); export const showSidebar = new Store(true, "showSidebar");
export const showPresenceSidebar = new Store(false, "showPresenceSidebar"); export const showPresenceSidebar = new Store(false, "showPresenceSidebar");
@ -691,7 +674,6 @@ export const typingStore = new TypingStore();
export const presenceStore = new PresenceStore(); export const presenceStore = new PresenceStore();
export const unreadStore = new UnreadStore(); export const unreadStore = new UnreadStore();
export const pluginStore = new PluginStore(); export const pluginStore = new PluginStore();
export const thirdPartyServicePresenceStore = new ThirdPartyServicePresenceStore();
export const setMessageInputEvent = new Store(null, "event:setMessageInput"); export const setMessageInputEvent = new Store(null, "event:setMessageInput");
export const sendMessageAction = createAction("sendMessageAction", async ({channelId, content}) => { export const sendMessageAction = createAction("sendMessageAction", async ({channelId, content}) => {