166 lines
6.6 KiB
JavaScript
166 lines
6.6 KiB
JavaScript
import server from "/people/@server/index.js"
|
|
import "./PeopleList.js"
|
|
|
|
class People extends Shadow {
|
|
searchText = ""
|
|
filterOnline = false
|
|
listEl = null
|
|
|
|
get people() { return this._people }
|
|
set people(val) {
|
|
this._people = val
|
|
global.currentNetwork.data.members = val
|
|
}
|
|
|
|
constructor() {
|
|
super()
|
|
this._people = (global.currentNetwork.data.members || []).map(p => ({ ...p, _online: this.isOnline(p) }))
|
|
}
|
|
|
|
isOnline(member) {
|
|
return global.socket.connectedUsers.includes(member.email)
|
|
}
|
|
|
|
get filtered() {
|
|
let list = this.people
|
|
if (this.filterOnline) list = list.filter(p => p._online)
|
|
if (this.searchText) {
|
|
const q = this.searchText.toLowerCase()
|
|
list = list.filter(p =>
|
|
[p.first_name, p.last_name, p.email]
|
|
.some(v => v?.toLowerCase().includes(q))
|
|
)
|
|
}
|
|
return list
|
|
}
|
|
|
|
get onlineCount() {
|
|
return this.people.filter(p => p._online).length
|
|
}
|
|
|
|
render() {
|
|
VStack(() => {
|
|
// ── Header ────────────────────────────────────────────────
|
|
VStack(() => {
|
|
HStack(() => {
|
|
VStack(() => {
|
|
|
|
HStack(() => {
|
|
p(`${this.people.length} total`)
|
|
.margin(0)
|
|
.fontSize(0.72, em)
|
|
.color("var(--headertext)")
|
|
.opacity(0.4)
|
|
|
|
if (this.onlineCount > 0) {
|
|
HStack(() => {
|
|
VStack(() => {})
|
|
.width(6, px)
|
|
.height(6, px)
|
|
.borderRadius(50, pct)
|
|
.background("#10b981")
|
|
.flexShrink(0)
|
|
p(`${this.onlineCount} online`)
|
|
.margin(0)
|
|
.fontSize(0.72, em)
|
|
.color("#10b981")
|
|
.fontWeight("600")
|
|
})
|
|
.gap(0.3, em)
|
|
.alignItems("center")
|
|
}
|
|
})
|
|
.gap(0.65, em)
|
|
.alignItems("center")
|
|
.marginTop(0.2, em)
|
|
})
|
|
.gap(0)
|
|
.flex(1)
|
|
|
|
// Online filter pill
|
|
if (this.people.length > 0) {
|
|
HStack(() => {
|
|
VStack(() => {})
|
|
.width(7, px)
|
|
.height(7, px)
|
|
.borderRadius(50, pct)
|
|
.background(this.filterOnline ? "#10b981" : "var(--headertext)")
|
|
.opacity(this.filterOnline ? 1 : 0.3)
|
|
.flexShrink(0)
|
|
p("Online")
|
|
.margin(0)
|
|
.fontSize(0.75, em)
|
|
.fontWeight(this.filterOnline ? "600" : "400")
|
|
.color("var(--headertext)")
|
|
.opacity(this.filterOnline ? 1 : 0.45)
|
|
})
|
|
.gap(0.35, em)
|
|
.alignItems("center")
|
|
.paddingHorizontal(0.75, em)
|
|
.paddingVertical(0.35, em)
|
|
.background(this.filterOnline ? "rgba(16,185,129,0.12)" : "var(--darkaccent)")
|
|
.border(`1px solid ${this.filterOnline ? "rgba(16,185,129,0.4)" : "var(--divider)"}`)
|
|
.borderRadius(100, px)
|
|
.cursor("pointer")
|
|
.onTap(() => { this.filterOnline = !this.filterOnline; this.rerender() })
|
|
}
|
|
})
|
|
.alignItems("flex-start")
|
|
.marginBottom(0.75, em)
|
|
|
|
// Search bar
|
|
HStack(() => {
|
|
p("🔍")
|
|
.margin(0)
|
|
.fontSize(0.75, em)
|
|
.opacity(0.4)
|
|
.flexShrink(0)
|
|
input("Search members…", "100%")
|
|
.border("none")
|
|
.background("transparent")
|
|
.color("var(--headertext)")
|
|
.fontSize(0.88, em)
|
|
.outline("none")
|
|
.flex(1)
|
|
.attr({ value: this.searchText })
|
|
.onInput(e => {
|
|
this.searchText = e.target.value
|
|
this.listEl._members = this.filtered
|
|
this.listEl.rerender()
|
|
})
|
|
})
|
|
.gap(0.5, em)
|
|
.paddingHorizontal(0.75, em)
|
|
.paddingVertical(0.55, em)
|
|
.background("var(--darkaccent)")
|
|
.border("1px solid var(--divider)")
|
|
.borderRadius(0.55, em)
|
|
.alignItems("center")
|
|
})
|
|
.paddingHorizontal(1, em)
|
|
.paddingTop(1.25, em)
|
|
.paddingBottom(0.85, em)
|
|
.flexShrink(0)
|
|
|
|
// ── Divider ───────────────────────────────────────────────
|
|
VStack(() => {}).height(1, px).background("var(--divider)").flexShrink(0)
|
|
|
|
// ── List ──────────────────────────────────────────────────
|
|
this.listEl = PeopleList(this.filtered, global.appRefreshing || this.people.length === 0)
|
|
})
|
|
.height(100, pct)
|
|
.width(100, pct)
|
|
.boxSizing("border-box")
|
|
.overflow("hidden")
|
|
.onAppear(async () => {
|
|
const res = await server.getPeople(global.currentNetwork.id)
|
|
if (!res.error && res.length > 0 && this.people.length !== res.length) {
|
|
this.people = res.map(p => ({ ...p, _online: this.isOnline(p) }))
|
|
this.rerender()
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
register(People)
|