new announcements page, adding searchbar and message input.

This commit is contained in:
metacryst
2026-03-23 05:26:55 -05:00
parent 35f0fe3654
commit 881c9408b6
22 changed files with 809 additions and 423 deletions

View File

@@ -1,125 +1,176 @@
import './Panel.js'
import server from '../../_/code/bridge/serverFunctions.js'
import './Announcement.js'
import server from '../../_/code/bridge/server.js'
import '../../components/SearchBar.js'
css(`
announcements- {
font-family: 'Arial';
scrollbar-width: none;
-ms-overflow-style: none;
}
announcements- h1 {
font-family: 'Bona';
}
announcements- input::placeholder {
font-family: 'Bona Nova';
font-size: 0.9em;
color: var(--accent);
announcements- .VStack::-webkit-scrollbar {
display: none;
width: 0px;
height: 0px;
}
input::placeholder {
font-family: Arial;
announcements- .VStack::-webkit-scrollbar-thumb {
background: transparent;
}
input[type="checkbox"] {
appearance: none; /* remove default style */
-webkit-appearance: none;
width: 1em;
height: 1em;
border: 1px solid var(--accent);
}
input[type="checkbox"]:checked {
background-color: var(--red);
announcements- .VStack::-webkit-scrollbar-track {
background: transparent;
}
`)
class Announcements extends Shadow {
announcements;
static searchableKeys = ['message', 'author'];
constructor() {
super()
this.announcements = global.currentNetwork.data.announcements.sort((a, b) => new Date(b.created) - new Date(a.created));
console.log(this.announcements)
}
this.searchedAnnouncements = [];
this.searchText = "";
}
render() {
ZStack(() => {
VStack(() => {
SearchBar(this.searchText, "90vw")
Panel(this.announcements)
input("Message", "70%")
.paddingVertical(0.75, em)
.boxSizing("border-box")
.paddingHorizontal(2, em)
.color("var(--text)")
.background("var(--searchbackground)")
.marginBottom(1, em)
.border("0.5px solid var(--accent)")
.outline("none")
.borderRadius(100, px)
.fontFamily("Arial")
.fontSize(1, em)
.onKeyDown(async function(e) {
if (e.key === "Enter") {
const result = await server.addAnnouncement(this.value, global.currentNetwork.id, global.profile.id)
if (result.data.status === 200) {
window.dispatchEvent(new CustomEvent('new-announcement', {
detail: { announcement: result.data.announcement }
}));
} else {
// error
VStack(() => {
if (!this.announcements || this.announcements == []) {
LoadingCircle()
} else if (this.searchText) {
if (this.searchedAnnouncements.length > 0) {
for (let i = 0; i < this.searchedAnnouncements.length; i++) {
AnnouncementCard(this.searchedAnnouncements[i])
}
this.value = ""
} else {
h2("Could not find any announcements with your search criteria.")
.color("var(--divider)")
.fontWeight("bold")
.marginTop(7.5, em)
.marginBottom(0.5, em)
.textAlign("center")
}
} else if (this.announcements.length > 0) {
for (let i = 0; i < this.announcements.length; i++) {
AnnouncementCard(this.announcements[i])
}
} else {
h2("No Announcements")
.color("var(--divider)")
.fontWeight("bold")
.marginTop(7.5, em)
.marginBottom(0.5, em)
.textAlign("center")
}
})
.overflowY("scroll")
.gap(0.75, em)
if(global.currentNetwork.permissions.includes("announcements.add")) {
HStack(() => {
input("Image Upload", "0px", "0px")
.attr({ name: "image-upload", type: "file" })
.display("none")
.visibility("hidden")
.onChange((e) => {
this.handleUpload(e.target.files[0]);
})
div("+")
.width(3, rem)
.height(3, rem)
.borderRadius(50, pct)
.border("1px solid color-mix(in srgb, var(--accent) 60%, transparent)")
.fontSize(2, em)
.transform("rotate(180deg)")
.zIndex(1001)
.display("flex")
.alignItems("center")
.justifyContent("center")
.transition("scale .2s")
.state("touched", function (touched) {
if(touched) {
this.scale("1.5")
this.color("var(--darkaccent)")
this.backgroundColor("var(--divider)")
} else {
this.scale("")
this.color("var(--divider)")
this.backgroundColor("var(--searchbackground)")
}
})
.onTouch(function (start) {
if(start) {
this.attr({touched: "true"})
} else {
this.attr({touched: ""})
}
})
.onClick((done) => {
if(done) {
const inputSelector = this.$('[name="image-upload"]');
inputSelector.click()
}
})
input("Add an Announcement")
.flex("1 1 auto")
.minWidth(0)
.color("var(--text)")
.background("var(--searchbackground)")
.paddingVertical(0, rem)
.fontSize(1, rem)
.paddingHorizontal(1, rem)
.borderRadius(100, px)
.border("1px solid color-mix(in srgb, var(--accent) 60%, transparent)")
.onTouch(function (start) {
if (start) {
this.style.backgroundColor = "var(--accent)"
} else {
setTimeout(() => {
$("appmenu-").display("none")
}, 20)
console.log($("appmenu-"))
this.style.backgroundColor = "var(--searchbackground)"
}
})
.addEventListener("blur", () => {
setTimeout(() => {
$("appmenu-").display("grid")
}, 20)
})
})
.width(100, pct)
.boxSizing("border-box")
.position("absolute")
.paddingHorizontal(1, rem)
.bottom(1, vh)
.gap(0.5, rem)
}
})
.gap(1, em)
.boxSizing("border-box")
.width(100, pct)
.height(100, pct)
.horizontalAlign("center")
.verticalAlign("end")
.minHeight(0)
.width(100, pct)
.onEvent("announcementsearch", this.onAnnouncementSearch)
.onEvent("new-announcement", this.onNewAnnouncement)
.onEvent("deleted-announcement", this.onDeletedAnnouncement)
.onEvent("edited-announcement", this.onEditedAnnouncement)
})
.backgroundColor("var(--main)")
.boxSizing("border-box")
.paddingVertical(1, em)
.width(100, pct)
.height(100, pct)
.flex("1 1 auto")
.onEvent("new-announcement", this.onNewAnnouncement)
.onEvent("deleted-announcement", this.onDeletedAnnouncement)
.onEvent("edited-announcement", this.onEditedAnnouncement)
}
connectedCallback() {
this.getAnnouncements(global.currentNetwork.id)
}
checkForUpdates(currentAnnouncements, fetchedAnnouncements) {
if (currentAnnouncements.length !== fetchedAnnouncements.length) return true;
const currentMap = new Map(currentAnnouncements.map(ann => [ann.id, ann]));
for (const fetchedAnn of fetchedAnnouncements) {
const currentAnn = currentMap.get(fetchedAnn.id);
// new event added
if (!currentAnn) return true;
// existing event changed
if (currentAnn.updated_at !== fetchedAnn.updated_at) {
return true;
}
}
return false;
}
async getAnnouncements(networkId) {
const fetchedAnnouncements = await server.getAnnouncements(networkId)
if (this.checkForUpdates(this.announcements, fetchedAnnouncements.data)) {
console.log("found updates")
this.announcements = fetchedAnnouncements.data.sort((a, b) => new Date(b.created) - new Date(a.created));
global.currentNetwork.data.announcements = this.announcements
this.rerender()
}
addPhoto() {
console.log("hey")
}
onNewAnnouncement = (e) => {
@@ -138,13 +189,54 @@ class Announcements extends Shadow {
onEditedAnnouncement = (e) => {
let editedAnnouncement = e.detail
const i = this.announcements.findIndex(ann => ann.id === editedPost.id)
if (i !== -1) {
const i = this.announcements.findIndex(ann => ann.id === editedAnnouncement.id)
if (i !== -1) {
this.announcements.splice(i, 1)
this.announcements.unshift(editedAnnouncement)
}
this.rerender()
}
onAnnouncementSearch = (e) => {
let searchText = e.detail.searchText.toLowerCase().trim();
if (!searchText) {
this.searchedAnnouncements = [];
} else {
this.searchedAnnouncements = this.announcements.filter(announcement =>
Announcements.searchableKeys.some(key =>
String(announcement[key]).toLowerCase().includes(searchText)
)
);
}
this.searchText = searchText
this.rerender()
}
async getAnnouncements(networkId) {
const fetchedAnnouncements = await server.getAnnouncements(networkId)
if (this.checkForUpdates(this.announcements, fetchedAnnouncements.data)) {
this.announcements = fetchedAnnouncements.data.sort((a, b) => new Date(b.created) - new Date(a.created));
global.currentNetwork.data.announcements = this.announcements
this.rerender()
}
}
connectedCallback() {
this.getAnnouncements(global.currentNetwork.id)
}
checkForUpdates(currentAnnouncements, fetchedAnnouncements) {
if (currentAnnouncements.length !== fetchedAnnouncements.length) return true;
const currentMap = new Map(currentAnnouncements.map(ann => [ann.id, ann]));
for (const fetchedAnn of fetchedAnnouncements) {
const currentAnn = currentMap.get(fetchedAnn.id);
if (!currentAnn) return true;
if (currentAnn.updated_at !== fetchedAnn.updated_at) return true;
}
return false;
}
}
register(Announcements)