better search
This commit is contained in:
parent
01e267846e
commit
83dc0ebb71
11 changed files with 321 additions and 70 deletions
|
@ -928,12 +928,35 @@ class Channel extends SnowFlake {
|
|||
}
|
||||
}
|
||||
async focus(id: string) {
|
||||
console.time();
|
||||
const m = this.messages.get(id);
|
||||
if (m && m.div) {
|
||||
if (document.contains(m.div)) {
|
||||
m.div.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "center",
|
||||
});
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 1000);
|
||||
});
|
||||
m.div.classList.remove("jumped");
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 100);
|
||||
});
|
||||
m.div.classList.add("jumped");
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log(await this.getmessage(id));
|
||||
await this.getHTML();
|
||||
console.timeEnd();
|
||||
|
||||
if (this.localuser.channelfocus === this) {
|
||||
this.localuser.channelfocus?.infinite.delete();
|
||||
this.localuser.channelfocus = undefined;
|
||||
}
|
||||
await this.getHTML(true, false);
|
||||
console.warn(id);
|
||||
this.infinite.focus(id);
|
||||
await this.buildmessages(id);
|
||||
//debugger;
|
||||
this.infinite.focus(id, true, true);
|
||||
}
|
||||
editLast() {
|
||||
let message: Message | undefined = this.lastmessage;
|
||||
|
@ -987,7 +1010,7 @@ class Channel extends SnowFlake {
|
|||
if (!this.last_pin_timestamp && !this.lastpin) return false;
|
||||
return this.last_pin_timestamp !== this.lastpin;
|
||||
}
|
||||
async getHTML(addstate = true) {
|
||||
async getHTML(addstate = true, getMessages = true) {
|
||||
const pinnedM = document.getElementById("pinnedMDiv");
|
||||
if (pinnedM) {
|
||||
if (this.unreadPins()) {
|
||||
|
@ -1059,14 +1082,14 @@ class Channel extends SnowFlake {
|
|||
if (!mobile) {
|
||||
(document.getElementById("typebox") as HTMLDivElement).focus();
|
||||
}
|
||||
await this.putmessages();
|
||||
if (getMessages) await this.putmessages();
|
||||
await prom;
|
||||
if (id !== Channel.genid) {
|
||||
return;
|
||||
}
|
||||
this.makereplybox();
|
||||
|
||||
await this.buildmessages();
|
||||
if (getMessages) await this.buildmessages();
|
||||
//loading.classList.remove("loading");
|
||||
}
|
||||
typingmap: Map<Member, number> = new Map();
|
||||
|
@ -1354,12 +1377,12 @@ class Channel extends SnowFlake {
|
|||
}
|
||||
});
|
||||
}
|
||||
async buildmessages() {
|
||||
async buildmessages(id: string | void) {
|
||||
this.infinitefocus = false;
|
||||
await this.tryfocusinfinate();
|
||||
await this.tryfocusinfinate(id);
|
||||
}
|
||||
infinitefocus = false;
|
||||
async tryfocusinfinate() {
|
||||
async tryfocusinfinate(id: string | void) {
|
||||
if (this.infinitefocus) return;
|
||||
this.infinitefocus = true;
|
||||
const messages = document.getElementById("channelw") as HTMLDivElement;
|
||||
|
@ -1370,12 +1393,13 @@ class Channel extends SnowFlake {
|
|||
const loading = document.getElementById("loadingdiv") as HTMLDivElement;
|
||||
const removetitle = document.getElementById("removetitle");
|
||||
//messages.innerHTML="";
|
||||
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.lastmessageid && this.messages.has(this.lastmessageid)) {
|
||||
id = this.goBackIds(this.lastmessageid, 50);
|
||||
if (!id) {
|
||||
if (this.lastreadmessageid && this.messages.has(this.lastreadmessageid)) {
|
||||
id = 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);
|
||||
}
|
||||
}
|
||||
if (!id) {
|
||||
if (!removetitle) {
|
||||
|
@ -1400,8 +1424,9 @@ class Channel extends SnowFlake {
|
|||
console.warn("rouge element detected and removed");
|
||||
}
|
||||
messages.append(await this.infinite.getDiv(id));
|
||||
|
||||
this.infinite.updatestuff();
|
||||
this.infinite.watchForChange().then(async (_) => {
|
||||
await this.infinite.watchForChange().then(async (_) => {
|
||||
//await new Promise(resolve => setTimeout(resolve, 0));
|
||||
this.infinite.focus(id, false); //if someone could figure out how to make this work correctly without this, that's be great :P
|
||||
loading.classList.remove("loading");
|
||||
|
|
|
@ -54,6 +54,11 @@ class Direct extends Guild {
|
|||
}
|
||||
}
|
||||
getHTML() {
|
||||
const sideContainDiv = document.getElementById("sideContainDiv");
|
||||
if (sideContainDiv) sideContainDiv.classList.remove("searchDiv");
|
||||
const searchBox = document.getElementById("searchBox");
|
||||
if (searchBox) searchBox.textContent = "";
|
||||
|
||||
const ddiv = document.createElement("div");
|
||||
const build = super.getHTML();
|
||||
const freindDiv = document.createElement("div");
|
||||
|
|
|
@ -855,6 +855,11 @@ class Guild extends SnowFlake {
|
|||
}
|
||||
}
|
||||
getHTML() {
|
||||
const sideContainDiv = document.getElementById("sideContainDiv");
|
||||
if (sideContainDiv) sideContainDiv.classList.remove("searchDiv");
|
||||
const searchBox = document.getElementById("searchBox");
|
||||
if (searchBox) searchBox.textContent = "";
|
||||
|
||||
//this.printServers();
|
||||
this.sortchannels();
|
||||
this.printServers();
|
||||
|
|
1
src/webpage/icons/plainx.svg
Normal file
1
src/webpage/icons/plainx.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg"><path fill="#c9c9c9" stroke="red" stroke-linecap="round" stroke-width="32.2" d="M16 164 164 16M16 16l148 148"/></svg>
|
After Width: | Height: | Size: 179 B |
1
src/webpage/icons/search.svg
Normal file
1
src/webpage/icons/search.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg"><circle style="fill:none;stroke:#fe0000;stroke-width:80;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none" cx="-178" cy="177.4" r="136" transform="scale(-1 1)"/><path style="fill:none;stroke:#fe0000;stroke-width:80;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none" d="m274 280 200 192"/></svg>
|
After Width: | Height: | Size: 389 B |
|
@ -78,7 +78,10 @@
|
|||
<div id="pinnedMDiv">
|
||||
<span class="svgicon svg-pin" id="pinnedM"></span>
|
||||
</div>
|
||||
<div contenteditable="true" class="searchBox" id="searchBox"></div>
|
||||
<div class="searchMeta">
|
||||
<div contenteditable="true" class="searchBox" id="searchBox"></div>
|
||||
<span id="searchX" class="svgicon svg-search" contenteditable="false"></span>
|
||||
</div>
|
||||
<label for="memberlisttoggle" id="memberlisttoggleicon">
|
||||
<span class="svgicon svg-friends"></span>
|
||||
</label>
|
||||
|
|
|
@ -149,13 +149,32 @@ import {I18n} from "./i18n.js";
|
|||
const searchBox = document.getElementById("searchBox") as CustomHTMLDivElement;
|
||||
const markdown = new MarkDown("", thisUser);
|
||||
searchBox.markdown = markdown;
|
||||
|
||||
const searchX = document.getElementById("searchX") as HTMLElement;
|
||||
searchBox.addEventListener("keydown", (event) => {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
thisUser.mSearch(markdown.rawString);
|
||||
}
|
||||
});
|
||||
searchBox.addEventListener("keyup", () => {
|
||||
if (searchBox.textContent === "") {
|
||||
setTimeout(() => (searchBox.innerHTML = ""), 0);
|
||||
searchX.classList.add("svg-search");
|
||||
searchX.classList.remove("svg-plainx");
|
||||
} else {
|
||||
searchX.classList.remove("svg-search");
|
||||
searchX.classList.add("svg-plainx");
|
||||
}
|
||||
});
|
||||
searchX.onclick = () => {
|
||||
if (searchX.classList.contains("svg-plainx")) {
|
||||
markdown.txt = [];
|
||||
searchBox.innerHTML = "";
|
||||
searchX.classList.add("svg-search");
|
||||
searchX.classList.remove("svg-plainx");
|
||||
thisUser.mSearch("");
|
||||
}
|
||||
};
|
||||
|
||||
markdown.giveBox(searchBox);
|
||||
markdown.setCustomBox((e) => {
|
||||
|
|
|
@ -242,7 +242,18 @@ class InfiniteScroller {
|
|||
}
|
||||
}
|
||||
|
||||
async watchForChange(): Promise<boolean> {
|
||||
async watchForChange(stop = false): Promise<boolean> {
|
||||
if (stop == true) {
|
||||
let prom = this.changePromise;
|
||||
while (this.changePromise) {
|
||||
prom = this.changePromise;
|
||||
await this.changePromise;
|
||||
if (prom === this.changePromise) {
|
||||
this.changePromise = undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.changePromise) {
|
||||
this.watchtime = true;
|
||||
return await this.changePromise;
|
||||
|
@ -268,6 +279,10 @@ class InfiniteScroller {
|
|||
console.error(e);
|
||||
res(false);
|
||||
} finally {
|
||||
if (stop === true) {
|
||||
this.changePromise = undefined;
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.changePromise = undefined;
|
||||
if (this.watchtime) {
|
||||
|
@ -279,17 +294,18 @@ class InfiniteScroller {
|
|||
|
||||
return await this.changePromise;
|
||||
}
|
||||
async focus(id: string, flash = true): Promise<void> {
|
||||
async focus(id: string, flash = true, sec = false): Promise<void> {
|
||||
let element: HTMLElement | undefined;
|
||||
for (const thing of this.HTMLElements) {
|
||||
if (thing[1] === id) {
|
||||
element = thing[0];
|
||||
}
|
||||
}
|
||||
if (element) {
|
||||
if (sec && element) {
|
||||
if (flash) {
|
||||
element.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
inline: "center",
|
||||
block: "center",
|
||||
});
|
||||
await new Promise((resolve) => {
|
||||
|
@ -301,9 +317,11 @@ class InfiniteScroller {
|
|||
});
|
||||
element.classList.add("jumped");
|
||||
} else {
|
||||
element.scrollIntoView();
|
||||
element.scrollIntoView({
|
||||
block: "center",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
} else if (!sec) {
|
||||
this.resetVars();
|
||||
//TODO may be a redundant loop, not 100% sure :P
|
||||
for (const thing of this.HTMLElements) {
|
||||
|
@ -312,11 +330,16 @@ class InfiniteScroller {
|
|||
this.HTMLElements = [];
|
||||
await this.firstElement(id);
|
||||
this.updatestuff();
|
||||
await this.watchForChange();
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 100);
|
||||
await this.watchForChange(true);
|
||||
this.changePromise = new Promise<boolean>((resolve) => {
|
||||
setTimeout(() => {
|
||||
this.changePromise = undefined;
|
||||
resolve(true);
|
||||
}, 1000);
|
||||
});
|
||||
await this.focus(id, true);
|
||||
await this.focus(id, !element, true);
|
||||
} else {
|
||||
console.warn("elm not exist");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -240,6 +240,7 @@ class Localuser {
|
|||
this.rights = new Rights(rights);
|
||||
|
||||
if (this.perminfo.user.disableColors === undefined) this.perminfo.user.disableColors = true;
|
||||
this.updateTranslations();
|
||||
}
|
||||
async gottenReady(ready: readyjson): Promise<void> {
|
||||
await I18n.done;
|
||||
|
@ -1751,6 +1752,7 @@ class Localuser {
|
|||
I18n.getTranslation("localuser.language"),
|
||||
(e) => {
|
||||
I18n.setLanguage(I18n.options()[e]);
|
||||
this.updateTranslations();
|
||||
},
|
||||
[...langmap.values()],
|
||||
{
|
||||
|
@ -2671,51 +2673,140 @@ class Localuser {
|
|||
box.innerHTML = "";
|
||||
}
|
||||
searching = false;
|
||||
updateTranslations() {
|
||||
const searchBox = document.getElementById("searchBox") as HTMLDivElement;
|
||||
searchBox.style.setProperty("--hint-text", JSON.stringify(I18n.search.search()));
|
||||
}
|
||||
curSearch?: Symbol;
|
||||
mSearch(query: string) {
|
||||
const searchy = Symbol("search");
|
||||
this.curSearch = searchy;
|
||||
const p = new URLSearchParams("?");
|
||||
this.searching = true;
|
||||
p.set("content", query.trim());
|
||||
fetch(this.info.api + `/guilds/${this.lookingguild?.id}/messages/search/?` + p.toString(), {
|
||||
headers: this.headers,
|
||||
})
|
||||
.then((_) => _.json())
|
||||
.then((json: {messages: [messagejson][]; total_results: number}) => {
|
||||
//FIXME total_results shall be ignored as it's known to be bad, spacebar bug.
|
||||
const messages = json.messages
|
||||
.map(([m]) => {
|
||||
const c = this.channelids.get(m.channel_id);
|
||||
if (!c) return;
|
||||
if (c.messages.get(m.id)) {
|
||||
return c.messages.get(m.id);
|
||||
}
|
||||
return new Message(m, c, true);
|
||||
})
|
||||
.filter((_) => _ !== undefined);
|
||||
const sideDiv = document.getElementById("sideDiv");
|
||||
const sideContainDiv = document.getElementById("sideContainDiv");
|
||||
if (!sideDiv || !sideContainDiv) return;
|
||||
sideDiv.innerHTML = "";
|
||||
sideContainDiv.classList.add("searchDiv");
|
||||
let channel: Channel | undefined = undefined;
|
||||
for (const message of messages) {
|
||||
if (channel !== message.channel) {
|
||||
channel = message.channel;
|
||||
const h3 = document.createElement("h3");
|
||||
h3.textContent = channel.name;
|
||||
h3.classList.add("channelSTitle");
|
||||
sideDiv.append(h3);
|
||||
p.set("sort_by", "timestamp");
|
||||
p.set("sort_order", "desc");
|
||||
let maxpage: undefined | number = undefined;
|
||||
const sideDiv = document.getElementById("sideDiv");
|
||||
const sideContainDiv = document.getElementById("sideContainDiv");
|
||||
if (!sideDiv || !sideContainDiv) return;
|
||||
const genPage = (page: number) => {
|
||||
p.set("offset", page * 50 + "");
|
||||
fetch(this.info.api + `/guilds/${this.lookingguild?.id}/messages/search/?` + p.toString(), {
|
||||
headers: this.headers,
|
||||
})
|
||||
.then((_) => _.json())
|
||||
.then((json: {messages: [messagejson][]; total_results: number}) => {
|
||||
if (this.curSearch !== searchy) {
|
||||
return;
|
||||
}
|
||||
const html = message.buildhtml(undefined, true);
|
||||
html.addEventListener("click", async () => {
|
||||
try {
|
||||
await message.channel.focus(message.id);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
//FIXME total_results shall be ignored as it's known to be bad, spacebar bug.
|
||||
const messages = json.messages
|
||||
.map(([m]) => {
|
||||
const c = this.channelids.get(m.channel_id);
|
||||
if (!c) return;
|
||||
if (c.messages.get(m.id)) {
|
||||
return c.messages.get(m.id);
|
||||
}
|
||||
return new Message(m, c, true);
|
||||
})
|
||||
.filter((_) => _ !== undefined);
|
||||
sideDiv.innerHTML = "";
|
||||
if (messages.length == 0 && page !== 0) {
|
||||
maxpage = page - 1;
|
||||
genPage(page - 1);
|
||||
return;
|
||||
} else if (messages.length !== 50) {
|
||||
maxpage = page;
|
||||
}
|
||||
const sortBar = document.createElement("div");
|
||||
sortBar.classList.add("flexltr", "sortBar");
|
||||
|
||||
const newB = document.createElement("button");
|
||||
const old = document.createElement("button");
|
||||
[newB.textContent, old.textContent] = [I18n.search.new(), I18n.search.old()];
|
||||
old.onclick = () => {
|
||||
p.set("sort_order", "asc");
|
||||
deleteMessages();
|
||||
genPage(0);
|
||||
};
|
||||
newB.onclick = () => {
|
||||
p.set("sort_order", "desc");
|
||||
deleteMessages();
|
||||
genPage(0);
|
||||
};
|
||||
if (p.get("sort_order") === "asc") {
|
||||
old.classList.add("selectedB");
|
||||
} else {
|
||||
newB.classList.add("selectedB");
|
||||
}
|
||||
|
||||
const spaceElm = document.createElement("div");
|
||||
spaceElm.classList.add("spaceElm");
|
||||
|
||||
sortBar.append(I18n.search.page(page + 1 + ""), spaceElm, newB, old);
|
||||
|
||||
sideDiv.append(sortBar);
|
||||
|
||||
sideContainDiv.classList.add("searchDiv");
|
||||
let channel: Channel | undefined = undefined;
|
||||
function deleteMessages() {
|
||||
for (const elm of htmls) elm.remove();
|
||||
}
|
||||
const htmls: HTMLElement[] = [];
|
||||
for (const message of messages) {
|
||||
if (channel !== message.channel) {
|
||||
channel = message.channel;
|
||||
const h3 = document.createElement("h3");
|
||||
h3.textContent = channel.name;
|
||||
h3.classList.add("channelSTitle");
|
||||
sideDiv.append(h3);
|
||||
htmls.push(h3);
|
||||
}
|
||||
});
|
||||
sideDiv.append(html);
|
||||
}
|
||||
});
|
||||
const html = message.buildhtml(undefined, true);
|
||||
html.addEventListener("click", async () => {
|
||||
try {
|
||||
await message.channel.focus(message.id);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
sideDiv.append(html);
|
||||
htmls.push(html);
|
||||
}
|
||||
if (messages.length === 0) {
|
||||
const noMs = document.createElement("h3");
|
||||
noMs.textContent = I18n.search.nofind();
|
||||
sideDiv.append(noMs);
|
||||
}
|
||||
const bottombuttons = document.createElement("div");
|
||||
bottombuttons.classList.add("flexltr", "searchNavButtons");
|
||||
const next = document.createElement("button");
|
||||
if (page == maxpage) next.disabled = true;
|
||||
next.onclick = () => {
|
||||
deleteMessages();
|
||||
genPage(page + 1);
|
||||
};
|
||||
const prev = document.createElement("button");
|
||||
prev.onclick = () => {
|
||||
deleteMessages();
|
||||
genPage(page - 1);
|
||||
};
|
||||
if (page == 0) prev.disabled = true;
|
||||
[next.textContent, prev.textContent] = [I18n.search.next(), I18n.search.back()];
|
||||
bottombuttons.append(prev, next);
|
||||
sideDiv.append(bottombuttons);
|
||||
sideDiv.scrollTo({top: 0, behavior: "instant"});
|
||||
});
|
||||
};
|
||||
if (query === "") {
|
||||
sideContainDiv.classList.remove("searchDiv");
|
||||
sideDiv.innerHTML = "";
|
||||
this.searching = false;
|
||||
this.getSidePannel();
|
||||
return;
|
||||
}
|
||||
genPage(0);
|
||||
}
|
||||
|
||||
keydown: (event: KeyboardEvent) => unknown = () => {};
|
||||
|
|
|
@ -57,16 +57,52 @@ body {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.searchNavButtons {
|
||||
height: 0.3in;
|
||||
flex-shrink: 0;
|
||||
background: var(--secondary-bg);
|
||||
top: 0px;
|
||||
padding: 0.1in;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: auto;
|
||||
|
||||
button {
|
||||
flex-shrink: 0;
|
||||
margin-left: 0.1in;
|
||||
}
|
||||
}
|
||||
.sortBar {
|
||||
height: 0.3in;
|
||||
flex-shrink: 0;
|
||||
background: var(--secondary-bg);
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
padding: 0.1in;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
z-index: 1;
|
||||
|
||||
button {
|
||||
flex-shrink: 0;
|
||||
margin-left: 0.1in;
|
||||
}
|
||||
}
|
||||
.selectedB {
|
||||
background: color-mix(in srgb, black, var(--button-bg) 60%);
|
||||
}
|
||||
.pinnedMessages {
|
||||
position: absolute;
|
||||
background: var(--secondary-bg);
|
||||
width: 3.5in;
|
||||
padding: 8px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 1px 1px 10px black;
|
||||
box-shadow: 1px 3px 10px var(--shadow);
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
min-height: 1in;
|
||||
z-index: 2;
|
||||
|
||||
b {
|
||||
width: 100%;
|
||||
height: 1in;
|
||||
|
@ -129,6 +165,7 @@ body {
|
|||
.channelSTitle {
|
||||
margin-top: 0.2in;
|
||||
margin-bottom: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
p,
|
||||
h1,
|
||||
|
@ -352,6 +389,14 @@ textarea {
|
|||
display: block;
|
||||
mask-size: cover !important;
|
||||
}
|
||||
.svg-plainx {
|
||||
mask: url(/icons/plainx.svg);
|
||||
mask-size: contain !important;
|
||||
}
|
||||
.svg-search {
|
||||
mask: url(/icons/search.svg);
|
||||
mask-size: contain !important;
|
||||
}
|
||||
.svg-spoiler {
|
||||
mask: url(/icons/spoiler.svg);
|
||||
}
|
||||
|
@ -458,6 +503,16 @@ textarea {
|
|||
aspect-ratio: 1/1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
#searchX {
|
||||
width: 0.16in;
|
||||
height: 0.16in;
|
||||
position: absolute;
|
||||
right: 13px;
|
||||
top: 6px;
|
||||
}
|
||||
#searchX.svg-plainx{
|
||||
cursor:pointer;
|
||||
}
|
||||
#pinnedM {
|
||||
width: 0.25in;
|
||||
height: 0.25in;
|
||||
|
@ -891,7 +946,10 @@ span.instanceStatus {
|
|||
background: var(--channels-bg);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.searchMeta {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
.header {
|
||||
flex: none;
|
||||
height: 48px;
|
||||
|
@ -1225,6 +1283,10 @@ span.instanceStatus {
|
|||
.searchBox:empty {
|
||||
width: 2in;
|
||||
}
|
||||
.searchBox:empty::after {
|
||||
content: var(--hint-text);
|
||||
color: var(--primary-text-soft);
|
||||
}
|
||||
.searchBox {
|
||||
white-space: nowrap;
|
||||
height: 0.075in;
|
||||
|
@ -1739,6 +1801,7 @@ img.bigembedimg {
|
|||
|
||||
/* Sidebar */
|
||||
#sideContainDiv {
|
||||
padding: 16px 8px;
|
||||
display: none;
|
||||
flex: none;
|
||||
width: 240px;
|
||||
|
@ -1747,17 +1810,22 @@ img.bigembedimg {
|
|||
justify-content: space-between;
|
||||
}
|
||||
#sideDiv {
|
||||
padding: 16px 8px;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
#page:has(#memberlisttoggle:checked) #sideContainDiv {
|
||||
display: flex;
|
||||
}
|
||||
#sideContainDiv.searchDiv {
|
||||
padding: 0px;
|
||||
display: flex;
|
||||
width: 30vw;
|
||||
|
||||
.topMessage {
|
||||
margin: 0px 10px;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
|
@ -2033,6 +2101,7 @@ img.bigembedimg {
|
|||
height: 100%;
|
||||
width: 100%;
|
||||
background: color-mix(in srgb, var(--black) 75%, transparent);
|
||||
z-index: 2;
|
||||
}
|
||||
.imgfit {
|
||||
max-height: 85svh;
|
||||
|
|
|
@ -380,6 +380,15 @@
|
|||
"mustTypePhrase": "To delete your account you must type the phrase",
|
||||
"manageInstance": "Manage Instance"
|
||||
},
|
||||
"search": {
|
||||
"back": "Back",
|
||||
"next": "Next",
|
||||
"page": "Page $1",
|
||||
"new": "New",
|
||||
"old": "Old",
|
||||
"search": "Search",
|
||||
"nofind": "There seems to be no messages that match your search, maybe trying broadening your search to try and find what you want"
|
||||
},
|
||||
"manageInstance": {
|
||||
"stop": "Stop instance",
|
||||
"AreYouSureStop": "Are you sure you want to stop this instance?",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue