mirror of
https://github.com/officialdakari/Extera.git
synced 2025-04-11 23:08:46 +02:00
BREAKING CHANGE: make back button handler perfect
This commit is contained in:
parent
693aba99f4
commit
ef02b16828
14 changed files with 66 additions and 24 deletions
30
index.html
30
index.html
|
@ -43,6 +43,36 @@
|
|||
<body id="appBody">
|
||||
<script>
|
||||
window.global ||= window;
|
||||
(function () {
|
||||
let stateSymbol = "__state__index__";
|
||||
history.stateIndex = -1;
|
||||
history.states = [];
|
||||
let pushState = history.pushState;
|
||||
function add(data, title, url) {
|
||||
if (data == null) data = {};
|
||||
if (typeof data != "object") data = { data: data };
|
||||
data[stateSymbol] = (history.stateIndex + 1);
|
||||
history.states.splice(history.stateIndex + 1, 0, [data, title, url])
|
||||
history.states.splice(history.stateIndex + 2)
|
||||
history.stateIndex++;
|
||||
}
|
||||
history.pushState = function (data, title, url = null) {
|
||||
add(data, title, url);
|
||||
pushState.bind(history)(data, title, url);
|
||||
}
|
||||
addEventListener("popstate", function (e) {
|
||||
var eventObject = {};
|
||||
var newStateIndex = e.state != null ? e.state[stateSymbol] : -1;
|
||||
eventObject.from = history.states[history.stateIndex];
|
||||
eventObject.to = newStateIndex > -1 ? history.states[newStateIndex] : null;
|
||||
eventObject.side = history.stateIndex > newStateIndex ? "back" : "forward";
|
||||
if (newStateIndex > -1 && !(newStateIndex in history.states)) {
|
||||
add(history.state, "", window.location.href);
|
||||
}
|
||||
window.dispatchEvent(new CustomEvent("historyChange", { detail: eventObject }))
|
||||
history.stateIndex = e.state != null ? e.state[stateSymbol] : -1;
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="./src/index.tsx"></script>
|
||||
|
|
|
@ -36,7 +36,7 @@ export const ImageViewer = as<'div', ImageViewerProps>(
|
|||
{...props}
|
||||
ref={ref}
|
||||
>
|
||||
<BackButtonHandler callback={requestClose} />
|
||||
<BackButtonHandler callback={requestClose} id='image-viewer' />
|
||||
<AppBar position='static'>
|
||||
<Toolbar>
|
||||
<IconButton onClick={requestClose}>
|
||||
|
|
|
@ -178,7 +178,7 @@ export const MessageReadReceiptItem = as<
|
|||
open={open}
|
||||
onClose={handleClose}
|
||||
>
|
||||
{open && <BackButtonHandler callback={handleClose} />}
|
||||
{open && <BackButtonHandler callback={handleClose} id='msg-readers-list' />}
|
||||
<AppBar position='relative'>
|
||||
<Toolbar>
|
||||
<Typography
|
||||
|
@ -255,7 +255,7 @@ export const MessageSourceCodeItem = as<
|
|||
onClose?.();
|
||||
};
|
||||
|
||||
useBackButton(handleClose);
|
||||
useBackButton(handleClose, 'source-code');
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -531,7 +531,7 @@ export const MessageRecoverItem = as<
|
|||
open={open}
|
||||
onClose={handleClose}
|
||||
>
|
||||
{open && <BackButtonHandler callback={handleClose} />}
|
||||
{open && <BackButtonHandler callback={handleClose} id='msg-recover' />}
|
||||
<DialogTitle>{getText('recovered.title')}</DialogTitle>
|
||||
<DialogContent>
|
||||
{message}
|
||||
|
@ -662,7 +662,7 @@ export const MessageTranslateItem = as<
|
|||
open={open}
|
||||
onClose={handleClose}
|
||||
>
|
||||
{open && <BackButtonHandler callback={handleClose} />}
|
||||
{open && <BackButtonHandler callback={handleClose} id='msg-translated' />}
|
||||
<DialogTitle>{getText('translated.title')}</DialogTitle>
|
||||
<DialogContent>
|
||||
{message}
|
||||
|
@ -847,7 +847,7 @@ export const MessageDeleteItem = as<
|
|||
onSubmit: handleSubmit
|
||||
}}
|
||||
>
|
||||
{open && <BackButtonHandler callback={handleClose} />}
|
||||
{open && <BackButtonHandler callback={handleClose} id='meg-delete' />}
|
||||
<DialogTitle>
|
||||
{getText('msg_redact.title')}
|
||||
</DialogTitle>
|
||||
|
|
|
@ -1,21 +1,33 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { v4 } from "uuid";
|
||||
|
||||
export const useBackButton = (callback) => {
|
||||
const cb = useCallback((evt) => {
|
||||
evt.preventDefault();
|
||||
callback();
|
||||
}, [callback]);
|
||||
export const useBackButton = (callback, fakeId) => {
|
||||
const fi2 = `${fakeId}-2`;
|
||||
const cb = (evt) => {
|
||||
console.log(`popstate`, evt, evt.state, history.state, fakeId);
|
||||
if (history.state === fakeId) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
addEventListener('popstate', cb);
|
||||
|
||||
history.pushState(fakeId, document.title, location.href);
|
||||
history.pushState(fi2, document.title, location.href);
|
||||
|
||||
return () => {
|
||||
removeEventListener('popstate', cb);
|
||||
if (history.state === fi2) {
|
||||
history.go(-2);
|
||||
} else if (history.state == fakeId) {
|
||||
history.back();
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
};
|
||||
|
||||
export const BackButtonHandler = ({ callback }) => {
|
||||
useBackButton(callback);
|
||||
export const BackButtonHandler = ({ callback, id }) => {
|
||||
useBackButton(callback, id ?? 'fake-route');
|
||||
return null;
|
||||
};
|
|
@ -261,7 +261,7 @@ function CreateRoom() {
|
|||
open={create !== null}
|
||||
onRequestClose={onRequestClose}
|
||||
>
|
||||
{create !== null && <BackButtonHandler callback={onRequestClose} />}
|
||||
{create !== null && <BackButtonHandler callback={onRequestClose} id='create-room' />}
|
||||
<AppBar position='relative'>
|
||||
<Toolbar>
|
||||
<Typography variant='h6' component='div' flexGrow={1}>
|
||||
|
|
|
@ -114,7 +114,7 @@ function HiddenRooms() {
|
|||
onRequestClose={requestClose}
|
||||
size="small"
|
||||
>
|
||||
{isOpen && <BackButtonHandler callback={requestClose} />}
|
||||
{isOpen && <BackButtonHandler callback={requestClose} id='hidden-rooms' />}
|
||||
<div className="hidden-rooms-dialog">
|
||||
<div className="hidden-rooms-dialog__content-wrapper">
|
||||
<ScrollView autoHide>
|
||||
|
|
|
@ -250,7 +250,7 @@ function InviteUser({ isOpen, roomId, searchTerm, onRequestClose }) {
|
|||
open={isOpen}
|
||||
onClose={onRequestClose}
|
||||
>
|
||||
{isOpen && <BackButtonHandler callback={onRequestClose} />}
|
||||
{isOpen && <BackButtonHandler callback={onRequestClose} id='invite-user' />}
|
||||
<AppBar position='relative'>
|
||||
<Toolbar>
|
||||
<Typography
|
||||
|
|
|
@ -137,7 +137,7 @@ function JoinAlias() {
|
|||
contentOptions={<IconButton src={mdiClose} onClick={requestClose} tooltip="Close" />}
|
||||
onRequestClose={requestClose}
|
||||
>
|
||||
{data !== null && <BackButtonHandler callback={requestClose} />}
|
||||
{data !== null && <BackButtonHandler callback={requestClose} id='join-alias' />}
|
||||
{data ? <JoinAliasContent term={data.term} requestClose={requestClose} /> : <div />}
|
||||
</Dialog>
|
||||
);
|
||||
|
|
|
@ -626,7 +626,7 @@ function ProfileViewer() {
|
|||
open={isOpen}
|
||||
onClose={closeDialog}
|
||||
>
|
||||
{isOpen && <BackButtonHandler callback={closeDialog} />}
|
||||
{isOpen && <BackButtonHandler callback={closeDialog} id='profile-viewer' />}
|
||||
{roomId ? renderProfile() : <div />}
|
||||
</Dialog>
|
||||
);
|
||||
|
|
|
@ -143,7 +143,7 @@ function RoomSettings() {
|
|||
scroll='body'
|
||||
sx={{ backdropFilter: 'blur(3px)' }}
|
||||
>
|
||||
{window !== null && <BackButtonHandler callback={requestClose} />}
|
||||
{window !== null && <BackButtonHandler callback={requestClose} id='room-settings' />}
|
||||
{window !== null && (
|
||||
<AppBar position='relative'>
|
||||
<ProminientToolbar>
|
||||
|
|
|
@ -209,7 +209,7 @@ function Search() {
|
|||
onRequestClose={requestClose}
|
||||
size="small"
|
||||
>
|
||||
{isOpen && <BackButtonHandler callback={requestClose} />}
|
||||
{isOpen && <BackButtonHandler callback={requestClose} id='ck-search' />}
|
||||
<div className="search-dialog">
|
||||
<form
|
||||
className="search-dialog__input"
|
||||
|
|
|
@ -901,7 +901,7 @@ function Settings() {
|
|||
scroll='body'
|
||||
sx={{ overscrollBehaviorY: 'none', backdropFilter: 'blur(3px)' }}
|
||||
>
|
||||
{isOpen && <BackButtonHandler callback={requestClose} />}
|
||||
{isOpen && <BackButtonHandler callback={requestClose} id='settings' />}
|
||||
<input type='file' accept='image/*' onChange={uploadImage} ref={uploadImageRef} style={{ display: 'none' }} />
|
||||
{isOpen && (
|
||||
<AppBar
|
||||
|
|
|
@ -168,7 +168,7 @@ function ShareMenu() {
|
|||
open={isOpen}
|
||||
onClose={requestClose}
|
||||
>
|
||||
{isOpen && <BackButtonHandler callback={requestClose} />}
|
||||
{isOpen && <BackButtonHandler callback={requestClose} id='share-menu' />}
|
||||
<ScrollView autoHide>
|
||||
<div className="share-menu-dialog__content">
|
||||
{Array.isArray(result) && result.map(renderRoomSelector)}
|
||||
|
|
|
@ -122,7 +122,7 @@ function SpaceSettings() {
|
|||
fullScreen={screenSize === ScreenSize.Mobile}
|
||||
sx={{ backdropFilter: 'blur(3px)' }}
|
||||
>
|
||||
{isOpen && <BackButtonHandler callback={requestClose} />}
|
||||
{isOpen && <BackButtonHandler callback={requestClose} id='space-settings' />}
|
||||
<AppBar sx={{ position: 'relative' }}>
|
||||
<ProminientToolbar>
|
||||
<div style={{ flexGrow: 1, alignSelf: 'flex-end' }}>
|
||||
|
|
Loading…
Add table
Reference in a new issue