Skip to content

Commit b2172de

Browse files
author
topboy
committed
history navigation (channels, settings, serverbuf)
1 parent c78473d commit b2172de

File tree

5 files changed

+167
-26
lines changed

5 files changed

+167
-26
lines changed

src/components/App.vue

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,19 +178,46 @@ export default {
178178
},
179179
listenForActiveComponents() {
180180
this.listen(this.$state, 'active.component', (component, props) => {
181-
this.activeComponent = null;
182181
if (component) {
183-
this.activeComponentProps = props;
184-
this.activeComponent = component;
182+
this.activeComponent = null;
183+
this.$state.history.push({
184+
enter: () => {
185+
this.activeComponent = component;
186+
this.activeComponentProps = props;
187+
},
188+
leave: () => {
189+
this.activeComponent = null;
190+
},
191+
query: {
192+
view: '',
193+
},
194+
});
195+
} else if (this.$state.history.currentPage) {
196+
// this.state.history.currentPage &&
197+
this.$state.history.go(-1);
198+
} else {
199+
this.activeComponent = null;
185200
}
201+
this.$state.activeComponent = this.activeComponent;
186202
});
187203
this.listen(this.$state, 'active.component.toggle', (component, props) => {
188204
if (component === this.activeComponent) {
189-
this.activeComponent = null;
205+
this.$state.history.go(-1);
190206
} else if (component) {
191-
this.activeComponentProps = props;
192-
this.activeComponent = component;
207+
this.$state.history.push({
208+
enter: () => {
209+
this.activeComponent = component;
210+
this.activeComponentProps = props;
211+
},
212+
leave: () => {
213+
this.activeComponent = null;
214+
},
215+
query: {
216+
view: '',
217+
},
218+
});
193219
}
220+
this.$state.activeComponent = this.activeComponent;
194221
});
195222
},
196223
watchForThemes() {
@@ -328,7 +355,7 @@ export default {
328355
},
329356
scrollToBottom() {
330357
if (this.$state?.ml?.scrollToBottom instanceof Function) {
331-
this.$state.ml.scrollToBottom();
358+
this.$state.$emit('messagelist.scrollto-bottom');
332359
setTimeout(() => {
333360
if (this.$refs.scrollToBottom) {
334361
this.$refs.scrollToBottom.classList.remove('active');
@@ -466,6 +493,7 @@ html, body, #kiwiirc {
466493
position: relative;
467494
}
468495
.kiwi-messagelist-controls {
496+
pointer-events: none;
469497
width: 100%;
470498
position: absolute;
471499
top: 90%;
@@ -475,6 +503,7 @@ html, body, #kiwiirc {
475503
}
476504
477505
.kiwi-messagelist-controls .control {
506+
pointer-events: all;
478507
background: var(--brand-primary);
479508
color: white;
480509
padding: 4px;

src/components/MessageList.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@ export default {
312312
this.maybeScrollToId(opt.id);
313313
}
314314
});
315+
this.listen(this.$state, 'messagelist.scrollto-bottom', () => {
316+
this.maybeScrollToBottom();
317+
});
315318
this.$state.$on('messageinfo.close', () => {
316319
this.message_info_open = null;
317320
});

src/libs/History.js

Lines changed: 105 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
'kiwi public';
22

3+
import getState from './state';
4+
35
export class History {
46
constructor(baseUrl) {
57
/**
@@ -12,56 +14,143 @@ export class History {
1214
this.baseUrl = baseUrl;
1315
}
1416

17+
go(n) {
18+
this.log('go', n);
19+
return this.history.go(n);
20+
}
21+
22+
log(...args) {
23+
window.kiwi.log.debug('[history]', ...args);
24+
}
25+
1526
prepare() {
1627
if (!this.prepared) {
17-
window.addEventListener('popstate', async(e) => {
18-
if (e.state) {
19-
const page = e.state.page;
20-
await this.setPage(page);
28+
// eslint-disable-next-line
29+
window.addEventListener('popstate', (e) => {
30+
const page = e?.state?.page;
31+
this.log('popstate', e);
32+
if (page === undefined) {
33+
this.currentPage = 0;
34+
this.history.replaceState({}, '', this.baseUrl + '/');
35+
const state = getState();
36+
const net = state.getActiveNetwork();
37+
const buf = state.getActiveBuffer();
38+
const serverBuffer = net.serverBuffer();
39+
if (!state.activeComponent && buf === serverBuffer) {
40+
this.history.go();
41+
return;
42+
}
43+
state.$emit('active.component');
44+
state.setActiveBuffer(net.id, serverBuffer.name || '*', false);
45+
// e.preventDefault();
46+
return;
2147
}
48+
this.setPage(page);
2249
});
2350
this.prepared = true;
2451
}
2552
}
2653

27-
async setPage(page) {
54+
setPage(page) {
2855
this.prepare();
56+
this.log('setting page', page);
2957
const previousHandler = this.handlers[this.currentPage];
3058
const handler = this.handlers[page];
31-
this.currentPage = page;
32-
await previousHandler.leave();
33-
await handler.enter();
59+
if (page !== undefined) {
60+
this.currentPage = page;
61+
}
62+
previousHandler && previousHandler.leave();
63+
handler && handler.enter();
3464
}
3565

3666
push({
3767
enter,
3868
leave,
3969
path,
70+
query,
71+
hash,
4072
}) {
73+
// eslint-disable-next-line
74+
this.log('pushing.....', ...arguments);
4175
const url = new URL(this.baseUrl);
42-
url.pathname += path;
76+
if (path) {
77+
url.pathname = [
78+
...url.pathname.split('/'),
79+
...path.split('/'),
80+
].filter(Boolean).join('/');
81+
}
82+
if (query) {
83+
Object.entries(query).forEach((e) => {
84+
url.searchParams.set(e[0], e[1].toString());
85+
});
86+
}
87+
if (hash) {
88+
url.hash = hash;
89+
}
90+
if (url.pathname.charAt(url.pathname.length - 1) !== '/') {
91+
url.pathname += '/';
92+
}
93+
if ('' + url === '' + window.location) {
94+
this.doReplace({ enter, leave, url });
95+
return;
96+
}
4397
if (this.currentPage < this.handlers.length - 1) {
4498
this.handlers.splice(this.currentPage + 1);
4599
}
46100
const page = this.handlers.length;
47101
this.history.pushState({
48102
page,
49103
}, '', url);
50-
this.handlers.push({ enter, leave });
51-
return this.setPage(page);
104+
this.handlers.push({ enter, leave, path: '' + url });
105+
this.setPage(page);
52106
}
53107

54-
async replace({ enter, leave, path }) {
108+
replace({
109+
enter,
110+
leave,
111+
path,
112+
query,
113+
hash,
114+
}) {
115+
// eslint-disable-next-line
116+
this.log('replacing.....', ...arguments);
55117
const url = new URL(this.baseUrl);
56-
url.pathname += path;
118+
if (path) {
119+
url.pathname = [
120+
...url.pathname.split('/'),
121+
...path.split('/'),
122+
].filter(Boolean).join('/');
123+
}
124+
if (query) {
125+
Object.entries(query).forEach((e) => {
126+
url.searchParams.set(e[0], e[1].toString());
127+
});
128+
}
129+
if (hash) {
130+
url.hash = hash;
131+
}
132+
if (url.pathname.charAt(url.pathname.length - 1) !== '/') {
133+
url.pathname += '/';
134+
}
135+
if ('' + url === '' + window.location) {
136+
return;
137+
}
138+
this.doReplace({ enter, leave, url });
139+
}
140+
141+
doReplace({
142+
enter,
143+
leave,
144+
url,
145+
}) {
57146
const page = this.currentPage;
58147
this.history.replaceState({
59148
page,
60149
}, '', url);
61150
const previousHandler = this.handlers[page];
62-
const handler = { enter, leave };
151+
const handler = { enter, leave, path: '' + url };
63152
this.handlers[page] = handler;
64-
previousHandler && await previousHandler.leave();
65-
await handler.enter();
153+
previousHandler && previousHandler.leave();
154+
handler.enter();
66155
}
67156
}

src/libs/state.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,28 @@ function createNewState() {
357357
getActiveBuffer() {
358358
return this.getBufferByName(this.ui.active_network, this.ui.active_buffer);
359359
},
360-
361-
setActiveBuffer(networkid, bufferName) {
360+
setActiveBuffer(networkid, bufferName, useHistory = true) {
361+
window.kiwi.log.debug('setting active buffer', bufferName);
362+
if (this.history && useHistory) {
363+
const bufPathName = bufferName === '*' ? '' : bufferName;
364+
/**
365+
* @type {import('./History').History}
366+
*/
367+
const history = this.history;
368+
const path = bufPathName.charAt(0) !== '#' ? '/' + bufPathName : '/';
369+
const hash = bufPathName.charAt(0) === '#' ? bufPathName : undefined;
370+
const fn = history.currentPage === 0 ? 'push' : 'replace';
371+
history[fn]({
372+
enter: () => this.doSetActiveBuffer(networkid, bufferName),
373+
leave: () => {},
374+
path,
375+
hash,
376+
});
377+
} else {
378+
this.doSetActiveBuffer(networkid, bufferName);
379+
}
380+
},
381+
doSetActiveBuffer(networkid, bufferName) {
362382
if (!networkid) {
363383
this.ui.active_network = 0;
364384
this.ui.active_buffer = '';

src/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ function applyConfigObj(obj, target) {
361361
}
362362
function initHistory() {
363363
const state = getState();
364-
state.history = new History(state.setting('baseUrl') || window.location);
364+
state.history = new History(state.setting('baseUrl') || '' + window.location);
365365
}
366366
function loadPlugins() {
367367
return new Promise((resolve, reject) => {

0 commit comments

Comments
 (0)