diff --git a/src/webpage/channel.ts b/src/webpage/channel.ts
index 4a97edc..6883d55 100644
--- a/src/webpage/channel.ts
+++ b/src/webpage/channel.ts
@@ -330,6 +330,7 @@ class Channel extends SnowFlake {
this.readbottom.bind(this),
);
}
+ last_pin_timestamp?: string;
constructor(json: channeljson | -1, owner: Guild, id: string = json === -1 ? "" : json.id) {
super(id);
if (json === -1) {
@@ -401,6 +402,61 @@ class Channel extends SnowFlake {
get info() {
return this.owner.info;
}
+ pinnedMessages?: Message[];
+ async pinnedClick(rect: DOMRect) {
+ const div = document.createElement("div");
+ div.classList.add("flexttb", "pinnedMessages");
+ div.style.top = rect.bottom + 20 + "px";
+ div.style.right = window.innerWidth - rect.right + "px";
+ document.body.append(div);
+ Contextmenu.keepOnScreen(div);
+ if (Contextmenu.currentmenu !== "") {
+ Contextmenu.currentmenu.remove();
+ }
+ this.last_pin_timestamp = this.lastpin;
+ const l = (e: MouseEvent) => {
+ if (e.target instanceof HTMLElement && div.contains(e.target)) {
+ return;
+ }
+ div.remove();
+ document.removeEventListener("click", l);
+ };
+ document.addEventListener("mouseup", l);
+ if (!this.pinnedMessages) {
+ const pinnedM = (await (
+ await fetch(`${this.info.api}/channels/${this.id}/pins`, {headers: this.headers})
+ ).json()) as messagejson[];
+ this.pinnedMessages = pinnedM.map((_) => {
+ if (this.messages.has(_.id)) {
+ return this.messages.get(_.id) as Message;
+ } else {
+ return new Message(_, this);
+ }
+ });
+ }
+ const pinnedM = document.getElementById("pinnedMDiv");
+ if (pinnedM) {
+ pinnedM.classList.remove("unreadPin");
+ }
+ if (this.pinnedMessages.length === 0) {
+ const b = document.createElement("b");
+ b.textContent = I18n.noPins();
+ div.append(b);
+ return;
+ }
+ div.append(
+ ...this.pinnedMessages.map((_) => {
+ const html = _.buildhtml(undefined, true);
+ html.style.cursor = "pointer";
+ html.onclick = async () => {
+ div.remove();
+ await this.focus(_.id);
+ };
+ Message.contextmenu.bindContextmenu(html, _);
+ return html;
+ }),
+ );
+ }
readStateInfo(json: readyjson["d"]["read_state"]["entries"][0]) {
const next = this.messages.get(this.idToNext.get(this.lastreadmessageid as string) as string);
this.lastreadmessageid = json.last_message_id;
@@ -927,7 +983,19 @@ class Channel extends SnowFlake {
html.classList.add("messagecontainer");
messages.append(html);
}
+ unreadPins() {
+ if (!this.last_pin_timestamp && !this.lastpin) return false;
+ return this.last_pin_timestamp !== this.lastpin;
+ }
async getHTML(addstate = true) {
+ const pinnedM = document.getElementById("pinnedMDiv");
+ if (pinnedM) {
+ if (this.unreadPins()) {
+ pinnedM.classList.add("unreadPin");
+ } else {
+ pinnedM.classList.remove("unreadPin");
+ }
+ }
const ghostMessages = document.getElementById("ghostMessages") as HTMLElement;
ghostMessages.innerHTML = "";
for (const thing of this.fakeMessages) {
diff --git a/src/webpage/direct.ts b/src/webpage/direct.ts
index 797b24e..b7be973 100644
--- a/src/webpage/direct.ts
+++ b/src/webpage/direct.ts
@@ -429,6 +429,14 @@ class Group extends Channel {
return div;
}
async getHTML(addstate = true) {
+ const pinnedM = document.getElementById("pinnedMDiv");
+ if (pinnedM) {
+ if (this.unreadPins()) {
+ pinnedM.classList.add("unreadPin");
+ } else {
+ pinnedM.classList.remove("unreadPin");
+ }
+ }
const ghostMessages = document.getElementById("ghostMessages") as HTMLElement;
ghostMessages.innerHTML = "";
for (const thing of this.fakeMessages) {
diff --git a/src/webpage/icons/pin.svg b/src/webpage/icons/pin.svg
new file mode 100644
index 0000000..ea8e642
--- /dev/null
+++ b/src/webpage/icons/pin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/webpage/index.html b/src/webpage/index.html
index f15bb36..d07f3f3 100644
--- a/src/webpage/index.html
+++ b/src/webpage/index.html
@@ -74,6 +74,10 @@
Channel name
Channel topic
+
+
+
+