discovery improvments and fixes

This commit is contained in:
MathMan05
2025-10-15 15:09:18 -05:00
parent d547c85ae9
commit 8b429e0abe
7 changed files with 267 additions and 76 deletions
+1
View File
@@ -1587,6 +1587,7 @@ class Channel extends SnowFlake {
this.localuser.channelfocus.collectBox();
}
const typebox = document.getElementById("typebox") as CustomHTMLDivElement;
typebox.style.setProperty("--channel-text", JSON.stringify(I18n.channel.typebox(this.name)));
const md = typebox.markdown;
md.owner = this;
typebox.textContent = this.textSave;
+15
View File
@@ -9,12 +9,14 @@ import {SnowFlake} from "./snowflake.js";
import {Contextmenu} from "./contextmenu.js";
import {I18n} from "./i18n.js";
import {Dialog, Float, FormError} from "./settings.js";
import {Discovery} from "./discovery.js";
class Direct extends Guild {
channels: Group[];
getUnixTime(): number {
throw new Error("Do not call this for Direct, it does not make sense");
}
discovery: Discovery;
constructor(json: dirrectjson[], owner: Localuser) {
super(-1, owner, null);
this.message_notifications = 0;
@@ -31,6 +33,7 @@ class Direct extends Guild {
this.localuser.channelids.set(temp.id, temp);
}
this.headchannels = this.channels;
this.discovery = new Discovery(this);
}
createChannelpac(json: any) {
const thischannel = new Group(json, this);
@@ -86,6 +89,14 @@ class Direct extends Guild {
ddiv.append(freindDiv, newDm, build);
return ddiv;
}
loadChannel(id?: string | null | undefined, addstate = true, message?: string) {
if (id === "discover") {
this.removePrevChannel();
this.discovery.makeMenu();
return;
}
super.loadChannel(id, addstate, message);
}
makeGroup() {
const dio = new Dialog(I18n.group.select());
const opt = dio.options;
@@ -501,7 +512,11 @@ class Group extends Channel {
this.icon = json.icon;
json.recipients = json.recipients.filter((_) => _.id !== this.localuser.user.id);
const userSet = new Set(json.recipients.map((user) => new User(user, this.localuser)));
if (userSet.size === 0) {
userSet.add(this.localuser.user);
}
this.users = [...userSet];
this.name = json.name || this.defaultName();
+200
View File
@@ -0,0 +1,200 @@
import {Direct} from "./direct.js";
import {I18n} from "./i18n.js";
import {guildjson} from "./jsontypes.js";
import {Dialog} from "./settings.js";
import {createImg} from "./utils/utils.js";
export class Discovery {
owner: Direct;
get info() {
return this.owner.info;
}
get headers() {
return this.owner.headers;
}
get localuser() {
return this.owner.localuser;
}
constructor(owner: Direct) {
this.owner = owner;
}
async makeMenu() {
if (this.owner instanceof Direct) {
this.owner.freindDiv?.classList.remove("viewChannel");
}
if (this.localuser.channelfocus) {
this.localuser.channelfocus.collectBox();
}
history.pushState(["@me", "discover"], "", "/channels/@me/discover");
this.localuser.pageTitle(I18n.discovery());
const channelTopic = document.getElementById("channelTopic") as HTMLSpanElement;
channelTopic.removeAttribute("hidden");
channelTopic.textContent = "";
channelTopic.onclick = () => {};
if (this.localuser.lookingguild) {
this.localuser.lookingguild.html.classList.remove("serveropen");
}
this.localuser.lookingguild = undefined;
this.localuser.channelfocus = undefined;
const loading = document.getElementById("loadingdiv") as HTMLDivElement;
loading.classList.remove("loading");
this.localuser.getSidePannel();
const messages = document.getElementById("scrollWrap") as HTMLDivElement;
for (const thing of Array.from(messages.getElementsByClassName("messagecontainer"))) {
thing.remove();
}
const channels = document.getElementById("channels") as HTMLDivElement;
channels.innerHTML = "";
const banner = document.getElementById("servertd") as HTMLDivElement;
banner.style.removeProperty("background-image");
banner.classList.remove("Banner");
banner.style.removeProperty("cursor");
banner.onclick = () => {};
(document.getElementById("serverName") as HTMLElement).textContent = I18n.discovery();
const scrollWrap = document.getElementById("scrollWrap") as HTMLDivElement;
scrollWrap.innerHTML = "";
const content = document.createElement("div");
content.classList.add("flexttb", "guildy", "messagecontainer");
content.textContent = I18n.guild.loadingDiscovery();
scrollWrap.append(content);
const guildsButton = document.createElement("button");
guildsButton.textContent = I18n.guild.guilds();
guildsButton.classList.add("discoverButton", "selected");
channels.append(guildsButton);
const res = await fetch(this.info.api + "/discoverable-guilds?limit=50", {
headers: this.headers,
});
const json = await res.json();
console.log([...json.guilds], json.guilds);
//@ts-ignore
json.guilds = json.guilds.sort((a, b) => {
return b.member_count - a.member_count;
});
content.innerHTML = "";
const title = document.createElement("h2");
title.textContent = I18n.guild.disoveryTitle(json.guilds.length + "");
content.appendChild(title);
const guilds = document.createElement("div");
guilds.id = "discovery-guild-content";
json.guilds.forEach((guild: guildjson["properties"]) => {
const content = document.createElement("div");
content.classList.add("discovery-guild");
const banner = this.getBannerURL(guild);
if (banner) {
banner.classList.add("banner");
banner.crossOrigin = "anonymous";
banner.alt = "";
content.appendChild(banner);
}
const nameContainer = document.createElement("div");
nameContainer.classList.add("flex");
const img = this.getIconURL(guild);
img.classList.add("icon");
img.crossOrigin = "anonymous";
img.alt = "";
nameContainer.appendChild(img);
const name = document.createElement("h3");
name.textContent = guild.name;
nameContainer.appendChild(name);
content.appendChild(nameContainer);
const desc = document.createElement("p");
desc.textContent = guild.description;
content.appendChild(desc);
content.addEventListener("click", async () => {
let guildObj = this.localuser.guildids.get(guild.id);
if (guildObj) {
guildObj.loadGuild();
guildObj.loadChannel();
return;
}
if (await this.confirmJoin(guild)) {
await this.join(guild);
}
});
guilds.appendChild(content);
});
content.appendChild(guilds);
}
getIconURL(guild: guildjson["properties"]) {
return createImg(
this.info.cdn +
(guild.icon
? "/icons/" + guild.id + "/" + guild.icon + ".png?size=48"
: "/embed/avatars/3.png"),
);
}
getBannerURL(guild: guildjson["properties"]) {
return (
guild.banner &&
createImg(this.info.cdn + "/icons/" + guild.id + "/" + guild.banner + ".png?size=256")
);
}
async confirmJoin(guild: guildjson["properties"]) {
return new Promise<boolean>((res) => {
const dio = new Dialog(I18n.guild.joinConfirm(guild.name));
const opt = dio.options;
const div = document.createElement("div");
div.classList.add("flexltr", "guildPreview");
const img = this.getIconURL(guild);
img.classList.add("icon");
img.crossOrigin = "anonymous";
img.alt = "";
div.append(img);
const banner = this.getBannerURL(guild);
if (banner) {
banner.classList.add("banner");
banner.crossOrigin = "anonymous";
banner.alt = "";
div.append(banner);
}
opt.addHTMLArea(div);
opt.addText(I18n.guild.memberCount(guild.member_count + ""));
if (guild.description) opt.addText(I18n.guild["description:"]() + "\n" + guild.description);
const buttons = opt.addOptions("", {ltr: true});
buttons.addButtonInput("", I18n.yes(), () => {
dio.hide();
res(true);
});
buttons.addButtonInput("", I18n.no(), () => {
dio.hide();
res(false);
});
dio.show();
});
}
async join(guild: guildjson["properties"]) {
await fetch(this.info.api + "/guilds/" + guild.id + "/members/@me", {
method: "PUT",
headers: this.headers,
});
let guildObj = this.localuser.guildids.get(guild.id);
while (!guildObj) {
guildObj = this.localuser.guildids.get(guild.id);
await new Promise((res) => setTimeout(res, 100));
}
guildObj.loadGuild();
guildObj.loadChannel();
}
}
-1
View File
@@ -1473,7 +1473,6 @@ class Guild extends SnowFlake {
divy.appendChild(img);
if (guild instanceof Guild && autoLink) {
img.onclick = () => {
console.log(guild.loadGuild);
guild.loadGuild();
guild.loadChannel();
};
+6 -70
View File
@@ -698,6 +698,10 @@ class Localuser {
this.guildids.delete(temp.d.id);
this.guilds.splice(this.guilds.indexOf(guildy), 1);
guildy.html.remove();
if (guildy === this.lookingguild) {
this.guildids.get("@me")?.loadGuild();
this.guildids.get("@me")?.loadChannel();
}
}
break;
}
@@ -1229,6 +1233,7 @@ class Localuser {
}
this.goToChannel(channelid, false, messageid);
}
gotoid: string | undefined;
async goToChannel(channelid: string, addstate = true, messageid: undefined | string = undefined) {
const channel = this.channelids.get(channelid);
@@ -1864,76 +1869,7 @@ class Localuser {
).json();
}
async guildDiscovery() {
const content = document.createElement("div");
content.classList.add("flexttb", "guildy");
content.textContent = I18n.guild.loadingDiscovery();
const full = new Dialog("");
full.options.addHTMLArea(content);
full.show();
const res = await fetch(this.info.api + "/discoverable-guilds?limit=50", {
headers: this.headers,
});
const json = await res.json();
console.log([...json.guilds], json.guilds);
//@ts-ignore
json.guilds = json.guilds.sort((a, b) => {
return b.member_count - a.member_count;
});
content.innerHTML = "";
const title = document.createElement("h2");
title.textContent = I18n.guild.disoveryTitle(json.guilds.length + "");
content.appendChild(title);
const guilds = document.createElement("div");
guilds.id = "discovery-guild-content";
json.guilds.forEach((guild: guildjson["properties"]) => {
const content = document.createElement("div");
content.classList.add("discovery-guild");
if (guild.banner) {
const banner = createImg(
this.info.cdn + "/icons/" + guild.id + "/" + guild.banner + ".png?size=256",
);
banner.classList.add("banner");
banner.crossOrigin = "anonymous";
banner.alt = "";
content.appendChild(banner);
}
const nameContainer = document.createElement("div");
nameContainer.classList.add("flex");
const img = createImg(
this.info.cdn +
(guild.icon
? "/icons/" + guild.id + "/" + guild.icon + ".png?size=48"
: "/embed/avatars/3.png"),
);
img.classList.add("icon");
img.crossOrigin = "anonymous";
img.alt = "";
nameContainer.appendChild(img);
const name = document.createElement("h3");
name.textContent = guild.name;
nameContainer.appendChild(name);
content.appendChild(nameContainer);
const desc = document.createElement("p");
desc.textContent = guild.description;
content.appendChild(desc);
content.addEventListener("click", async () => {
const joinRes = await fetch(this.info.api + "/guilds/" + guild.id + "/members/@me", {
method: "PUT",
headers: this.headers,
});
if (joinRes.ok) full.hide();
});
guilds.appendChild(content);
});
content.appendChild(guilds);
this.guildids.get("@me")?.loadChannel("discover");
}
messageCreate(messagep: messageCreateJson): void {
messagep.d.guild_id ??= "@me";
+40 -5
View File
@@ -477,6 +477,17 @@ audio::-webkit-media-controls-panel {
.joinb:hover {
background: color-mix(in srgb, var(--green) 80%, transparent);
}
.discoverButton {
width: calc(100% - 10px);
text-align: center;
margin: 5px;
box-sizing: border-box;
background: #00000029;
padding: 10px;
&.selected {
background: #00000050;
}
}
button,
input::file-selector-button,
select {
@@ -1820,6 +1831,12 @@ span.instanceStatus {
margin-right: 0.03in;
padding: 10px 0;
}
#typebox:empty:before,
#typebox:has(span:empty):before {
content: var(--channel-text);
opacity: 0.5;
position: absolute;
}
.outerTypeBox {
max-height: 50svh;
padding: 10px 10px;
@@ -3067,10 +3084,14 @@ fieldset input[type="radio"] {
max-height: unset;
width: auto;
}
#typediv[style*="hidden"] {
height: 0px;
}
.guildy {
height: 80svh;
width: 80svw;
gap: 6px;
height: 100%;
padding: 10px;
box-sizing: border-box;
}
#discovery-guild-content {
flex: 1;
@@ -3189,6 +3210,11 @@ fieldset input[type="radio"] {
align-self: center;
cursor: pointer;
}
.centeritem {
.fadeHTMLArea {
animation-duration: 0s;
}
}
.fadeHTMLArea {
position: absolute;
width: 100%;
@@ -3196,12 +3222,12 @@ fieldset input[type="radio"] {
background: var(--settings-bg);
animation-duration: 0.2s;
animation-name: fadeOldSettings;
@media screen and (max-width: 600px) {
animation-duration: 0s;
}
animation-timing-function: ease-in;
z-index: 900;
height: 100%;
&:empty {
display: none;
}
@@ -3246,7 +3272,6 @@ fieldset input[type="radio"] {
animation-timing-function: ease-in;
}
.titlediv {
height: 100%;
}
.flexspace {
padding-bottom: 32px;
@@ -3378,7 +3403,7 @@ fieldset input[type="radio"] {
.optionElement input[type="text"],
.optionElement textarea,
.optionElement .fileinputdiv {
width: 500px;
max-width: 500px;
}
#app-list-container div,
#connection-container div {
@@ -4133,3 +4158,13 @@ img.error::after {
margin-bottom: 0px;
}
}
.guildPreview {
.banner {
position: relative !important;
margin-left: 10px;
border-radius: 10px;
}
.icon {
flex-shrink: 0;
}
}
+5
View File
@@ -191,6 +191,7 @@
"searchGifs": "Search Tenor",
"muteDuration":"Unmute in:",
"channel": {
"typebox":"Message in $1",
"creating": "Creating channel",
"name": "Channel",
"copyId": "Copy channel id",
@@ -314,7 +315,11 @@
"nevermind": "Nevermind",
"submit": "submit",
"edit": "Edit",
"discovery":"Discovery",
"guild": {
"memberCount":"$1 {{PLURAL:$1|member|members}}",
"joinConfirm":"Join $1?",
"guilds":"Guilds",
"template": "Template:",
"admins":"Find Admins",
"adminMenu":{