diff --git a/gulpfile.cjs b/gulpfile.cjs index a1560a6..fd43e3a 100644 --- a/gulpfile.cjs +++ b/gulpfile.cjs @@ -8,98 +8,110 @@ const plumber = require("gulp-plumber"); const sourcemaps = require('gulp-sourcemaps'); const fs=require("fs"); const swcOptions = { - jsc: { +jsc: { parser: { - syntax: "typescript", - tsx: false, - decorators: true, - dynamicImport: true, + syntax: "typescript", + tsx: false, + decorators: true, + dynamicImport: true, + }, + transform: { + react: { + runtime: "automatic", + }, + }, + target: "es2022", + loose: false, + externalHelpers: false, + keepClassNames: true, }, - transform: { - react: { - runtime: "automatic", - }, + module: { + type: "es6", + strict: true, + strictMode: true, + lazy: false, + noInterop: false, }, - target: "es2022", - loose: false, - externalHelpers: false, - keepClassNames: true, - }, - module: { - type: "es6", - strict: true, - strictMode: true, - lazy: false, - noInterop: false, - }, - sourceMaps: true, - minify: false, + sourceMaps: true, + minify: false, }; + + +gulp.task('watch', function () { + gulp.watch('./src', gulp.series("default")); +}, {debounceDelay: 10}); + // Clean task to delete the dist directory gulp.task("clean", (cb) => { - return rimraf.rimraf("dist").then(cb()); -}); - -// Task to compile TypeScript files using SWC -gulp.task("scripts", () => { - if (argv.swc) { - return gulp - .src("src/**/*.ts") - .pipe(sourcemaps.init()) - .pipe(plumber()) // Prevent pipe breaking caused by errors - .pipe(swc(swcOptions)) - .pipe(sourcemaps.write('.')) - .pipe(gulp.dest("dist")); - } else { - console.warn("[WARN] Using TSC compiler, will be slower than SWC"); - return gulp - .src("src/**/*.ts") - .pipe(sourcemaps.init()) - .pipe(plumber()) // Prevent pipe breaking caused by errors - .pipe(tsProject()) - .pipe(sourcemaps.write('.')) - .pipe(gulp.dest("dist")); - } + return rimraf.rimraf("dist").then(cb()); + }); + const exec = require('child_process').exec; + // Task to compile TypeScript files using SWC + gulp.task("scripts", async () => { + if (argv.swc) { + return gulp + .src("src/**/*.ts") + .pipe(sourcemaps.init()) + .pipe(plumber()) // Prevent pipe breaking caused by errors + .pipe(swc(swcOptions)) + .pipe(sourcemaps.write('.')) + .pipe(gulp.dest("dist")); + } else if(argv.bunswc){ + return await new Promise(ret=>{ + exec("bun swc ./src -s -d dist").on('exit', function (code) { + ret(); + }); + }) + }else { + console.warn("[WARN] Using TSC compiler, will be slower than SWC"); + return gulp + .src("src/**/*.ts") + .pipe(sourcemaps.init()) + .pipe(plumber()) // Prevent pipe breaking caused by errors + .pipe(tsProject()) + .pipe(sourcemaps.write('.')) + .pipe(gulp.dest("dist")); + } }); // Task to copy HTML files gulp.task("copy-html", () => { - return gulp +return gulp .src("src/**/*.html") .pipe(plumber()) // Prevent pipe breaking caused by errors .pipe(gulp.dest("dist")); }); gulp.task("copy-translations", () => { - let langs=fs.readdirSync("translations"); - langs=langs.filter((e)=>e!=="qqq.json"); - const langobj={}; - for(const lang of langs){ +let langs=fs.readdirSync("translations"); +langs=langs.filter((e)=>e!=="qqq.json"); +const langobj={}; +for(const lang of langs){ const json=JSON.parse(fs.readFileSync("translations/"+lang).toString()); langobj[lang]=json.readableName; - } - if(!fs.existsSync("dist/webpage/translations")) fs.mkdirSync("dist/webpage/translations") - fs.writeFileSync("dist/webpage/translations/langs.js",`const langs=${JSON.stringify(langobj)};export{langs}`); - return gulp +} +if(!fs.existsSync("dist/webpage/translations")) fs.mkdirSync("dist/webpage/translations") +fs.writeFileSync("dist/webpage/translations/langs.js",`const langs=${JSON.stringify(langobj)};export{langs}`); +return gulp .src("translations/*.json") .pipe(plumber()) // Prevent pipe breaking caused by errors .pipe(gulp.dest("dist/webpage/translations")); }); // Task to copy other static assets (e.g., CSS, images) gulp.task("copy-assets", () => { - return gulp +return gulp .src([ - "src/**/*.css", - "src/**/*.bin", - "src/**/*.ico", - "src/**/*.json", - "src/**/*.js", - "src/**/*.png", - "src/**/*.jpg", - "src/**/*.jpeg", - "src/**/*.webp", - "src/**/*.gif", - "src/**/*.svg", + "src/**/*.css", + "src/**/*.bin", + "src/**/*.ico", + "src/**/*.json", + "src/**/*.js", + "src/**/*.png", + "src/**/*.jpg", + "src/**/*.jpeg", + "src/**/*.webp", + "src/**/*.gif", + "src/**/*.svg", ],{encoding:false}) .pipe(plumber()) // Prevent pipe breaking caused by errors .pipe(gulp.dest("dist")); @@ -107,6 +119,6 @@ gulp.task("copy-assets", () => { // Default task to run all tasks gulp.task( - "default", - gulp.series("clean", gulp.parallel("scripts", "copy-html", "copy-assets"), "copy-translations") +"default", +gulp.series("clean", gulp.parallel("scripts", "copy-html", "copy-assets"), "copy-translations") ); diff --git a/src/webpage/channel.ts b/src/webpage/channel.ts index 62c383c..9e88783 100644 --- a/src/webpage/channel.ts +++ b/src/webpage/channel.ts @@ -853,6 +853,7 @@ class Channel extends SnowFlake{ //loading.classList.remove("loading"); (document.getElementById("typebox") as HTMLDivElement).contentEditable =""+this.canMessage; (document.getElementById("upload") as HTMLElement).style.visibility=this.canMessage?"visible":"hidden"; + (document.getElementById("typediv") as HTMLElement).style.visibility="visible"; (document.getElementById("typebox") as HTMLDivElement).focus(); } typingmap: Map = new Map(); @@ -1086,10 +1087,8 @@ class Channel extends SnowFlake{ let id: string | undefined; if(this.lastreadmessageid && this.messages.has(this.lastreadmessageid)){ id = this.lastreadmessageid; - }else if( - this.lastreadmessageid && - (id = this.findClosest(this.lastreadmessageid)) - ){ + }else if(this.lastreadmessageid && (id = this.findClosest(this.lastreadmessageid))){ + }else if(this.lastmessageid && this.messages.has(this.lastmessageid)){ id = this.goBackIds(this.lastmessageid, 50); } @@ -1098,7 +1097,7 @@ class Channel extends SnowFlake{ const title = document.createElement("h2"); title.id = "removetitle"; title.textContent = I18n.getTranslation("noMessages"); - title.classList.add("titlespace"); + title.classList.add("titlespace","messagecontainer"); messages.append(title); } this.infinitefocus = false; diff --git a/src/webpage/direct.ts b/src/webpage/direct.ts index 1b582a1..8e99394 100644 --- a/src/webpage/direct.ts +++ b/src/webpage/direct.ts @@ -3,12 +3,7 @@ import{ Channel }from"./channel.js"; import{ Message }from"./message.js"; import{ Localuser }from"./localuser.js"; import{ User }from"./user.js"; -import{ - channeljson, - dirrectjson, - memberjson, - messagejson, -}from"./jsontypes.js"; +import{channeljson,dirrectjson,memberjson,messagejson}from"./jsontypes.js"; import{ Permissions }from"./permissions.js"; import{ SnowFlake }from"./snowflake.js"; import{ Contextmenu }from"./contextmenu.js"; @@ -23,9 +18,6 @@ class Direct extends Guild{ super(-1, owner, null); this.message_notifications = 0; this.owner = owner; - if(!this.localuser){ - console.error("Owner was not included, please fix"); - } this.headers = this.localuser.headers; this.channels = []; this.channelids = {}; @@ -58,6 +50,25 @@ class Direct extends Guild{ channel.del(); } } + getHTML(){ + const ddiv=document.createElement("div"); + const build=super.getHTML(); + const freindDiv=document.createElement("div"); + freindDiv.classList.add("liststyle","flexltr","friendsbutton"); + + const icon=document.createElement("span"); + icon.classList.add("svgicon","svg-friends","space"); + freindDiv.append(icon); + + freindDiv.append("Friends"); + ddiv.append(freindDiv); + freindDiv.onclick=()=>{ + this.loadChannel(null); + } + + ddiv.append(build); + return ddiv; + } giveMember(_member: memberjson){ console.error("not a real guild, can't give member object"); } @@ -200,6 +211,7 @@ class Group extends Channel{ this.buildmessages(); (document.getElementById("typebox") as HTMLDivElement).contentEditable ="" + true; (document.getElementById("upload") as HTMLElement).style.visibility="visible"; + (document.getElementById("typediv") as HTMLElement).style.visibility="visible"; (document.getElementById("typebox") as HTMLDivElement).focus(); } messageCreate(messagep: { d: messagejson }){ diff --git a/src/webpage/guild.ts b/src/webpage/guild.ts index dfdb5ca..a729a2c 100644 --- a/src/webpage/guild.ts +++ b/src/webpage/guild.ts @@ -577,7 +577,7 @@ class Guild extends SnowFlake{ } return this.member.hasRole(r); } - loadChannel(ID?: string | undefined,addstate=true){ + loadChannel(ID?: string | undefined| null,addstate=true){ if(ID){ const channel = this.localuser.channelids.get(ID); if(channel){ @@ -585,17 +585,63 @@ class Guild extends SnowFlake{ return; } } - if(this.prevchannel){ + if(this.prevchannel&&ID!==null){ console.log(this.prevchannel); this.prevchannel.getHTML(addstate); return; } - for(const thing of this.channels){ - if(thing.children.length === 0){ - thing.getHTML(addstate); - return; + if(this.id!=="@me"){ + for(const thing of this.channels){ + if(thing.type!==4){ + thing.getHTML(addstate); + return; + } } } + this.removePrevChannel(); + this.noChannel(addstate); + } + removePrevChannel(){ + if(this.localuser.channelfocus){ + this.localuser.channelfocus.infinite.delete(); + } + if(this !== this.localuser.lookingguild){ + this.loadGuild(); + } + if(this.localuser.channelfocus && this.localuser.channelfocus.myhtml){ + this.localuser.channelfocus.myhtml.classList.remove("viewChannel"); + } + this.prevchannel = undefined; + this.localuser.channelfocus = undefined; + const replybox = document.getElementById("replybox") as HTMLElement; + const typebox = document.getElementById("typebox") as HTMLElement; + replybox.classList.add("hideReplyBox"); + typebox.classList.remove("typeboxreplying"); + (document.getElementById("typebox") as HTMLDivElement).contentEditable ="false"; + (document.getElementById("upload") as HTMLElement).style.visibility="hidden"; + (document.getElementById("typediv") as HTMLElement).style.visibility="hidden"; + (document.getElementById("sideDiv") as HTMLElement).innerHTML=""; + } + noChannel(addstate:boolean){ + if(addstate){ + history.pushState([this.id,undefined], "", "/channels/" + this.id); + } + this.localuser.pageTitle("Weird spot"); + const channelTopic = document.getElementById("channelTopic") as HTMLSpanElement; + channelTopic.setAttribute("hidden", ""); + + const loading = document.getElementById("loadingdiv") as HTMLDivElement; + loading.classList.remove("loading"); + this.localuser.getSidePannel(); + + const messages = document.getElementById("channelw") as HTMLDivElement; + for(const thing of Array.from(messages.getElementsByClassName("messagecontainer"))){ + thing.remove(); + } + const h1=document.createElement("h1"); + h1.classList.add("messagecontainer") + h1.textContent="You're in a weird spot, this guild has no channels"; + messages.append(h1); } loadGuild(){ this.localuser.loadGuild(this.id); @@ -703,7 +749,9 @@ class Guild extends SnowFlake{ if(indexy !== -1){ this.headchannels.splice(indexy, 1); } - + if(channel===this.prevchannel){ + this.prevchannel=undefined; + } /* const build=[]; for(const thing of this.channels){ diff --git a/src/webpage/icons/friends.svg b/src/webpage/icons/friends.svg new file mode 100644 index 0000000..21b8252 --- /dev/null +++ b/src/webpage/icons/friends.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/webpage/index.html b/src/webpage/index.html index 8a05715..b1933ce 100644 --- a/src/webpage/index.html +++ b/src/webpage/index.html @@ -64,7 +64,7 @@ diff --git a/src/webpage/index.ts b/src/webpage/index.ts index 9099fba..6499fcb 100644 --- a/src/webpage/index.ts +++ b/src/webpage/index.ts @@ -5,7 +5,6 @@ import{ MarkDown }from"./markdown.js"; import{ Message }from"./message.js"; import{File}from"./file.js"; import { I18n } from "./i18n.js"; - (async ()=>{ await I18n.done const users = getBulkUsers(); diff --git a/src/webpage/localuser.ts b/src/webpage/localuser.ts index 26863ac..0422d50 100644 --- a/src/webpage/localuser.ts +++ b/src/webpage/localuser.ts @@ -794,8 +794,7 @@ class Localuser{ guild.html.classList.add("serveropen"); } this.lookingguild = guild; - (document.getElementById("serverName") as HTMLElement).textContent = - guild.properties.name; + (document.getElementById("serverName") as HTMLElement).textContent = guild.properties.name; //console.log(this.guildids,id) const channels = document.getElementById("channels") as HTMLDivElement; channels.innerHTML = ""; diff --git a/src/webpage/style.css b/src/webpage/style.css index ba652d9..fb23e4c 100644 --- a/src/webpage/style.css +++ b/src/webpage/style.css @@ -248,12 +248,18 @@ textarea { } .svg-upload { mask: url(/icons/upload.svg); - width: .2in !important;!i;!; + width: .2in !important; cursor: pointer; } .svg-x { mask: url(/icons/x.svg); } +.svg-friends{ + mask: url(/icons/friends.svg); + width: 24px !important;!i;!; + height: 24px !important;!i;!; + margin-right: 0 !important;!i;!; +} .svgicon { display: block; height: 100%; @@ -328,6 +334,10 @@ textarea { ::-webkit-scrollbar-thumb:hover { background: var(--primary-text-soft); } +#sideDiv:empty{ + width:0px; + padding:0; +} #servers::-webkit-scrollbar, #channels::-webkit-scrollbar, #sideDiv::-webkit-scrollbar { display: none; } @@ -2054,6 +2064,11 @@ fieldset input[type="radio"] { } } +.friendsbutton{ + transition: background-color .2s; + background-color: #00000050; + padding: .08in; +} .bigemoji{ width:.6in; }