This commit is contained in:
metacryst
2026-04-28 20:05:00 -05:00
commit 0d6c7683ff
123 changed files with 20922 additions and 0 deletions

150
announcements/Panel.js Normal file
View File

@@ -0,0 +1,150 @@
import "/_/code/components/LoadingCircle.js"
css(`
panel- {
scrollbar-width: none;
-ms-overflow-style: none;
}
panel-::-webkit-scrollbar {
display: none;
width: 0px;
height: 0px;
}
panel-::-webkit-scrollbar-thumb {
background: transparent;
}
panel-::-webkit-scrollbar-track {
background: transparent;
}
`)
class Panel extends Shadow {
announcements = []
isSending = false
constructor(announcements) {
super()
this.announcements = announcements
}
render() {
VStack(() => {
if(this.announcements.length > 0) {
let previousDate = null
for(let i=0; i<this.announcements.length; i++) {
let announcement = this.announcements[i]
const isMe = announcement.creator_id === global.profile.id
const dateParts = this.parseDate(announcement.created);
const { date, time } = dateParts;
if (previousDate !== date) {
previousDate = date;
p(date)
.textAlign("center")
.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(() => {
h3(isMe ? "Me" : this.getAuthorName(announcement))
.color(isMe ? "var(--quillred)" : "var(--headertext")
.opacity(0.75)
.margin(0)
h3(`${date} ${time}`)
.opacity(0.5)
.color("var(--headertext)")
.margin(0)
.marginLeft(0.5, em)
.fontSize(1, em)
if (announcement.created !== announcement.updated_at) {
p("(edited)")
.color("var(--headertext)")
.letterSpacing(0.8, "px")
.opacity(0.5)
.fontWeight("bold")
.paddingLeft(0.25, em)
.fontSize(0.9, em)
}
})
.verticalAlign("center")
.marginBottom(0.1, em)
p(announcement.text)
.color("var(--text)")
.marginHorizontal(0.2, em)
.paddingVertical(0.2, em)
.boxSizing("border-box")
})
.marginBottom(0.05, em)
}
} else {
LoadingCircle()
}
})
.gap(1, em)
.fontSize(1.1, em)
.boxSizing("border-box")
.flex("1 1 auto")
.minHeight(0)
.overflowY("auto")
.width(100, pct)
.paddingBottom(2, em)
.paddingHorizontal(4, pct)
.backgroundColor("var(--main)")
.onAppear(async () => {
requestAnimationFrame(() => {
this.scrollTo({ top: 0, behavior: "smooth" });
});
})
}
getAuthorName(announcement) {
const members = global.currentNetwork.data.members;
const creator = members.find(m => m.id === announcement.creator_id);
if (creator) {
return `${creator.first_name} ${creator.last_name}`
} else {
return "No name"
}
}
parseDate(str) {
// Format: YYYY-MM-DDTHH:MM:SS.mmmZ
const match = str.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):\d{2}\.\d+Z$/);
if (!match) return null;
const [, yyyy, mm, dd, hh, min] = match;
// Convert 24h to 12h
const hour24 = parseInt(hh, 10);
const ampm = hour24 >= 12 ? 'pm' : 'am';
const hour12 = hour24 % 12 || 12;
const date = `${mm}/${dd}/${yyyy}`;
const time = `${hour12}:${min}${ampm}`;
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(Panel)