use event communication instead of variable checking for cross-window dragging = less-buggy

This commit is contained in:
dragonwocky 2020-10-19 22:03:54 +11:00
parent 1d1503c826
commit b2491a0a09
Signed by: dragonwocky
GPG Key ID: C7A48B7846AA706D
2 changed files with 79 additions and 45 deletions

View File

@ -86,10 +86,16 @@ module.exports = (store, __exports) => {
}; };
document.addEventListener('dragstart', (event) => { document.addEventListener('dragstart', (event) => {
if (!this.$titlebar) return; if (!this.$titlebar) return;
this.$dragging = getTab(event.target)[0]; const tab = getTab(event.target);
this.$dragging = tab[0];
event.dataTransfer.setData( event.dataTransfer.setData(
'text', 'text',
document.getElementById(getTab(event.target)[0]).src JSON.stringify({
target: electron.remote.getCurrentWindow().webContents.id,
tab: tab[0],
title: tab[1].children[0].innerText,
url: document.getElementById(getTab(event.target)[0]).src,
})
); );
event.target.style.opacity = 0.5; event.target.style.opacity = 0.5;
}); });
@ -99,10 +105,6 @@ module.exports = (store, __exports) => {
document document
.querySelectorAll('.dragged-over') .querySelectorAll('.dragged-over')
.forEach((el) => el.classList.remove('dragged-over')); .forEach((el) => el.classList.remove('dragged-over'));
if (this.$dragging !== null) {
this.closeTab(this.$dragging);
this.$dragging = null;
}
}); });
document.addEventListener('dragover', (event) => { document.addEventListener('dragover', (event) => {
if (!this.$titlebar) return; if (!this.$titlebar) return;
@ -110,40 +112,50 @@ module.exports = (store, __exports) => {
document document
.querySelectorAll('.dragged-over') .querySelectorAll('.dragged-over')
.forEach((el) => el.classList.remove('dragged-over')); .forEach((el) => el.classList.remove('dragged-over'));
const tab = getTab(event.target); const tab = getTab(event.target)[1];
if (tab[1]) tab[1].classList.add('dragged-over'); if (tab) tab.classList.add('dragged-over');
}); });
document.addEventListener('drop', (event) => { document.addEventListener('drop', async (event) => {
event.preventDefault(); event.preventDefault();
if (this.$dragging === null) { const eventData = JSON.parse(event.dataTransfer.getData('text'));
console.log(event.dataTransfer.getData('text')); if (
if (event.dataTransfer.getData('text').startsWith('notion://')) eventData.target !==
this.newTab(event.dataTransfer.getData('text')); electron.remote.getCurrentWindow().webContents.id
} else { ) {
if (this.$titlebar) { electron.ipcRenderer.send(
const from = getTab(this.views.tabs[+this.$dragging]), 'enhancer:close-tab',
to = getTab(event.target); eventData.target,
if (from[0] !== to[0]) { eventData.tab
if (to[1].classList.contains('new')) { );
const list = new Map(this.state.tabs); this.$dragging = await this.newTab(
list.delete(from[0]); eventData.url,
list.set(from[0], this.state.tabs.get(from[0])); eventData.title,
this.setState({ tabs: list }); false
} else { );
const list = [...this.state.tabs], }
fromIndex = list.findIndex( if (this.$titlebar) {
([id, { title, open }]) => id === from[0] const from = getTab(this.views.tabs[+this.$dragging]),
), to = getTab(event.target);
toIndex = list.findIndex( if (from[0] !== to[0]) {
([id, { title, open }]) => id === to[0] if (to[1].classList.contains('new')) {
); const list = new Map(this.state.tabs);
list.splice( list.delete(from[0]);
toIndex > fromIndex ? toIndex - 1 : toIndex, list.set(from[0], this.state.tabs.get(from[0]));
0, this.setState({ tabs: list });
list.splice(fromIndex, 1)[0] } else {
const list = [...this.state.tabs],
fromIndex = list.findIndex(
([id, { title, open }]) => id === from[0]
),
toIndex = list.findIndex(
([id, { title, open }]) => id === to[0]
); );
this.setState({ tabs: new Map(list) }); list.splice(
} toIndex > fromIndex ? toIndex - 1 : toIndex,
0,
list.splice(fromIndex, 1)[0]
);
this.setState({ tabs: new Map(list) });
} }
} }
this.$dragging = null; this.$dragging = null;
@ -192,6 +204,9 @@ module.exports = (store, __exports) => {
if (triggered && document.querySelector('.tab.current .close')) if (triggered && document.querySelector('.tab.current .close'))
document.querySelector('.tab.current .close').click(); document.querySelector('.tab.current .close').click();
}); });
electron.ipcRenderer.on('enhancer:close-tab', (event, tab) => {
this.closeTab(tab);
});
} }
componentDidMount() { componentDidMount() {
@ -233,12 +248,17 @@ module.exports = (store, __exports) => {
}); });
} }
newTab(url = '') { newTab(url = '', title = 'notion.so', animate = true) {
let id = 0; let id = 0;
const list = new Map(this.state.tabs); const list = new Map(this.state.tabs);
while (this.state.tabs.get(id) && this.state.tabs.get(id).open) id++; while (this.state.tabs.get(id) && this.state.tabs.get(id).open) id++;
list.delete(id); list.delete(id);
return this.openTab(id, { state: list, load: url || true }); return this.openTab(id, {
state: list,
load: url || true,
title,
animate,
});
} }
openTab( openTab(
id, id,
@ -246,15 +266,19 @@ module.exports = (store, __exports) => {
state = new Map(this.state.tabs), state = new Map(this.state.tabs),
slideOut = new Set(this.state.slideOut), slideOut = new Set(this.state.slideOut),
load, load,
animate,
title = 'notion.so',
} = { } = {
state: new Map(this.state.tabs), state: new Map(this.state.tabs),
slideOut: new Set(this.state.slideOut), slideOut: new Set(this.state.slideOut),
load: false, load: false,
title: 'notion.so',
animate: false,
} }
) { ) {
return new Promise((res, rej) => { return new Promise((res, rej) => {
if (!id && id !== 0) { if (!id && id !== 0) {
if (state.get(this.views.current.id).open) return res(true); if (state.get(this.views.current.id).open) return res(id);
const currentIndex = [...state].findIndex( const currentIndex = [...state].findIndex(
([id, { title, open }]) => id === this.views.current.id ([id, { title, open }]) => id === this.views.current.id
); );
@ -268,10 +292,12 @@ module.exports = (store, __exports) => {
this.setState( this.setState(
{ {
tabs: state.set(id, { tabs: state.set(id, {
title: state.get(id) ? state.get(id).title : 'notion.so', title: state.get(id) ? state.get(id).title : title,
open: true, open: true,
}), }),
slideIn: load ? this.state.slideIn.add(id) : this.state.slideIn, slideIn: animate
? this.state.slideIn.add(id)
: this.state.slideIn,
slideOut: slideOut, slideOut: slideOut,
}, },
async () => { async () => {
@ -319,7 +345,7 @@ module.exports = (store, __exports) => {
setTimeout(() => { setTimeout(() => {
this.setState( this.setState(
{ slideIn: new Set(), slideOut: new Set() }, { slideIn: new Set(), slideOut: new Set() },
() => res(true) () => res(id)
); );
}, 150); }, 150);
}); });
@ -421,8 +447,11 @@ module.exports = (store, __exports) => {
this.newTab(event.args[0]); this.newTab(event.args[0]);
break; break;
case 'enhancer:close-tab': case 'enhancer:close-tab':
if (document.querySelector('.tab.current .close')) this.closeTab(
document.querySelector('.tab.current .close').click(); event.args[0] || event.args[0] === 0
? event.args[0]
: this.views.current.id
);
break; break;
} }
} }

View File

@ -46,6 +46,11 @@ module.exports = (store, __exports) => {
webContents.send('enhancer:get-menu-theme', arg) webContents.send('enhancer:get-menu-theme', arg)
); );
}); });
electron.ipcMain.on('enhancer:close-tab', (event, target, tab) => {
electron.webContents
.fromId(target)
.webContents.send('enhancer:close-tab', tab);
});
function calculateWindowPos(width, height) { function calculateWindowPos(width, height) {
const screen = electron.screen.getDisplayNearestPoint({ const screen = electron.screen.getDisplayNearestPoint({