Skip to content

Commit

Permalink
work on creating channels
Browse files Browse the repository at this point in the history
  • Loading branch information
targoninc-alex committed May 28, 2024
1 parent 748f74b commit ab5e509
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 7 deletions.
2 changes: 1 addition & 1 deletion main.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ app.get('*', (req, res) => {
});

app.listen(process.env.PORT || 3001, () => {
console.log(`Server running on port ${process.env.PORT || 3001}`);
console.log(`Server running on port http://localhost:${process.env.PORT || 3001}/`);
});
21 changes: 21 additions & 0 deletions ui/actions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,25 @@ export function toast(message, type = "info", timeout = 5) {
setTimeout(() => {
toast.remove();
}, timeout * 10000);
}

export function popup(popup, classes = []) {
const container = create("div")
.classes("popup-container", ...classes)
.children(popup)
.build();

Page.popups.appendChild(container);

setTimeout(() => {
document.addEventListener("click", (event) => {
if (!container.contains(event.target)) {
container.remove();
}
}, {once: true});
}, 10);
}

export function removePopups() {
Page.popups.innerHTML = "";
}
3 changes: 3 additions & 0 deletions ui/api/Api.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,7 @@ export class Api extends ApiBase {
static async url() {
return await this.get("/api/live/url", {});
}
static async search(query = null) {
return await this.get("/api/users/search", {query});
}
}
34 changes: 34 additions & 0 deletions ui/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ button, input, textarea, select {
height: max-content;
}

button.no-border, input.no-border, textarea.no-border, select.no-border {
border: none;
background: transparent;
}

button.positive, input.positive, textarea.positive, select.positive {
border: var(--input-border-width) solid var(--green);
color: var(--green);
Expand Down Expand Up @@ -170,6 +175,35 @@ button:hover {
z-index: 999;
}

#popups {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
justify-content: center;
align-items: center;
z-index: 999;
display: none;
}

#popups:has(.popup-container) {
display: flex;
}

.popup-container {
background: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
z-index: 999;
}

.toast {
background: var(--bg-4);
border: 1px solid var(--bg-3);
Expand Down
8 changes: 8 additions & 0 deletions ui/classes.css
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@
align-items: center;
}

.self-end {
align-self: end;
}

.card, .main-card {
padding: calc(var(--gap-v) * 2);
background: var(--bg-2);
Expand Down Expand Up @@ -242,4 +246,8 @@

.message-content:hover {
background: var(--bg-2);
}

.close-button {
align-self: end;
}
38 changes: 38 additions & 0 deletions ui/components/common.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,19 @@ export class CommonTemplates {
).build();
}

static chatWithButton(username, onclick) {
return create("button")
.classes("flex", "align-center", "small-gap", "full-width", "space-between")
.onclick(onclick)
.children(
CommonTemplates.icon("chat"),
create("span")
.classes("bold")
.text(username)
.build(),
).build();
}

static input(type, id, label, placeholder, value, onchange, required = true, autocomplete = "off", onkeydown = () => {}) {
return create("div")
.classes("flex-v", "small-gap")
Expand All @@ -118,6 +131,31 @@ export class CommonTemplates {
).build();
}

static responsiveInput(type, id, label, placeholder, value, oninput, required = true, autocomplete = "off", onkeydown = () => {}) {
return create("div")
.classes("flex-v", "small-gap")
.children(
create("label")
.for(id)
.text(label)
.build(),
create("input")
.type(type)
.id(id)
.placeholder(placeholder)
.value(value)
.oninput(oninput)
.onkeydown((e) => {
if (e.key === "Enter") {
e.preventDefault();
onkeydown(e);
}
})
.autocomplete(autocomplete)
.build()
).build();
}

static error(message) {
return create("span")
.classes("error")
Expand Down
54 changes: 48 additions & 6 deletions ui/components/pages/chat.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import {LayoutTemplates} from "../layout.mjs";
import {Store} from "../../api/Store.mjs";
import {CommonTemplates} from "../common.mjs";
import {Api} from "../../api/Api.mjs";
import {toast} from "../../actions.mjs";
import {addMessage, Hooks, removeMessage} from "../../api/Hooks.mjs";
import {popup, removePopups, toast} from "../../actions.mjs";
import {Hooks, removeMessage} from "../../api/Hooks.mjs";
import {Time} from "../../tooling/Time.mjs";
import {Live} from "../../live/Live.mjs";
import {PopupComponents} from "../popup.mjs";

export class ChatComponent {
static render() {
Expand All @@ -31,7 +32,7 @@ export class ChatComponent {
return create("div")
.classes("panes-v", "full-width", "full-height")
.children(
ChatComponent.actions(user),
ChatComponent.actions(user, channels),
create("div")
.classes("panes", "full-width", "flex-grow")
.children(
Expand Down Expand Up @@ -117,14 +118,55 @@ export class ChatComponent {
}, sending, ["rounded-max", "double"]);
}

static actions(user) {
static actions(user, channels) {
const userSearchResults = signal([]);

return create("div")
.classes("flex", "align-center", "full-width")
.classes("flex", "align-center", "full-width", "space-between")
.children(
CommonTemplates.buttonWithIcon("person_add", "New DM", () => {
popup(PopupComponents.searchPopup(() => {
removePopups();
}, (e) => {
const query = e.target.value;
if (query.length < 3) {
userSearchResults.value = [];
return;
}

Api.search(query).then((res) => {
if (res.status !== 200) {
toast("Failed to search for users", "error");
return;
}
userSearchResults.value = res.data.filter(user => {
return !channels.value.some(channel => {
return channel.type === "dm" && channel.members.some(member => member.id === user.id);
});
});
})
}, () => {}, userSearchResults, (result) => {
return CommonTemplates.chatWithButton(result.username, () => {
Api.createDirect(result.id).then((res) => {
if (res.status !== 200) {
toast("Failed to create DM", "error");
removePopups();
return;
}
toast("DM created", "success");
Live.send({
type: "createChannel",
channelId: res.data.id,
});
removePopups();
});
});
}, "New DM", "Search for users"));
}),
create("div")
.classes("padded")
.children(
CommonTemplates.userInList("face_5", user.displayname, user.username, () => {})
CommonTemplates.userInList("face_5", user.displayname ?? user.displayname, user.username, () => {})
).build(),
CommonTemplates.pageLink("Logout", "logout")
).build();
Expand Down
57 changes: 57 additions & 0 deletions ui/components/popup.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {create, ifjs, signalMap} from "https://fjs.targoninc.com/f.js";
import {CommonTemplates} from "./common.mjs";

export class PopupComponents {
static popup(content, classes = []) {
return create("div")
.classes(...classes)
.children(
create("div")
.classes("popup-content")
.children(content)
.build()
).build();
}

static searchPopup(onclose, onsearch, onselect, searchResults, renderResult = (result) => PopupComponents.searchResult(result, onselect), title = "Search", inputLabel = "", classes = []) {
return create("div")
.classes("card", ...classes)
.children(
create("div")
.classes("flex-v")
.children(
create("div")
.classes("flex", "space-between")
.children(
ifjs(title, create("h3").text(title).build()),
PopupComponents.closeButton(onclose),
).build(),
CommonTemplates.responsiveInput("text", "search", inputLabel, inputLabel, "", onsearch),
ifjs(searchResults, signalMap(searchResults,
create("div")
.classes("flex-v"),
renderResult
)),
ifjs(searchResults, create("div")
.classes("no-results")
.text("No results found")
.build(), true),
).build()
).build();
}

static closeButton(onclose) {
return CommonTemplates.buttonWithIcon("close", "Close", onclose, ["no-border", "self-end"])
}

static searchResult(result, onselect) {
return create("div")
.classes("search-result")
.onclick(() => onselect(result))
.children(
create("span")
.text(result)
.build()
).build();
}
}
11 changes: 11 additions & 0 deletions ui/routing/Page.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,24 @@ export class Page {
}
}

static get popups() {
const popups = document.getElementById("popups");
if (!popups) {
Page.initialize();
return Page.popups;
} else {
return popups;
}
}

static empty() {
Page.container.innerHTML = "";
Page.initialize();
}

static initialize() {
Page.container.appendChild(create("div").id("toasts").build());
Page.container.appendChild(create("div").id("popups").build());
}

static load(page, params, router) {
Expand Down

0 comments on commit ab5e509

Please sign in to comment.