Forum changes
- Added 2 new svg icons - Fixed visual styling bugs on Forum page involving overflowing containers - Added current network name underneath "Forum" title - Input in Forum.js now sends ws message to server with new post, which is then broadcasted through the ws - Forum app now displays a list of posts for the current network showing the author, time, text, whether it's been edited, and whether it's yours - ForumPanel.js .onClick() contains the ws calls for DELETE and PUT - Fixed bug where Forum would not scroll to top upon a new post/onAppear - Modified ws GET call in ForumPanel.js to reflect new format - Added .onEvent() handlers inForumPanel.js for "new-post", "deleted-post", and "edited-post" - Changed AppMenu People icon -
This commit is contained in:
@@ -45,6 +45,7 @@ class Home extends Shadow {
|
||||
AppMenu()
|
||||
})
|
||||
.height(100, pct)
|
||||
.minHeight(0)
|
||||
.onNavigate(() => {
|
||||
console.log("navigate")
|
||||
this.rerender()
|
||||
|
||||
24
src/_/icons/people.svg
Normal file
24
src/_/icons/people.svg
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
|
||||
<svg width="100px" height="100px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" fill="#000000">
|
||||
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
||||
|
||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
|
||||
<g id="SVGRepo_iconCarrier">
|
||||
|
||||
<title>ionicons-v5-j</title>
|
||||
|
||||
<path d="M402,168c-2.93,40.67-33.1,72-66,72s-63.12-31.32-66-72c-3-42.31,26.37-72,66-72S405,126.46,402,168Z" style="fill:none;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/>
|
||||
|
||||
<path d="M336,304c-65.17,0-127.84,32.37-143.54,95.41-2.08,8.34,3.15,16.59,11.72,16.59H467.83c8.57,0,13.77-8.25,11.72-16.59C463.85,335.36,401.18,304,336,304Z" style="fill:none;stroke:#000000;stroke-miterlimit:10;stroke-width:32px"/>
|
||||
|
||||
<path d="M200,185.94C197.66,218.42,173.28,244,147,244S96.3,218.43,94,185.94C91.61,152.15,115.34,128,147,128S202.39,152.77,200,185.94Z" style="fill:none;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/>
|
||||
|
||||
<path d="M206,306c-18.05-8.27-37.93-11.45-59-11.45-52,0-102.1,25.85-114.65,76.2C30.7,377.41,34.88,384,41.72,384H154" style="fill:none;stroke:#000000;stroke-linecap:round;stroke-miterlimit:10;stroke-width:32px"/>
|
||||
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
src/_/icons/trash.svg
Normal file
1
src/_/icons/trash.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><path d="M 20.5 4 A 1.50015 1.50015 0 0 0 19.066406 6 L 14.640625 6 C 12.803372 6 11.082924 6.9194511 10.064453 8.4492188 L 7.6972656 12 L 7.5 12 A 1.50015 1.50015 0 1 0 7.5 15 L 8.2636719 15 A 1.50015 1.50015 0 0 0 8.6523438 15.007812 L 11.125 38.085938 C 11.423352 40.868277 13.795836 43 16.59375 43 L 31.404297 43 C 34.202211 43 36.574695 40.868277 36.873047 38.085938 L 39.347656 15.007812 A 1.50015 1.50015 0 0 0 39.728516 15 L 40.5 15 A 1.50015 1.50015 0 1 0 40.5 12 L 40.302734 12 L 37.935547 8.4492188 C 36.916254 6.9202798 35.196001 6 33.359375 6 L 28.933594 6 A 1.50015 1.50015 0 0 0 27.5 4 L 20.5 4 z M 14.640625 9 L 33.359375 9 C 34.196749 9 34.974746 9.4162203 35.439453 10.113281 L 36.697266 12 L 11.302734 12 L 12.560547 10.113281 A 1.50015 1.50015 0 0 0 12.5625 10.111328 C 13.025982 9.4151428 13.801878 9 14.640625 9 z M 11.669922 15 L 36.330078 15 L 33.890625 37.765625 C 33.752977 39.049286 32.694383 40 31.404297 40 L 16.59375 40 C 15.303664 40 14.247023 39.049286 14.109375 37.765625 L 11.669922 15 z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -29,18 +29,24 @@ css(`
|
||||
`)
|
||||
|
||||
class Forum extends Shadow {
|
||||
|
||||
selectedForum = "HY"
|
||||
|
||||
render() {
|
||||
ZStack(() => {
|
||||
VStack(() => {
|
||||
h1("Forum")
|
||||
.color("var(--quillred)")
|
||||
.textAlign("center")
|
||||
.marginBottom(0)
|
||||
h3(global.currentNetwork.name)
|
||||
.color("var(--quillred)")
|
||||
.textAlign("center")
|
||||
.margin(0)
|
||||
|
||||
ForumPanel()
|
||||
|
||||
input("Message", "70%")
|
||||
.paddingVertical(0.75, em)
|
||||
.paddingLeft(2, em)
|
||||
.boxSizing("border-box")
|
||||
.paddingHorizontal(2, em)
|
||||
.color("var(--accent)")
|
||||
.background("#fff1dd")
|
||||
.marginBottom(5.5, em)
|
||||
@@ -48,9 +54,17 @@ class Forum extends Shadow {
|
||||
.borderRadius(100, px)
|
||||
.fontFamily("Arial")
|
||||
.fontSize(1, em)
|
||||
.onKeyDown(function (e) {
|
||||
.onKeyDown(async function(e) {
|
||||
if (e.key === "Enter") {
|
||||
window.Socket.send({app: "FORUM", operation: "SEND", msg: {forum: "HY", text: this.value }})
|
||||
let msg = {
|
||||
forum: global.currentNetwork.abbreviation,
|
||||
text: this.value
|
||||
}
|
||||
await global.Socket.send({
|
||||
app: "FORUM",
|
||||
operation: "SEND",
|
||||
msg: msg
|
||||
})
|
||||
this.value = ""
|
||||
}
|
||||
})
|
||||
@@ -61,11 +75,14 @@ class Forum extends Shadow {
|
||||
.height(100, pct)
|
||||
.horizontalAlign("center")
|
||||
.verticalAlign("end")
|
||||
.minHeight(0)
|
||||
})
|
||||
.backgroundColor("var(--main)")
|
||||
.boxSizing("border-box")
|
||||
.paddingVertical(1, em)
|
||||
.width(100, pct)
|
||||
.height(100, pct)
|
||||
.minHeight(0)
|
||||
.flex("1 1 auto")
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,38 @@
|
||||
import "../../components/LoadingCircle.js"
|
||||
|
||||
css(`
|
||||
forumpanel- {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
forumpanel-::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
forumpanel-::-webkit-scrollbar-thumb {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
forumpanel-::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
`)
|
||||
|
||||
class ForumPanel extends Shadow {
|
||||
forums = [
|
||||
"HY"
|
||||
]
|
||||
messages = []
|
||||
isSending = false
|
||||
|
||||
render() {
|
||||
VStack(() => {
|
||||
if(this.messages.length > 0) {
|
||||
|
||||
let previousDate = null
|
||||
|
||||
for(let i=0; i<this.messages.length; i++) {
|
||||
let message = this.messages[i]
|
||||
const isMe = message.authorId === global.profile.id
|
||||
const dateParts = this.parseDate(message.time);
|
||||
const { date, time } = dateParts;
|
||||
|
||||
@@ -22,22 +41,64 @@ class ForumPanel extends Shadow {
|
||||
|
||||
p(date)
|
||||
.textAlign("center")
|
||||
.opacity(0.5)
|
||||
.marginVertical(1, em)
|
||||
.color("var(--divider)")
|
||||
.opacity(0.6)
|
||||
.fontWeight("bold")
|
||||
.paddingTop(1, em)
|
||||
.paddingBottom(0.5, em)
|
||||
.color("var(--quillred)")
|
||||
.borderTop(`1px solid var(--${i == 0 ? "transparent" : "divider"})`)
|
||||
}
|
||||
|
||||
VStack(() => {
|
||||
HStack(() => {
|
||||
p(message.sentBy)
|
||||
.fontWeight("bold")
|
||||
.marginBottom(0.3, em)
|
||||
h3(isMe ? "Me" : message.sentBy)
|
||||
.color(isMe ? "var(--quillred)" : "var(--brown")
|
||||
.margin(0)
|
||||
|
||||
p(util.formatTime(message.time))
|
||||
.opacity(0.2)
|
||||
.marginLeft(1, em)
|
||||
h3(`${date} ${time}`)
|
||||
.opacity(0.5)
|
||||
.color("var(--brown)")
|
||||
.margin(0)
|
||||
.marginLeft(0.5, em)
|
||||
.fontSize(1, em)
|
||||
|
||||
if (message.edited) {
|
||||
p("(edited)")
|
||||
.color("var(--brown)")
|
||||
.letterSpacing(0.8, "px")
|
||||
.opacity(0.8)
|
||||
.fontWeight("bold")
|
||||
.paddingLeft(0.25, em)
|
||||
.fontSize(0.9, em)
|
||||
}
|
||||
})
|
||||
.verticalAlign("center")
|
||||
.marginBottom(0.1, em)
|
||||
|
||||
p(message.text)
|
||||
.color("var(--accent)")
|
||||
.borderLeft("1.5px solid var(--divider)")
|
||||
.borderBottomLeftRadius("7.5px")
|
||||
.paddingLeft(0.5, em)
|
||||
.marginHorizontal(0.2, em)
|
||||
.paddingVertical(0.2, em)
|
||||
.boxSizing("border-box")
|
||||
})
|
||||
.marginBottom(0.05, em)
|
||||
.onClick(async (finished, e) => {
|
||||
if (finished) {
|
||||
console.log(message.id)
|
||||
let msg = {
|
||||
forum: global.currentNetwork.abbreviation,
|
||||
id: message.id,
|
||||
text: "EDITED TEXT TEST!"
|
||||
}
|
||||
await global.Socket.send({
|
||||
app: "FORUM",
|
||||
operation: "PUT",
|
||||
msg: msg
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@@ -45,31 +106,68 @@ class ForumPanel extends Shadow {
|
||||
}
|
||||
})
|
||||
.gap(1, em)
|
||||
.fontSize(1.1, em)
|
||||
.boxSizing("border-box")
|
||||
.position("relative")
|
||||
.overflow("scroll")
|
||||
.height(100, pct)
|
||||
.width(96, pct)
|
||||
.paddingTop(5, em)
|
||||
.flex("1 1 auto")
|
||||
.minHeight(0)
|
||||
.overflowY("auto")
|
||||
.width(100, pct)
|
||||
.paddingBottom(2, em)
|
||||
.paddingLeft(4, pct)
|
||||
.paddingHorizontal(4, pct)
|
||||
.backgroundColor("var(--main)")
|
||||
.onAppear(async () => {
|
||||
requestAnimationFrame(() => {
|
||||
this.scrollTop = this.scrollHeight
|
||||
this.scrollTo({ top: 0, behavior: "smooth" });
|
||||
});
|
||||
let res = await global.Socket.send({app: "FORUM", operation: "GET", msg: {forum: "HY", number: 100}})
|
||||
if(!res) console.error("failed to get messages")
|
||||
if(res.msg.length > 0 && this.messages.length === 0) {
|
||||
this.messages = res.msg
|
||||
this.rerender()
|
||||
}
|
||||
window.addEventListener("new-post", (e) => {
|
||||
this.messages = e.detail
|
||||
if(e.detail.length !== this.messages || e.detail.last.time !== this.messages.last.time || e.detail.first.time !== this.messages.first.time) {
|
||||
if (!this.isSending) {
|
||||
this.isSending = true
|
||||
let res = await global.Socket.send({
|
||||
app: "FORUM",
|
||||
operation: "GET",
|
||||
msg: {
|
||||
forum: global.currentNetwork.abbreviation,
|
||||
by: "network",
|
||||
authorId: -999 // default
|
||||
}
|
||||
})
|
||||
if(!res) console.error("failed to get messages")
|
||||
if(res.msg.length > 0 && this.messages.length === 0) {
|
||||
this.messages = res.msg.reverse()
|
||||
this.rerender()
|
||||
}
|
||||
})
|
||||
this.isSending = false
|
||||
}
|
||||
})
|
||||
.onEvent("new-post", this.onNewPost)
|
||||
.onEvent("deleted-post", this.onDeletedPost)
|
||||
.onEvent("edited-post", this.onEditedPost)
|
||||
}
|
||||
|
||||
onNewPost = (e) => {
|
||||
let newPost = e.detail
|
||||
if (this.messages && !this.messages.some(post => post.id === newPost.id)) {
|
||||
this.messages.unshift(newPost)
|
||||
this.rerender()
|
||||
}
|
||||
}
|
||||
|
||||
onDeletedPost = (e) => {
|
||||
let deletedId = e.detail
|
||||
const i = this.messages.findIndex(post => post.id === deletedId)
|
||||
if (i !== -1) this.messages.splice(i, 1);
|
||||
this.rerender()
|
||||
}
|
||||
|
||||
onEditedPost = (e) => {
|
||||
let editedPost = e.detail
|
||||
const i = this.messages.findIndex(post => post.id === editedPost.id)
|
||||
if (i !== -1) {
|
||||
this.messages.splice(i, 1)
|
||||
this.messages.unshift(editedPost)
|
||||
}
|
||||
|
||||
this.rerender()
|
||||
}
|
||||
|
||||
parseDate(str) {
|
||||
@@ -83,6 +181,14 @@ class ForumPanel extends Shadow {
|
||||
|
||||
return { date, time };
|
||||
}
|
||||
|
||||
formatTime(str) {
|
||||
const match = str.match(/-(\d+:\d+):\d+.*(am|pm)/i);
|
||||
if (!match) return null;
|
||||
|
||||
const [_, hourMin, ampm] = match;
|
||||
return hourMin + ampm.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
register(ForumPanel)
|
||||
@@ -38,7 +38,7 @@ class AppMenu extends Shadow {
|
||||
window.navigateTo("/messages")
|
||||
}
|
||||
})
|
||||
img("/_/icons/jobs.svg", "1.5em", "1.5em")
|
||||
img("/_/icons/people.svg", "1.5em", "1.5em")
|
||||
.attr({app: "people"})
|
||||
.padding(0.5, em)
|
||||
.borderRadius(10, px)
|
||||
@@ -61,6 +61,7 @@ class AppMenu extends Shadow {
|
||||
.paddingVertical(1, em)
|
||||
.width(100, vw)
|
||||
.boxSizing("border-box")
|
||||
.flex("0 0 auto")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user