get invite embeds working

This commit is contained in:
MathMan05
2024-09-06 15:43:11 -05:00
parent 7915032462
commit 1502dbec17
8 changed files with 500 additions and 46 deletions

View File

@@ -1,7 +1,9 @@
import{Dialog}from"./dialog.js";
import{Message}from"./message.js";
import{MarkDown}from"./markdown.js";
import{ embedjson }from"./jsontypes.js";
import{ embedjson,guildjson, invitejson }from"./jsontypes.js";
import { getapiurls, getInstances } from "./login.js";
import { Guild } from "./guild.js";
class Embed{
type:string;
@@ -11,8 +13,38 @@ class Embed{
this.type=this.getType(json);
this.owner=owner;
this.json=json;
console.log(this);
}
getType(json:embedjson){
const instances=getInstances();
if(instances&&json.type==="link"&&json.url&&URL.canParse(json.url)){
const Url=new URL(json.url);
for(const instance of instances){
if(instance.url&&URL.canParse(instance.url)){
const IUrl=new URL(instance.url);
const params=new URLSearchParams(Url.search);
let host:string;
if(params.has("instance")){
const url=params.get("instance") as string;
if(URL.canParse(url)){
host=new URL(url).host;
}else{
host=Url.host;
}
}else{
host=Url.host;
}
if(IUrl.host===host){
const code=Url.pathname.split("/")[Url.pathname.split("/").length-1];
json.invite={
url:instance.url,
code
}
return "invite";
}
}
}
}
return json.type||"rich";
}
generateHTML(){
@@ -21,6 +53,8 @@ class Embed{
return this.generateRich();
case"image":
return this.generateImage();
case"invite":
return this.generateInvite();
case"link":
return this.generateLink();
case "video":
@@ -192,6 +226,106 @@ class Embed{
table.append(bottomtr);
return table;
}
invcache:[invitejson,{cdn:string,api:string}]|undefined;
generateInvite(){
if(this.invcache&&(!this.json.invite||!this.localuser)){
return this.generateLink();
}
const div=document.createElement("div");
div.classList.add("embed","inviteEmbed","flexttb");
const json1=this.json.invite;
(async ()=>{
let json:invitejson;
let info:{cdn:string,api:string};
if(!this.invcache){
if(!json1){
div.append(this.generateLink());
return;
}
const tempinfo=await getapiurls(json1.url);;
if(!tempinfo){
div.append(this.generateLink());
return;
}
info=tempinfo;
const res=await fetch(info.api+"/invites/"+json1.code)
if(!res.ok){
div.append(this.generateLink());
}
json=await res.json() as invitejson;
this.invcache=[json,info];
}else{
[json,info]=this.invcache;
}
if(!json){
div.append(this.generateLink());
return;
}
if(json.guild.banner){
const banner=document.createElement("img");
banner.src=this.localuser.info.cdn+"/icons/"+json.guild.id+"/"+json.guild.banner+".png?size=256";
banner.classList.add("banner");
div.append(banner);
}
const guild:invitejson["guild"] & {info?:{cdn:string}}=json.guild;
guild.info=info;
const icon=Guild.generateGuildIcon(guild as invitejson["guild"] & {info:{cdn:string}})
const iconrow=document.createElement("div");
iconrow.classList.add("flexltr","flexstart");
iconrow.append(icon);
{
const guildinfo=document.createElement("div");
guildinfo.classList.add("flexttb","invguildinfo");
const name=document.createElement("b");
name.textContent=guild.name;
guildinfo.append(name);
const members=document.createElement("span");
members.innerText="#"+json.channel.name+" • Members: "+guild.member_count
guildinfo.append(members);
members.classList.add("subtext");
iconrow.append(guildinfo);
}
div.append(iconrow);
const h2=document.createElement("h2");
h2.textContent=`You've been invited by ${json.inviter.username}`;
div.append(h2);
const button=document.createElement("button");
button.textContent="Accept";
if(this.localuser.info.api.startsWith(info.api)){
if(this.localuser.guildids.has(guild.id)){
button.textContent="Already joined";
button.disabled=true;
}
}
button.classList.add("acceptinvbutton");
div.append(button);
button.onclick=_=>{
if(this.localuser.info.api.startsWith(info.api)){
fetch(this.localuser.info.api+"/invites/"+json.code,{
method: "POST",
headers: this.localuser.headers,
}).then(r=>r.json()).then(_=>{
if(_.message){
alert(_.message);
}
});
}else{
if(this.json.invite){
const params=new URLSearchParams("");
params.set("instance",this.json.invite.url);
const encoded=params.toString();
const url=`${location.origin}/invite/${this.json.invite.code}?${encoded}`;
window.open(url,"_blank");
}
}
}
})()
return div;
}
generateArticle(){
const colordiv=document.createElement("div");
colordiv.style.backgroundColor="#000000";

View File

@@ -7,7 +7,7 @@ import{Member}from"./member.js";
import{Settings}from"./settings.js";
import{Permissions}from"./permissions.js";
import{ SnowFlake }from"./snowflake.js";
import{ channeljson, guildjson, emojijson, memberjson }from"./jsontypes.js";
import{ channeljson, guildjson, emojijson, memberjson, invitejson }from"./jsontypes.js";
import{ User }from"./user.js";
class Guild extends SnowFlake{
@@ -274,39 +274,60 @@ class Guild extends SnowFlake{
return a.position-b.position;
});
}
generateGuildIcon(){
static generateGuildIcon(guild:Guild|(invitejson["guild"] & {info:{cdn:string}})){
const divy=document.createElement("div");
divy.classList.add("servernoti");
const noti=document.createElement("div");
noti.classList.add("unread");
divy.append(noti);
this.localuser.guildhtml.set(this.id,divy);
if(this.properties.icon!=null){
if(guild instanceof Guild){
guild.localuser.guildhtml.set(guild.id,divy);
}
let icon:string|null
if(guild instanceof Guild){
icon=guild.properties.icon;
}else{
icon=guild.icon;
}
if(icon!==null){
const img=document.createElement("img");
img.classList.add("pfp","servericon");
img.src=this.info.cdn+"/icons/"+this.properties.id+"/"+this.properties.icon+".png";
img.src=guild.info.cdn+"/icons/"+guild.id+"/"+icon+".png";
divy.appendChild(img);
img.onclick=()=>{
console.log(this.loadGuild);
this.loadGuild();
this.loadChannel();
};
Guild.contextmenu.bindContextmenu(img,this,undefined);
if(guild instanceof Guild){
img.onclick=()=>{
console.log(guild.loadGuild);
guild.loadGuild();
guild.loadChannel();
};
Guild.contextmenu.bindContextmenu(img,guild,undefined);
}
}else{
const div=document.createElement("div");
const build=this.properties.name.replace(/'s /g, " ").replace(/\w+/g, word=>word[0]).replace(/\s/g, "");
let name:string
if(guild instanceof Guild){
name=guild.properties.name;
}else{
name=guild.name;
}
const build=name.replace(/'s /g, " ").replace(/\w+/g, word=>word[0]).replace(/\s/g, "");
div.textContent=build;
div.classList.add("blankserver","servericon");
divy.appendChild(div);
div.onclick=()=>{
this.loadGuild();
this.loadChannel();
};
Guild.contextmenu.bindContextmenu(div,this,undefined);
if(guild instanceof Guild){
div.onclick=()=>{
guild.loadGuild();
guild.loadChannel();
};
Guild.contextmenu.bindContextmenu(div,guild,undefined);
}
}
return divy;
}
generateGuildIcon(){
return Guild.generateGuildIcon(this);
}
confirmDelete(){
let confirmname="";
const full= new Dialog([

View File

@@ -333,13 +333,79 @@ type embedjson={
provider:{
name:string,
},
video:{
video?:{
url: string,
width?: number|null,
height?: number|null,
proxy_url?: string
},
invite?:{
url:string,
code:string
}
}
type invitejson={
code: string,
temporary: boolean,
uses: number,
max_use: number,
max_age: number,
created_at: string,
expires_at: string,
guild_id: string,
channel_id: string,
inviter_id: string,
target_user_id: string|null,
target_user_type: string|null,
vanity_url: string|null,
flags: number,
guild: {
id: string,
afk_channel_id: string|null,
afk_timeout: number,
banner: string|null,
default_message_notifications: number,
description: string|null,
discovery_splash: string|null,
explicit_content_filter: number,
features: [],
primary_category_id: string|null,
icon: string|null,
large: boolean,
max_members: number,
max_presences: number,
max_video_channel_users: number,
member_count: number,
presence_count: number,
template_id: string|null,
mfa_level: number,
name: string,
owner_id: string,
preferred_locale: string,
premium_subscription_count: number,
premium_tier: number,
public_updates_channel_id: string|null,
rules_channel_id: string|null,
region: string|null,
splash: string|null,
system_channel_id: string|null,
system_channel_flags: number,
verification_level: number,
welcome_screen: {
enabled: boolean,
description: string,
welcome_channels: string[]
},
widget_channel_id: string|null,
widget_enabled: boolean,
nsfw_level: number,
nsfw: boolean,
parent: string|null,
premium_progress_bar_enabled: boolean
},
channel: channeljson,
inviter: userjson
}
type presencejson={
status: string,
since: number|null,
@@ -426,4 +492,4 @@ type memberChunk={
chunk_count: number,
not_found: string[]
}
export{readyjson,dirrectjson,channeljson,guildjson,rolesjson,userjson,memberjson,mainuserjson,messagejson,filejson,embedjson,emojijson,presencejson,wsjson,messageCreateJson,memberChunk};
export{readyjson,dirrectjson,channeljson,guildjson,rolesjson,userjson,memberjson,mainuserjson,messagejson,filejson,embedjson,emojijson,presencejson,wsjson,messageCreateJson,memberChunk,invitejson};

View File

@@ -10,6 +10,11 @@ function setTheme(){
}
document.body.className=name+"-theme";
}
let instances:{name:string,description?:string,descriptionLong?:string,image?:string,url?:string,display?:boolean,online?:boolean,
uptime:{alltime:number,daytime:number,weektime:number},
urls:{wellknown:string,api:string,cdn:string,gateway:string,login?:string}}[]|null;
setTheme();
function getBulkUsers(){
const json=getBulkInfo();
@@ -407,8 +412,15 @@ export{mobile, getBulkUsers,getBulkInfo,setTheme,Specialuser,getapiurls,adduser}
const datalist=document.getElementById("instances");
console.warn(datalist);
if(datalist){
fetch("/instances.json").then(_=>_.json()).then((json:{name:string,online:boolean,description?:string,src?:string,url?:string,display?:boolean,urls:{wellknown:string,api:string,cdn:string,gateway:string,login?:string}}[])=>{
export function getInstances(){
return instances;
}
fetch("/instances.json").then(_=>_.json()).then((json:{name:string,description?:string,descriptionLong?:string,image?:string,url?:string,display?:boolean,online?:boolean,
uptime:{alltime:number,daytime:number,weektime:number},
urls:{wellknown:string,api:string,cdn:string,gateway:string,login?:string}}[])=>{
instances=json;
if(datalist){
console.warn(json);
if(instancein&&instancein.value===""){
instancein.value=json[0].name;
@@ -438,5 +450,5 @@ if(datalist){
datalist.append(option);
}
checkInstance("");
});
}
}
});

View File

@@ -1478,7 +1478,6 @@ span {
width: 100%;
flex-direction: column;
max-height:100in;
justify-content: flex-end;
}
#connection-container, #app-list-container {
@@ -1876,7 +1875,6 @@ form div{
}
.banner{
position:absolute;
z-index: 0;
top:0;
left:0;
width:100%;
@@ -2132,3 +2130,63 @@ form div{
background:var(--message-bg-hover);
}
}
.acceptinvbutton{
background:var(--green);
width: 95%;
text-align:center;
font-size:.25in;
box-sizing: border-box;
margin: .1in;
}
.acceptinvbutton:hover{
background:color-mix(in hsl,var(--green) 80%,var(--black));
}
.acceptinvbutton:disabled:hover{
background:color-mix(in hsl,var(--green) 80%,var(--black));
}
.acceptinvbutton:disabled{
background:color-mix(in hsl,var(--green) 80%,var(--black));
}
.inviteEmbed{
border: solid .035in var(--black);
gap: .075in;
min-width:4in;
max-width:6in;
min-height: 1.5in;
display: flex;
align-items: center;
position: relative;
.banner{
height: .5in;
position: relative;
}
;
padding: 0in;
}
.inviteEmbed .flexltr {
display: flex;
flex-wrap: nowrap;
}
.inviteEmbed .invguildinfo{
display:flex;
justify-content: center;
margin-left: .15in;
background: var(--channels-bg);
border: solid .03in var(--black);
border-radius: .1in;
padding: .07in;
flex-grow: 1;
height: fit-content;
backdrop-filter: blur(5px);
margin-right: .15in;
}
.subtext{
color:color-mix(in srgb, var(--black),var(--primary-text) 65%);
}
.flexstart{
align-self:start;
z-index: 1;
margin-left: .04in;
margin-top: .04in;
width: 100%;
}