better drag and drop and various fixes

This commit is contained in:
MathMan05 2025-04-30 21:55:40 -05:00
parent ea8d9978a6
commit 7a93e5f9b5
4 changed files with 117 additions and 18 deletions

View file

@ -633,17 +633,28 @@ class Channel extends SnowFlake {
decoration.classList.add("hiddencat"); decoration.classList.add("hiddencat");
childrendiv.style.height = "0px"; childrendiv.style.height = "0px";
} }
decdiv.onclick = () => { const handleColapse = async (animate: boolean = true) => {
if (childrendiv.style.height !== "0px") { if (this.perminfo.collapsed) {
decoration.classList.add("hiddencat"); decoration.classList.add("hiddencat");
this.perminfo.collapsed = true; childrendiv.style.height = childrendiv.scrollHeight + "px";
await new Promise((res) => setTimeout(res, 0));
childrendiv.style.height = "0px"; childrendiv.style.height = "0px";
} else { } else {
decoration.classList.remove("hiddencat"); decoration.classList.remove("hiddencat");
this.perminfo.collapsed = false; if (childrendiv.style.height === "0px" && animate) {
childrendiv.style.height = childrendiv.scrollHeight + "px"; childrendiv.style.height = childrendiv.scrollHeight + "px";
} else {
childrendiv.style.removeProperty("height");
}
} }
}; };
const observer = new MutationObserver(handleColapse.bind(this, false));
observer.observe(childrendiv, {childList: true, subtree: true});
decdiv.onclick = () => {
this.perminfo.collapsed = !this.perminfo.collapsed;
handleColapse();
};
} else { } else {
div.classList.add("channel"); div.classList.add("channel");
this.unreads(); this.unreads();
@ -786,27 +797,42 @@ class Channel extends SnowFlake {
} }
} }
coatDropDiv(div: HTMLDivElement, container: HTMLElement | boolean = false) { coatDropDiv(div: HTMLDivElement, container: HTMLElement | false = false) {
div.addEventListener("dragenter", (event) => { div.addEventListener("dragenter", (event) => {
console.log("enter"); console.log("enter");
event.preventDefault(); event.preventDefault();
}); });
div.addEventListener("dragover", (event) => { div.addEventListener("dragover", (event) => {
const height = div.getBoundingClientRect().height;
if (event.offsetY / height < 0.5) {
div.classList.add("dragTopView");
div.classList.remove("dragBottomView");
} else {
div.classList.remove("dragTopView");
div.classList.add("dragBottomView");
}
event.preventDefault(); event.preventDefault();
}); });
div.addEventListener("dragleave", () => {
div.classList.remove("dragTopView");
div.classList.remove("dragBottomView");
});
div.addEventListener("drop", (event) => { div.addEventListener("drop", (event) => {
div.classList.remove("dragTopView");
div.classList.remove("dragBottomView");
const that = Channel.dragged[0]; const that = Channel.dragged[0];
if (!that) return; if (!that) return;
event.preventDefault(); event.preventDefault();
if (container && that.type !== 4) { const height = div.getBoundingClientRect().height;
const before = event.offsetY / height < 0.5;
if (container && that.type !== 4 && !before) {
that.move_id = this.id; that.move_id = this.id;
if (that.parent) { if (that.parent) {
that.parent.children.splice(that.parent.children.indexOf(that), 1); that.parent.children.splice(that.parent.children.indexOf(that), 1);
} }
that.parent = this; that.parent = this;
(container as HTMLElement).prepend(Channel.dragged[1] as HTMLDivElement); container.prepend(Channel.dragged[1] as HTMLDivElement);
this.children.unshift(that); this.children.unshift(that);
} else { } else {
console.log(this, Channel.dragged); console.log(this, Channel.dragged);
@ -830,23 +856,32 @@ class Channel extends SnowFlake {
for (let i = 0; i < that.parent.children.length; i++) { for (let i = 0; i < that.parent.children.length; i++) {
build.push(that.parent.children[i]); build.push(that.parent.children[i]);
if (that.parent.children[i] === thisy) { if (that.parent.children[i] === thisy) {
if (before) build.pop();
build.push(that); build.push(that);
if (before) build.push(thisy);
} }
} }
that.parent.children = build; that.parent.children = build;
console.log(build);
} else { } else {
const build: Channel[] = []; const build: Channel[] = [];
for (let i = 0; i < thisy.guild.headchannels.length; i++) { for (let i = 0; i < thisy.guild.headchannels.length; i++) {
build.push(thisy.guild.headchannels[i]); build.push(thisy.guild.headchannels[i]);
if (thisy.guild.headchannels[i] === thisy) { if (thisy.guild.headchannels[i] === thisy) {
if (before) build.pop();
build.push(that); build.push(that);
if (before) build.push(thisy);
} }
} }
thisy.guild.headchannels = build; thisy.guild.headchannels = build;
} }
if (Channel.dragged[1]) { if (Channel.dragged[1]) {
if (this === thisy && this.type !== 4) { if (this === thisy && this.type !== 4) {
div.after(Channel.dragged[1]); if (before) {
div.before(Channel.dragged[1]);
} else {
div.after(Channel.dragged[1]);
}
} else { } else {
div = div.parentElement as HTMLDivElement; div = div.parentElement as HTMLDivElement;
if (!div) return; if (!div) return;
@ -855,11 +890,15 @@ class Channel extends SnowFlake {
console.log(div); console.log(div);
Channel.dragged[1].remove(); Channel.dragged[1].remove();
div.after(Channel.dragged[1]); if (before) {
div.before(Channel.dragged[1]);
} else {
div.after(Channel.dragged[1]);
}
} }
} }
} }
this.guild.calculateReorder(); this.guild.calculateReorder(that.id);
}); });
return div; return div;

View file

@ -1149,18 +1149,19 @@ class Guild extends SnowFlake {
let build = ""; let build = "";
for (const thing of this.headchannels) { for (const thing of this.headchannels) {
build += thing.name + ":" + thing.position + "\n"; build += thing.name + ":" + thing.position + "\n";
console.log(thing.children);
for (const thingy of thing.children) { for (const thingy of thing.children) {
build += " " + thingy.name + ":" + thingy.position + "\n"; build += " " + thingy.name + ":" + thingy.position + "\n";
} }
} }
console.log(build); console.log(build);
} }
calculateReorder() { calculateReorder(movedId?: string) {
let position = -1; let position = -1;
const build: { const build: {
id: string; id: string;
position: number | undefined; position: number | undefined;
parent_id: string | undefined; parent_id: string | undefined | null;
}[] = []; }[] = [];
for (const thing of this.headchannels) { for (const thing of this.headchannels) {
const thisthing: { const thisthing: {
@ -1188,6 +1189,18 @@ class Guild extends SnowFlake {
} }
} }
} }
const find = build.find((_) => _.id === movedId);
const channel = this.channels.find((_) => _.id === movedId);
if (!find) {
if (channel)
build.push({
id: channel.id,
position: channel.position,
parent_id: channel.parent?.id || null,
});
} else {
if (channel) find.parent_id = channel.parent?.id || null;
}
console.log(build); console.log(build);
this.printServers(); this.printServers();
if (build.length === 0) { if (build.length === 0) {
@ -1489,6 +1502,10 @@ class Guild extends SnowFlake {
this.headchannels.push(thing); this.headchannels.push(thing);
} }
} }
for (const channel of this.channels) {
channel.children = channel.children.sort((a, b) => a.position - b.position);
}
this.channels = this.channels.sort((a, b) => a.position - b.position);
this.printServers(); this.printServers();
} }
} }

