Compare commits
No commits in common. "4d336e4a26d806beabc80904eaa5c7407d24ad7b" and "2655e12d9031fb839d399765fb769d5a379766d0" have entirely different histories.
4d336e4a26
...
2655e12d90
3 changed files with 38 additions and 73 deletions
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
replyString += `@${message.author_username}: `;
|
replyString += `@${message.author_username}: `;
|
||||||
|
|
||||||
setMessageInputEvent.emit(replyString);
|
setMessageInputEvent.update(replyString);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { onDestroy, onMount } from "svelte";
|
import { onDestroy, onMount } from "svelte";
|
||||||
import request from "../request";
|
import request from "../request";
|
||||||
import { apiRoute, getItem } from "../storage";
|
import { apiRoute, getItem } from "../storage";
|
||||||
import { messagesStoreProvider, overlayStore, selectedChannel, sendMessageAction, setMessageInputEvent, smallViewport, typingStore, userInfoStore } from "../stores";
|
import { messagesStoreProvider, overlayStore, selectedChannel, setMessageInputEvent, smallViewport, typingStore, userInfoStore } from "../stores";
|
||||||
|
|
||||||
export let channel;
|
export let channel;
|
||||||
let messageInput = "";
|
let messageInput = "";
|
||||||
|
@ -41,11 +41,37 @@
|
||||||
|
|
||||||
const sendMessage = async () => {
|
const sendMessage = async () => {
|
||||||
messageTextarea.focus();
|
messageTextarea.focus();
|
||||||
sendMessageAction.emit({
|
|
||||||
channelId: channel.id,
|
if (messageInput.trim() === "" || !$userInfoStore)
|
||||||
content: messageInput
|
return;
|
||||||
});
|
|
||||||
|
// optimistically add message to store
|
||||||
|
const optimisticMessageId = Math.floor(Math.random() * 999999);
|
||||||
|
const optimisticMessage = {
|
||||||
|
id: optimisticMessageId,
|
||||||
|
content: messageInput,
|
||||||
|
channel_id: channel.id,
|
||||||
|
author_id: $userInfoStore.id,
|
||||||
|
author_username: $userInfoStore.username,
|
||||||
|
created_at: Date.now().toString(),
|
||||||
|
_isPending: true
|
||||||
|
};
|
||||||
|
messages.addMessage(optimisticMessage);
|
||||||
messageInput = "";
|
messageInput = "";
|
||||||
|
|
||||||
|
const res = await request("POST", apiRoute(`channels/${channel.id}/messages`), true, {
|
||||||
|
content: optimisticMessage.content,
|
||||||
|
optimistic_id: optimisticMessageId
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.success && res.ok) {
|
||||||
|
messages.setMessage(optimisticMessageId, res.json);
|
||||||
|
} else {
|
||||||
|
messages.deleteMessage({
|
||||||
|
id: optimisticMessageId
|
||||||
|
});
|
||||||
|
overlayStore.toast("Couldn't send message");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onKeydown = async (e) => {
|
const onKeydown = async (e) => {
|
||||||
|
@ -74,10 +100,10 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
onMount(focusTextarea);
|
onMount(focusTextarea);
|
||||||
unsubscribers.push(selectedChannel.on(focusTextarea));
|
unsubscribers.push(selectedChannel.watch(focusTextarea));
|
||||||
|
|
||||||
// Handle the setMessageInput event
|
// Handle the setMessageInput event
|
||||||
unsubscribers.push(setMessageInputEvent.on((value) => {
|
unsubscribers.push(setMessageInputEvent.watch((value) => {
|
||||||
messageInput = value;
|
messageInput = value;
|
||||||
if (messageTextarea) {
|
if (messageTextarea) {
|
||||||
messageTextarea.focus();
|
messageTextarea.focus();
|
||||||
|
|
|
@ -10,7 +10,6 @@ let storeCallbackQueue = [];
|
||||||
class Store {
|
class Store {
|
||||||
constructor(value=null, name="[no name]") {
|
constructor(value=null, name="[no name]") {
|
||||||
this._handlers = new Set();
|
this._handlers = new Set();
|
||||||
this._pipes = new Set();
|
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this._isInBatch = false;
|
this._isInBatch = false;
|
||||||
|
@ -21,7 +20,7 @@ class Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
// like subscribe, but without initially calling the handler
|
// like subscribe, but without initially calling the handler
|
||||||
on(handler) {
|
watch(handler) {
|
||||||
storeLog(`[Watch] (${this.name})`, "handler:", handler);
|
storeLog(`[Watch] (${this.name})`, "handler:", handler);
|
||||||
|
|
||||||
this._handlers.add(handler);
|
this._handlers.add(handler);
|
||||||
|
@ -43,16 +42,6 @@ class Store {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe(handler) {
|
|
||||||
storeLog(`[Pipe] (${this.name})`, "handler:", handler);
|
|
||||||
|
|
||||||
this._pipes.add(handler);
|
|
||||||
return () => {
|
|
||||||
storeLog(`[Remove Pipe] (${this.name})`);
|
|
||||||
this._pipes.delete(handler);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value === this.value)
|
if (value === this.value)
|
||||||
return;
|
return;
|
||||||
|
@ -62,7 +51,7 @@ class Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
// like set(), but without checking if the value is the same
|
// like set(), but without checking if the value is the same
|
||||||
emit(value) {
|
update(value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.updated();
|
this.updated();
|
||||||
}
|
}
|
||||||
|
@ -98,8 +87,6 @@ class Store {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.value = this._applyPipes(this.value);
|
|
||||||
|
|
||||||
storeLog(`[Update] (${this.name}) Will queue ${this._handlers.size} handlers`, "value:", this.value, "handlers:", this._handlers);
|
storeLog(`[Update] (${this.name}) Will queue ${this._handlers.size} handlers`, "value:", this.value, "handlers:", this._handlers);
|
||||||
|
|
||||||
const isRootNode = storeCallbackQueue.length === 0;
|
const isRootNode = storeCallbackQueue.length === 0;
|
||||||
|
@ -111,25 +98,12 @@ class Store {
|
||||||
this.flushCallbackQueue();
|
this.flushCallbackQueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_applyPipes(value) {
|
|
||||||
this._pipes.forEach(p => {
|
|
||||||
value = p(value);
|
|
||||||
});
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAction(name, handler) {
|
|
||||||
const store = new Store(null, name);
|
|
||||||
store.on(handler);
|
|
||||||
return store;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class StorageItemStore extends Store {
|
class StorageItemStore extends Store {
|
||||||
constructor(key) {
|
constructor(key) {
|
||||||
super(getItem(key), `StorageItemStore[key=${key}]`);
|
super(getItem(key), `StorageItemStore[key=${key}]`);
|
||||||
this.on(e => setItem(key, e));
|
this.watch(e => setItem(key, e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,40 +637,7 @@ 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 setMessageInputEvent = new Store(null, "event:setMessageInput");
|
export const setMessageInputEvent = new Store(null, "event:setMessageInput");
|
||||||
export const sendMessageAction = createAction("sendMessageAction", async ({channelId, content}) => {
|
|
||||||
if (content.trim() === "" || !userInfoStore.value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// optimistically add message to store
|
|
||||||
const optimisticMessageId = Math.floor(Math.random() * 999999);
|
|
||||||
const optimisticMessage = {
|
|
||||||
id: optimisticMessageId,
|
|
||||||
content: content,
|
|
||||||
channel_id: channelId,
|
|
||||||
author_id: userInfoStore.value.id,
|
|
||||||
author_username: userInfoStore.value.username,
|
|
||||||
created_at: Date.now().toString(),
|
|
||||||
_isPending: true
|
|
||||||
};
|
|
||||||
const messagesStoreForChannel = messagesStoreProvider.getStore(channelId);
|
|
||||||
messagesStoreForChannel.addMessage(optimisticMessage);
|
|
||||||
|
|
||||||
const res = await request("POST", apiRoute(`channels/${channelId}/messages`), true, {
|
|
||||||
content: optimisticMessage.content,
|
|
||||||
optimistic_id: optimisticMessageId
|
|
||||||
});
|
|
||||||
|
|
||||||
if (res.success && res.ok) {
|
|
||||||
messagesStoreForChannel.setMessage(optimisticMessageId, res.json);
|
|
||||||
} else {
|
|
||||||
messagesStoreForChannel.deleteMessage({
|
|
||||||
id: optimisticMessageId
|
|
||||||
});
|
|
||||||
overlayStore.toast("Couldn't send message");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export const allStores = {
|
export const allStores = {
|
||||||
selectedChannel,
|
selectedChannel,
|
||||||
|
@ -714,12 +655,10 @@ export const allStores = {
|
||||||
typingStore,
|
typingStore,
|
||||||
presenceStore,
|
presenceStore,
|
||||||
unreadStore,
|
unreadStore,
|
||||||
pluginStore,
|
|
||||||
setMessageInputEvent,
|
setMessageInputEvent,
|
||||||
sendMessageAction,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
selectedChannel.on((newSelectedChannel) => {
|
selectedChannel.watch((newSelectedChannel) => {
|
||||||
if (getItem("ui:stateful:presistSelectedChannel")) {
|
if (getItem("ui:stateful:presistSelectedChannel")) {
|
||||||
setItem("state:openChannelId", newSelectedChannel.id);
|
setItem("state:openChannelId", newSelectedChannel.id);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue