271 lines
10 KiB
JavaScript
271 lines
10 KiB
JavaScript
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- .VStack::-webkit-scrollbar {
|
|
display: none;
|
|
width: 0px;
|
|
height: 0px;
|
|
}
|
|
|
|
announcements- .VStack::-webkit-scrollbar-thumb {
|
|
background: transparent;
|
|
}
|
|
|
|
announcements- .VStack::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
`)
|
|
|
|
class Announcements extends Shadow {
|
|
static searchableKeys = ['message', 'author'];
|
|
|
|
constructor() {
|
|
super()
|
|
this.announcements = global.currentNetwork.data.announcements.sort((a, b) => new Date(b.created) - new Date(a.created));
|
|
this.searchedAnnouncements = [];
|
|
this.searchText = "";
|
|
}
|
|
|
|
render() {
|
|
ZStack(() => {
|
|
|
|
VStack(() => {
|
|
SearchBar(this.searchText, "90vw")
|
|
|
|
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])
|
|
}
|
|
} 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) => {
|
|
const file = e.target.files[0]
|
|
if (!file) return
|
|
this.stagedImage = file
|
|
this.stagedImageURL = URL.createObjectURL(file)
|
|
this.rerender()
|
|
})
|
|
|
|
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")
|
|
this.focus()
|
|
}, 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)
|
|
}
|
|
})
|
|
.boxSizing("border-box")
|
|
.height(100, pct)
|
|
.width(100, pct)
|
|
.onEvent("announcementsearch", this.onAnnouncementSearch)
|
|
.onEvent("new-announcement", this.onNewAnnouncement)
|
|
.onEvent("deleted-announcement", this.onDeletedAnnouncement)
|
|
.onEvent("edited-announcement", this.onEditedAnnouncement)
|
|
})
|
|
}
|
|
|
|
async handleUpload(file) {
|
|
try {
|
|
const body = new FormData();
|
|
body.append('image', file);
|
|
const res = await util.authFetch(`${util.HOST}/profile/upload-image`, {
|
|
method: "POST",
|
|
credentials: "include",
|
|
headers: {
|
|
"Accept": "application/json"
|
|
},
|
|
body: body
|
|
});
|
|
|
|
if(res.status === 401) {
|
|
return res.status
|
|
}
|
|
if (!res.ok) return res.status;
|
|
const data = await res.json()
|
|
global.profile = data.member
|
|
console.log(global.profile)
|
|
} catch (err) { // Network error / Error reaching server
|
|
console.error(err);
|
|
}
|
|
}
|
|
|
|
addPhoto() {
|
|
console.log("hey")
|
|
}
|
|
|
|
onNewAnnouncement = (e) => {
|
|
let newAnnouncement = e.detail.announcement;
|
|
this.announcements.push(newAnnouncement)
|
|
this.announcements.sort((a, b) => new Date(b.created) - new Date(a.created));
|
|
this.rerender()
|
|
}
|
|
|
|
onDeletedAnnouncement = (e) => {
|
|
let deletedId = e.detail.id
|
|
const i = this.announcements.findIndex(ann => ann.id === deletedId)
|
|
if (i !== -1) this.announcements.splice(i, 1);
|
|
this.rerender()
|
|
}
|
|
|
|
onEditedAnnouncement = (e) => {
|
|
let editedAnnouncement = e.detail
|
|
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) |