significantly improve unread system
This commit is contained in:
parent
81e9de6cd8
commit
7b9379732e
3 changed files with 74 additions and 31 deletions
|
@ -348,7 +348,7 @@ body {
|
|||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.sidebar-button div {
|
||||
.sidebar-button .sidebar-button-icon {
|
||||
display: inline;
|
||||
flex-shrink: 0;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { HashIcon, PlusIcon, MoreVerticalIcon, SettingsIcon, CloudIcon } from "svelte-feather-icons";
|
||||
import { quadInOut } from "svelte/easing";
|
||||
import { maybeFly, maybeFlyIf } from "../animations";
|
||||
import { channels, gatewayStatus, overlayStore, selectedChannel, showSidebar, smallViewport, userInfoStore } from "../stores";
|
||||
import { channels, gatewayStatus, overlayStore, selectedChannel, showSidebar, smallViewport, userInfoStore, unreadStore } from "../stores";
|
||||
import UserTopBar from "./UserTopBar.svelte";
|
||||
|
||||
const selectChannel = (channel) => {
|
||||
|
@ -19,30 +19,32 @@
|
|||
<div class="sidebar">
|
||||
{#each $channels as channel (channel.id)}
|
||||
<button on:click="{ selectChannel(channel) }" class="sidebar-button" class:selected={ channel.id === $selectedChannel.id }>
|
||||
<div>
|
||||
<div class="sidebar-button-icon">
|
||||
<HashIcon />
|
||||
</div>
|
||||
<span>{ channel.name }</span>
|
||||
{#if channel._hasUnreads}
|
||||
<span class="unread-indicator">•</span>
|
||||
<div class="sidebar-channel-buttons">
|
||||
{#if $unreadStore.get(channel.id)}
|
||||
<div class="unread-indicator">{ $unreadStore.get(channel.id) }</div>
|
||||
{/if}
|
||||
{#if $userInfoStore && (channel.owner_id === $userInfoStore.id || $userInfoStore.is_superuser)}
|
||||
<button class="icon-button icon-button-auto" on:click|stopPropagation="{ () => overlayStore.open('editChannel', { channel }) }" aria-label="Edit Channel">
|
||||
<button class="icon-button" on:click|stopPropagation="{ () => overlayStore.open('editChannel', { channel }) }" aria-label="Edit Channel">
|
||||
<MoreVerticalIcon />
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
{/each}
|
||||
{#if $userInfoStore && $userInfoStore.permissions.create_channel}
|
||||
<button on:click="{ () => overlayStore.open('createChannel') }" class="sidebar-button">
|
||||
<div>
|
||||
<div class="sidebar-button-icon">
|
||||
<PlusIcon />
|
||||
</div>
|
||||
<span>Create Channel</span>
|
||||
</button>
|
||||
{/if}
|
||||
<button on:click="{ () => overlayStore.open('settings') }" class="sidebar-button">
|
||||
<div>
|
||||
<div class="sidebar-button-icon">
|
||||
<SettingsIcon />
|
||||
</div>
|
||||
<span>Settings</span>
|
||||
|
@ -58,7 +60,24 @@
|
|||
|
||||
<style>
|
||||
.unread-indicator {
|
||||
color: var(--purple-2);
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--red-2);
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
padding-left: 0.375rem;
|
||||
padding-right: 0.375rem;
|
||||
border-radius: 9999px;
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
.sidebar-channel-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -103,22 +103,6 @@ class ChannelsStore extends Store {
|
|||
this.value[index] = data;
|
||||
this.updated();
|
||||
});
|
||||
gateway.subscribe(GatewayEventType.MessageCreate, ({ channel_id }) => {
|
||||
const index = this.value.findIndex(e => e.id === channel_id);
|
||||
if (index === -1 || !this.value[index] || selectedChannel.value.id === channel_id)
|
||||
return;
|
||||
|
||||
this.value[index]._hasUnreads = true;
|
||||
this.updated();
|
||||
});
|
||||
selectedChannel.subscribe(({ id }) => {
|
||||
const index = this.value.findIndex(e => e.id === id);
|
||||
if (index === -1 || !this.value[index] || !this.value[index]._hasUnreads)
|
||||
return;
|
||||
|
||||
this.value[index]._hasUnreads = false;
|
||||
this.updated();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -448,6 +432,31 @@ class PresenceStore extends Store {
|
|||
}
|
||||
}
|
||||
|
||||
class UnreadStore extends Store {
|
||||
constructor() {
|
||||
super(new Map(), "UnreadStore");
|
||||
|
||||
gateway.subscribe(GatewayEventType.MessageCreate, ({ channel_id: channelId }) => {
|
||||
if (selectedChannel.value.id !== channelId || window.document.visibilityState !== "visible") {
|
||||
this.value.set(channelId, (this.value.get(channelId) || 0) + 1);
|
||||
this.updated();
|
||||
}
|
||||
});
|
||||
|
||||
selectedChannel.subscribe(({ id }) => {
|
||||
this.value.delete(id);
|
||||
this.updated();
|
||||
});
|
||||
|
||||
window.document.addEventListener("visibilitychange", () => {
|
||||
if (window.document.visibilityState === "visible" && selectedChannel.value) {
|
||||
this.value.delete(selectedChannel.value.id);
|
||||
this.updated();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const selectedChannel = new Store({ id: -1, name: "none", creator_id: -1 }, "selectedChannel");
|
||||
export const showSidebar = new Store(true, "showSidebar");
|
||||
export const showPresenceSidebar = new Store(false, "showPresenceSidebar");
|
||||
|
@ -462,14 +471,15 @@ export const userInfoStore = new UserInfoStore();
|
|||
export const overlayStore = new OverlayStore();
|
||||
export const typingStore = new TypingStore();
|
||||
export const presenceStore = new PresenceStore();
|
||||
export const unreadStore = new UnreadStore();
|
||||
export const setMessageInputEvent = new Store(null, "event:setMessageInput");
|
||||
|
||||
export const allStores = {
|
||||
selectedChannel,
|
||||
showSidebar,
|
||||
showPresenceSidebar,
|
||||
showChannelView,
|
||||
smallViewport,
|
||||
showChannelView,
|
||||
theme,
|
||||
doAnimations,
|
||||
channels,
|
||||
|
@ -478,6 +488,9 @@ export const allStores = {
|
|||
userInfoStore,
|
||||
overlayStore,
|
||||
typingStore,
|
||||
presenceStore,
|
||||
unreadStore,
|
||||
setMessageInputEvent,
|
||||
};
|
||||
|
||||
selectedChannel.watch((newSelectedChannel) => {
|
||||
|
@ -485,3 +498,14 @@ selectedChannel.watch((newSelectedChannel) => {
|
|||
setItem("state:openChannelId", newSelectedChannel.id);
|
||||
}
|
||||
});
|
||||
|
||||
unreadStore.subscribe(() => {
|
||||
let totalUnreads = 0;
|
||||
unreadStore.value.forEach(count => totalUnreads += count);
|
||||
|
||||
if (totalUnreads > 0) {
|
||||
window.document.title = `(${totalUnreads}) waffle`;
|
||||
} else {
|
||||
window.document.title = "waffle";
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue