tabs proof-of-concept (unusable)

This commit is contained in:
dragonwocky 2020-10-02 23:06:44 +10:00
parent bc646ab8ae
commit 4f053dc23f
Signed by: dragonwocky
GPG Key ID: C7A48B7846AA706D
2 changed files with 529 additions and 22 deletions

View File

@ -79,6 +79,7 @@ module.exports = (store, __exports) => {
});
electron.app.on('before-quit', () => (intended_quit = true));
window.loadURL(__exports.getIndexUrl(relativeUrl));
window.webContents.openDevTools();
return window;
};
return __exports.createWindow;

View File

@ -6,16 +6,521 @@
'use strict';
const url = require('url'),
path = require('path'),
{ __notion } = require('../../pkg/helpers.js'),
config = require(`${__notion}/app/config.js`),
constants = require(`${__notion}/app/shared/constants.js`),
notion_intl = require(`${__notion}/app/shared/notion-intl/index.js`),
notionIpc = require(`${__notion}/app/helpers/notionIpc.js`),
localizationHelper = require(`${__notion}/app/helpers/localizationHelper.js`),
koMessages = require(`${__notion}/app/i18n/ko_KR/messages.json`),
schemeHelpers = require(`${__notion}/app/shared/schemeHelpers.js`),
React = require(`${__notion}/app/node_modules/react/index.js`),
ReactDOM = require(`${__notion}/app/node_modules/react-dom/index.js`);
module.exports = (store, __exports) => {
if (store().tabs) {
class Index extends React.PureComponent {
constructor() {
super(...arguments);
this.state = {
error: false,
searching: false,
searchingPeekView: false,
zoomFactor: 1,
tabs: 2,
};
this.notionElm = [];
this.loadedElms = [];
this.reactTabs = [];
this.handleNotionRef = (notionElm) => {
this.notionElm.push(notionElm);
};
this.searchElm = null;
this.handleSearchRef = (searchElm) => {
this.searchElm = searchElm;
};
this.handleReload = () => {
this.setState({ error: false });
setTimeout(() => {
if (this.notionElm.length) {
this.notionElm.forEach(($notion) => {
if ($notion.isWaitingForResponse()) $notion.reload();
});
}
}, 50);
};
window['newtab'] = () => {
this.setState({ tabs: this.state.tabs + 1 });
setTimeout(() => this.addListeners(), 100);
};
}
componentDidMount() {
this.addListeners();
}
addListeners() {
const searchElm = this.searchElm;
const notionElm = this.notionElm;
if (!searchElm || !notionElm.length) {
return;
}
notionElm
.filter(($notion) => !this.loadedElms.includes($notion))
.forEach(($notion) => {
this.loadedElms.push($notion);
$notion.addEventListener('did-fail-load', (error) => {
// logger.info('Failed to load:', error);
if (error.errorCode === -3) {
return;
}
if (
!error.validatedURL.startsWith(
schemeHelpers.getSchemeUrl({
httpUrl: config.default.baseURL,
protocol: config.default.protocol,
})
)
) {
return;
}
this.setState({ error: true });
});
notionIpc.receiveIndexFromNotion.addListener(
$notion,
'search:start',
(isPeekView) => {
this.setState({
searching: true,
searchingPeekView: isPeekView,
});
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur();
}
searchElm.focus();
notionIpc.sendIndexToSearch(searchElm, 'search:start');
notionIpc.sendIndexToNotion(searchElm, 'search:started');
}
);
notionIpc.receiveIndexFromNotion.addListener(
$notion,
'search:stop',
() => {
notionIpc.sendIndexToSearch(searchElm, 'search:reset');
this.setState({
searching: false,
});
this.lastSearchQuery = undefined;
$notion.getWebContents().stopFindInPage('clearSelection');
notionIpc.sendIndexToNotion($notion, 'search:stopped');
}
);
notionIpc.receiveIndexFromSearch.addListener(
searchElm,
'search:next',
(query) => {
$notion.getWebContents().findInPage(query, {
forward: true,
findNext: query === this.lastSearchQuery,
});
this.lastSearchQuery = query;
}
);
notionIpc.receiveIndexFromSearch.addListener(
searchElm,
'search:prev',
(query) => {
$notion.getWebContents().findInPage(query, {
forward: false,
findNext: query === this.lastSearchQuery,
});
this.lastSearchQuery = query;
}
);
notionIpc.receiveIndexFromSearch.addListener(
searchElm,
'search:clear',
() => {
this.lastSearchQuery = undefined;
$notion.getWebContents().stopFindInPage('clearSelection');
}
);
notionIpc.receiveIndexFromSearch.addListener(
searchElm,
'search:stop',
() => {
this.lastSearchQuery = undefined;
$notion.getWebContents().stopFindInPage('clearSelection');
this.setState({ searching: false });
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur();
}
$notion.focus();
notionIpc.sendIndexToNotion($notion, 'search:stopped');
}
);
$notion.addEventListener('dom-ready', () => {
$notion
.getWebContents()
.addListener('found-in-page', (event, result) => {
const matches = result
? {
count: result.matches,
index: result.activeMatchOrdinal,
}
: { count: 0, index: 0 };
notionIpc.sendIndexToSearch(
searchElm,
'search:result',
matches
);
});
notionIpc.proxyAllMainToNotion($notion);
});
notionIpc.receiveIndexFromNotion.addListener(
$notion,
'search:set-theme',
(theme) => {
notionIpc.sendIndexToSearch(
searchElm,
'search:set-theme',
theme
);
}
);
notionIpc.receiveIndexFromNotion.addListener(
$notion,
'zoom',
(zoomFactor) => {
$notion.getWebContents().setZoomFactor(zoomFactor);
searchElm.getWebContents().setZoomFactor(zoomFactor);
this.setState({ zoomFactor });
}
);
let electronWindow;
try {
electronWindow = electron.remote.getCurrentWindow();
} catch (error) {
notionIpc.sendToMain('notion:log-error', {
level: 'error',
from: 'index',
type: 'GetCurrentWindowError',
error: error.message,
});
}
if (!electronWindow) {
this.setState({ error: true });
this.handleReload();
return;
}
electronWindow.on('focus', (e) => {
$notion.focus();
});
$notion.addEventListener('dom-ready', function () {
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur();
}
$notion.blur();
$notion.focus();
});
electronWindow.addListener('app-command', (e, cmd) => {
const webContents = $notion.getWebContents();
if (cmd === 'browser-backward' && webContents.canGoBack()) {
webContents.goBack();
} else if (
cmd === 'browser-forward' &&
webContents.canGoForward()
) {
webContents.goForward();
}
});
electronWindow.addListener('swipe', (e, dir) => {
const webContents = $notion.getWebContents();
if (dir === 'left' && webContents.canGoBack()) {
webContents.goBack();
} else if (dir === 'right' && webContents.canGoForward()) {
webContents.goForward();
}
});
const sendFullScreenChangeEvent = () => {
notionIpc.sendIndexToNotion(
$notion,
'notion:full-screen-changed'
);
};
electronWindow.addListener(
'enter-full-screen',
sendFullScreenChangeEvent
);
electronWindow.addListener(
'leave-full-screen',
sendFullScreenChangeEvent
);
electronWindow.addListener(
'enter-html-full-screen',
sendFullScreenChangeEvent
);
electronWindow.addListener(
'leave-html-full-screen',
sendFullScreenChangeEvent
);
});
}
renderSearchContainer() {
return React.createElement(
'div',
{ style: this.getSearchContainerStyle() },
React.createElement('webview', {
id: 'search',
style: this.getSearchWebviewStyle(),
ref: this.handleSearchRef,
partition: constants.electronSessionPartition,
preload: `file://${path.resolve(
`${__notion}/app/renderer/search.js`
)}`,
src: `file://${path.resolve(
`${__notion}/app/renderer/search.html`
)}`,
})
);
}
renderNotionContainer() {
this.reactTabs = [
...this.reactTabs,
...new Array(this.state.tabs - this.reactTabs.length)
.fill(0)
.map((i) =>
React.createElement('webview', {
className: 'notion',
style: Index.notionWebviewStyle,
ref: this.handleNotionRef,
partition: constants.electronSessionPartition,
preload: path.resolve(`${__notion}/app/renderer/preload.js`),
src: this.props.notionUrl,
})
),
];
return React.createElement(
'div',
{ style: this.getNotionContainerStyle() },
...this.reactTabs
);
}
renderErrorContainer() {
return React.createElement(
'div',
{ style: this.getErrorContainerStyle() },
React.createElement('img', {
style: Index.frontImageStyle,
src: './onboarding-offline.png',
}),
React.createElement(
'div',
{ style: Index.frontMessageStyle },
React.createElement(
'div',
null,
React.createElement(notion_intl.FormattedMessage, {
id: 'desktopLogin.offline.title',
defaultMessage: 'Welcome to <strong>Notion</strong>!',
values: {
strong: (...chunks) =>
React.createElement('strong', null, chunks),
},
})
),
React.createElement(
'div',
null,
React.createElement(notion_intl.FormattedMessage, {
id: 'desktopLogin.offline.message',
defaultMessage: 'Connect to the internet to get started.',
})
)
),
React.createElement(
'div',
null,
React.createElement(
'button',
{ style: Index.reloadButtonStyle, onClick: this.handleReload },
React.createElement(notion_intl.FormattedMessage, {
id:
'desktopLogin.offline.retryConnectingToInternetButton.label',
defaultMessage: 'Try again',
})
)
)
);
}
renderDragRegion() {
return React.createElement('div', { style: Index.dragRegionStyle });
}
render() {
const notionLocale = localizationHelper.getNotionLocaleFromElectronLocale(
window.navigator.language
),
result = React.createElement(
notion_intl.IntlProvider,
{
locale: notionLocale,
messages: notionLocale === 'ko-KR' ? koMessages : {},
},
this.renderDragRegion(),
this.renderNotionContainer(),
this.renderSearchContainer(),
this.renderErrorContainer()
);
this.addListeners();
return result;
}
getNotionContainerStyle() {
const style = {
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
display: this.state.error ? 'none' : 'flex',
};
return style;
}
getErrorContainerStyle() {
const style = {
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
display: this.state.error ? 'flex' : 'none',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
padding: 24,
paddingBottom: '8vh',
};
return style;
}
getSearchWebviewStyle() {
const style = {
width: '100%',
height: '100%',
transition: 'transform 70ms ease-in',
transform: 'translateY(-100%)',
pointerEvents: 'none',
};
if (this.state.searching) {
style.transition = 'transform 70ms ease-out';
style.transform = 'translateY(0%)';
style.pointerEvents = 'auto';
}
return style;
}
getSearchContainerStyle() {
const style = {
position: 'fixed',
overflow: 'hidden',
pointerEvents: 'none',
padding: '0 20px',
top:
(this.state.searchingPeekView
? 0
: process.platform === 'darwin'
? 37
: 45) * this.state.zoomFactor,
right: (48 - 24) * this.state.zoomFactor,
width: 440 * this.state.zoomFactor,
height: 72 * this.state.zoomFactor,
};
return style;
}
}
Index.frontMessageStyle = {
paddingTop: 16,
paddingBottom: 16,
textAlign: 'center',
lineHeight: 1.4,
fontSize: 17,
letterSpacing: '-0.01em',
color: '#424241',
fontWeight: 500,
};
Index.reloadButtonStyle = {
background: '#fefaf8',
border: '1px solid #f1cbca',
boxSizing: 'border-box',
boxShadow: '0px 1px 2px rgba(0, 0, 0, 0.1)',
borderRadius: 3,
lineHeight: 'normal',
fontSize: 14,
fontWeight: 600,
letterSpacing: '-0.03em',
color: '#d8615c',
paddingLeft: 12,
paddingRight: 12,
height: 36,
};
Index.frontImageStyle = {
width: 300,
maxWidth: '100%',
};
Index.notionWebviewStyle = {
width: '100%',
height: '100%',
};
Index.dragRegionStyle = {
position: 'absolute',
zIndex: 9999,
top: 0,
left: 0,
right: 0,
height: 2,
pointerEvents: 'none',
WebkitAppRegion: 'drag',
};
window['__start'] = () => {
const parsed = url.parse(window.location.href, true),
notionUrl =
parsed.query.path ||
schemeHelpers.getSchemeUrl({
httpUrl: config.default.baseURL,
protocol: config.default.protocol,
});
delete parsed.search;
delete parsed.query;
const plainUrl = url.format(parsed);
window.history.replaceState(undefined, undefined, plainUrl);
document.title = localizationHelper
.createIntlShape(
localizationHelper.getNotionLocaleFromElectronLocale(
window.navigator.language
)
)
.formatMessage(
notion_intl.defineMessages({
documentTitle: {
id: 'desktop.documentTitle',
defaultMessage: 'Notion Desktop',
},
}).documentTitle
);
const rootElm = document.getElementById('root');
ReactDOM.render(
React.createElement(Index, { notionUrl: notionUrl }),
rootElm
);
};
} else {
const __start = window['__start'];
window['__start'] = function () {
window['__start'] = () => {
__start();
const dragarea = document.querySelector(
'#root [style*="-webkit-app-region: drag"]'
),
default_styles = dragarea.getAttribute('style');
if (store().tiling_mode) {
dragarea.style.display = 'none';
} else {
@ -32,4 +537,5 @@ module.exports = (store, __exports) => {
});
}
};
}
};