View file

@ -274,6 +274,9 @@ class RoleList extends Buttons {
headers: this.headers, headers: this.headers,
}); });
}, },
{
visable: (role) => role.id !== role.guild.id,
},
); );
return menu; return menu;
} }
@ -296,6 +299,7 @@ class RoleList extends Buttons {
buttonRoleMap = new WeakMap<HTMLButtonElement, Role>(); buttonRoleMap = new WeakMap<HTMLButtonElement, Role>();
dragged?: HTMLButtonElement; dragged?: HTMLButtonElement;
buttonDragEvents(button: HTMLButtonElement, role: Role) { buttonDragEvents(button: HTMLButtonElement, role: Role) {
const height = 35;
this.buttonRoleMap.set(button, role); this.buttonRoleMap.set(button, role);
button.addEventListener("dragstart", (e) => { button.addEventListener("dragstart", (e) => {
this.dragged = button; this.dragged = button;
@ -307,23 +311,38 @@ class RoleList extends Buttons {
}); });
button.addEventListener("dragenter", (event) => { button.addEventListener("dragenter", (event) => {
console.log("enter");
event.preventDefault(); event.preventDefault();
return true; return true;
}); });
button.addEventListener("dragover", (event) => { button.addEventListener("dragover", (event) => {
event.preventDefault(); event.preventDefault();
if (event.offsetY / height < 0.5) {
button.classList.add("dragTopView");
button.classList.remove("dragBottomView");
} else {
button.classList.remove("dragTopView");
button.classList.add("dragBottomView");
}
return true; return true;
}); });
button.addEventListener("dragleave", () => {
button.classList.remove("dragTopView");
button.classList.remove("dragBottomView");
});
button.addEventListener("drop", (_) => { button.addEventListener("drop", (event) => {
const role2 = this.buttonRoleMap.get(this.dragged as HTMLButtonElement); const role2 = this.buttonRoleMap.get(this.dragged as HTMLButtonElement);
if (!role2) return; if (!role2 || this.dragged === button) return;
const index2 = this.guild.roles.indexOf(role2); const index2 = this.guild.roles.indexOf(role2);
this.guild.roles.splice(index2, 1); this.guild.roles.splice(index2, 1);
const index = this.guild.roles.indexOf(role); const index = this.guild.roles.indexOf(role);
this.guild.roles.splice(index + 1, 0, role2); if (event.offsetY / height < 0.5) {
this.guild.roles.splice(index, 0, role2);
} else {
this.guild.roles.splice(index + 1, 0, role2);
}
this.guild.recalcRoles(); this.guild.recalcRoles();
console.log(role); console.log(role);
}); });

View file

@ -1046,6 +1046,7 @@ span.instanceStatus {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-bottom: 2px; margin-bottom: 2px;
position: relative;
} }
.channelbutton { .channelbutton {
height: 2em; height: 2em;
@ -1939,6 +1940,8 @@ img.bigembedimg {
background: var(--secondary-bg); background: var(--secondary-bg);
border-radius: 4px; border-radius: 4px;
box-shadow: 0 0 8px var(--shadow); box-shadow: 0 0 8px var(--shadow);
z-index: 2;
hr { hr {
width: 90%; width: 90%;
height: 1px; height: 1px;
@ -2424,6 +2427,7 @@ fieldset input[type="radio"] {
color: var(--primary-text-soft); color: var(--primary-text-soft);
border: none; border: none;
transition: background 0.1s; transition: background 0.1s;
position: relative;
} }
.activeSetting { .activeSetting {
background: color-mix(in srgb, var(--secondary-bg) 60%, transparent); background: color-mix(in srgb, var(--secondary-bg) 60%, transparent);
@ -3052,6 +3056,26 @@ img.error::after {
top: 0; top: 0;
left: 0; left: 0;
} }
.dragTopView::after {
content: "";
width: 100%;
height: 4px;
border-radius: 4px;
background: var(--primary-text-soft);
top: -1px;
left: 0px;
position: absolute;
}
.dragBottomView::after {
content: "";
width: 100%;
height: 4px;
border-radius: 4px;
background: var(--primary-text-soft);
bottom: -3px;
left: 0px;
position: absolute;
}
.gifBox { .gifBox {
img { img {
max-width: 196px; max-width: 196px;