mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Prompt dialog and popup menu
This commit is contained in:
parent
5a7fde7d21
commit
7d12da27ad
@ -2,6 +2,7 @@ const { _ } = require('lib/locale.js');
|
||||
const { BrowserWindow } = require('electron');
|
||||
const url = require('url')
|
||||
const path = require('path')
|
||||
const urlUtils = require('lib/urlUtils.js');
|
||||
|
||||
class ElectronAppWrapper {
|
||||
|
||||
@ -27,20 +28,6 @@ class ElectronAppWrapper {
|
||||
return this.win_;
|
||||
}
|
||||
|
||||
// store() {
|
||||
// return this.store_;
|
||||
// }
|
||||
|
||||
// dispatch(action) {
|
||||
// return this.store().dispatch(action);
|
||||
// }
|
||||
|
||||
// windowContentSize() {
|
||||
// if (!this.win_) return { width: 0, height: 0 };
|
||||
// const s = this.win_.getContentSize();
|
||||
// return { width: s[0], height: s[1] };
|
||||
// }
|
||||
|
||||
createWindow() {
|
||||
this.win_ = new BrowserWindow({width: 800, height: 600})
|
||||
|
||||
@ -55,18 +42,6 @@ class ElectronAppWrapper {
|
||||
this.win_.on('closed', () => {
|
||||
this.win_ = null
|
||||
})
|
||||
|
||||
this.win_.on('resize', () => {
|
||||
// this.dispatch({
|
||||
// type: 'WINDOW_CONTENT_SIZE_SET',
|
||||
// size: this.windowContentSize(),
|
||||
// });
|
||||
});
|
||||
|
||||
// this.dispatch({
|
||||
// type: 'WINDOW_CONTENT_SIZE_SET',
|
||||
// size: this.windowContentSize(),
|
||||
// });
|
||||
}
|
||||
|
||||
async waitForElectronAppReady() {
|
||||
|
@ -1,3 +1,5 @@
|
||||
const { _ } = require('lib/locale.js');
|
||||
|
||||
class Bridge {
|
||||
|
||||
constructor(electronWrapper) {
|
||||
@ -23,6 +25,30 @@ class Bridge {
|
||||
return dialog.showMessageBox(options);
|
||||
}
|
||||
|
||||
showErrorMessageBox(message) {
|
||||
return this.showMessageBox({
|
||||
type: 'error',
|
||||
message: message,
|
||||
});
|
||||
}
|
||||
|
||||
showConfirmMessageBox(message) {
|
||||
const result = this.showMessageBox({
|
||||
type: 'question',
|
||||
message: message,
|
||||
buttons: [_('OK'), _('Cancel')],
|
||||
});
|
||||
return result === 0;
|
||||
}
|
||||
|
||||
get Menu() {
|
||||
return require('electron').Menu;
|
||||
}
|
||||
|
||||
get MenuItem() {
|
||||
return require('electron').MenuItem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let bridge_ = null;
|
||||
|
@ -11,7 +11,6 @@ class HeaderComponent extends React.Component {
|
||||
}
|
||||
|
||||
makeButton(key, options) {
|
||||
console.info(key, options);
|
||||
return <a key={key} href="#" onClick={() => {options.onClick()}}>{options.title}</a>
|
||||
}
|
||||
|
||||
@ -42,7 +41,7 @@ class HeaderComponent extends React.Component {
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return { theme: state.theme };
|
||||
return { theme: state.settings.theme };
|
||||
};
|
||||
|
||||
const Header = connect(mapStateToProps)(HeaderComponent);
|
||||
|
@ -4,11 +4,20 @@ const { Header } = require('./Header.min.js');
|
||||
const { SideBar } = require('./SideBar.min.js');
|
||||
const { NoteList } = require('./NoteList.min.js');
|
||||
const { NoteText } = require('./NoteText.min.js');
|
||||
const { PromptDialog } = require('./PromptDialog.min.js');
|
||||
const { Setting } = require('lib/models/setting.js');
|
||||
const { Note } = require('lib/models/note.js');
|
||||
const { themeStyle } = require('../theme.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const layoutUtils = require('lib/layout-utils.js');
|
||||
const { bridge } = require('electron').remote.require('./bridge');
|
||||
|
||||
class MainScreenComponent extends React.Component {
|
||||
|
||||
componentWillMount() {
|
||||
this.setState({ newNotePromptVisible: false });
|
||||
}
|
||||
|
||||
render() {
|
||||
const style = this.props.style;
|
||||
const theme = themeStyle(this.props.theme);
|
||||
@ -40,9 +49,40 @@ class MainScreenComponent extends React.Component {
|
||||
verticalAlign: 'top',
|
||||
};
|
||||
|
||||
const promptStyle = {
|
||||
width: style.width,
|
||||
height: style.height,
|
||||
};
|
||||
|
||||
const headerButtons = [
|
||||
{
|
||||
title: _('New note'),
|
||||
onClick: () => {
|
||||
this.setState({ newNotePromptVisible: true });
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const newNotePromptOnAccept = async (answer) => {
|
||||
const folderId = Setting.value('activeFolderId');
|
||||
if (!folderId) return;
|
||||
|
||||
const note = await Note.save({
|
||||
title: answer,
|
||||
parent_id: folderId,
|
||||
});
|
||||
Note.updateGeolocation(note.id);
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'NOTES_SELECT',
|
||||
noteId: note.id,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={style}>
|
||||
<Header style={headerStyle} showBackButton={false} />
|
||||
<PromptDialog style={promptStyle} onAccept={(answer) => newNotePromptOnAccept(answer)} message={_('Note title:')} visible={this.state.newNotePromptVisible}/>
|
||||
<Header style={headerStyle} showBackButton={false} buttons={headerButtons} />
|
||||
<SideBar style={sideBarStyle} />
|
||||
<NoteList itemHeight={40} style={noteListStyle} />
|
||||
<NoteText style={noteTextStyle} />
|
||||
|
@ -1,10 +1,28 @@
|
||||
const { ItemList } = require('./ItemList.min.js');
|
||||
const React = require('react');
|
||||
const { connect } = require('react-redux');
|
||||
const { themeStyle } = require('../theme.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { bridge } = require('electron').remote.require('./bridge');
|
||||
const Menu = bridge().Menu;
|
||||
const MenuItem = bridge().MenuItem;
|
||||
|
||||
class NoteListComponent extends React.Component {
|
||||
|
||||
itemRenderer(index, item) {
|
||||
itemContextMenu(event) {
|
||||
const noteId = event.target.getAttribute('data-id');
|
||||
if (!noteId) throw new Error('No data-id on element');
|
||||
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({label: _('Delete'), async click() {
|
||||
const ok = bridge().showConfirmMessageBox(_('Delete note?'));
|
||||
if (!ok) return;
|
||||
await Note.delete(noteId);
|
||||
}}))
|
||||
menu.popup(bridge().window());
|
||||
}
|
||||
|
||||
itemRenderer(index, item, theme) {
|
||||
const onClick = (item) => {
|
||||
this.props.dispatch({
|
||||
type: 'NOTES_SELECT',
|
||||
@ -12,20 +30,27 @@ class NoteListComponent extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
let classes = ['item'];
|
||||
classes.push(index % 2 === 0 ? 'even' : 'odd');
|
||||
if (this.props.selectedNoteId === item.id) classes.push('selected');
|
||||
return <div onClick={() => { onClick(item) }} className={classes.join(' ')} key={index}>{item.title + ' ' + item.id.substr(0,4)}</div>
|
||||
const style = {
|
||||
height: this.props.itemHeight,
|
||||
display: 'block',
|
||||
cursor: 'pointer',
|
||||
backgroundColor: index % 2 === 0 ? theme.backgroundColor : theme.oddBackgroundColor,
|
||||
fontWeight: this.props.selectedNoteId === item.id ? 'bold' : 'normal',
|
||||
};
|
||||
|
||||
return <a data-id={item.id} onContextMenu={(event) => this.itemContextMenu(event)} href="#" style={style} onClick={() => { onClick(item) }} key={index}>{item.title}</a>
|
||||
}
|
||||
|
||||
render() {
|
||||
const theme = themeStyle(this.props.theme);
|
||||
|
||||
return (
|
||||
<ItemList
|
||||
itemHeight={this.props.itemHeight}
|
||||
style={this.props.style}
|
||||
className={"note-list"}
|
||||
items={this.props.notes}
|
||||
itemRenderer={ (index, item) => { return this.itemRenderer(index, item) } }
|
||||
itemRenderer={ (index, item) => { return this.itemRenderer(index, item, theme) } }
|
||||
></ItemList>
|
||||
);
|
||||
}
|
||||
@ -36,6 +61,7 @@ const mapStateToProps = (state) => {
|
||||
return {
|
||||
notes: state.notes,
|
||||
selectedNoteId: state.selectedNoteId,
|
||||
theme: state.settings.theme,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@ const { reg } = require('lib/registry.js');
|
||||
const MdToHtml = require('lib/MdToHtml');
|
||||
const shared = require('lib/components/shared/note-screen-shared.js');
|
||||
const { bridge } = require('electron').remote.require('./bridge');
|
||||
const { themeStyle } = require('../theme.js');
|
||||
|
||||
class NoteTextComponent extends React.Component {
|
||||
|
||||
@ -55,6 +56,10 @@ class NoteTextComponent extends React.Component {
|
||||
await shared.saveNoteButton_press(this);
|
||||
}
|
||||
|
||||
async saveOneProperty(name, value) {
|
||||
await shared.saveOneProperty(this, name, value);
|
||||
}
|
||||
|
||||
scheduleSave() {
|
||||
if (this.scheduleSaveTimeout_) clearTimeout(this.scheduleSaveTimeout_);
|
||||
this.scheduleSaveTimeout_ = setTimeout(() => {
|
||||
@ -73,6 +78,7 @@ class NoteTextComponent extends React.Component {
|
||||
|
||||
this.setState({
|
||||
note: note,
|
||||
lastSavedNote: Object.assign({}, note),
|
||||
mode: 'view',
|
||||
});
|
||||
}
|
||||
@ -164,7 +170,7 @@ class NoteTextComponent extends React.Component {
|
||||
webviewReady: true,
|
||||
});
|
||||
|
||||
this.webview_.openDevTools();
|
||||
//this.webview_.openDevTools();
|
||||
}
|
||||
|
||||
webview_ref(element) {
|
||||
@ -218,6 +224,7 @@ class NoteTextComponent extends React.Component {
|
||||
const style = this.props.style;
|
||||
const note = this.state.note;
|
||||
const body = note ? note.body : '';
|
||||
const theme = themeStyle(this.props.theme);
|
||||
|
||||
const viewerStyle = {
|
||||
width: Math.floor(style.width / 2),
|
||||
@ -227,12 +234,17 @@ class NoteTextComponent extends React.Component {
|
||||
verticalAlign: 'top',
|
||||
};
|
||||
|
||||
const paddingTop = 14;
|
||||
|
||||
const editorStyle = {
|
||||
width: style.width - viewerStyle.width,
|
||||
height: style.height,
|
||||
height: style.height - paddingTop,
|
||||
overflowY: 'scroll',
|
||||
float: 'left',
|
||||
verticalAlign: 'top',
|
||||
paddingTop: paddingTop + 'px',
|
||||
lineHeight: theme.textAreaLineHeight + 'px',
|
||||
fontSize: theme.fontSize + 'px',
|
||||
};
|
||||
|
||||
if (this.state.webviewReady) {
|
||||
@ -242,7 +254,7 @@ class NoteTextComponent extends React.Component {
|
||||
},
|
||||
postMessageSyntax: 'ipcRenderer.sendToHost',
|
||||
};
|
||||
const html = this.mdToHtml().render(body, {}, mdOptions);
|
||||
const html = this.mdToHtml().render(body, theme, mdOptions);
|
||||
this.webview_.send('setHtml', html);
|
||||
}
|
||||
|
||||
|
107
ElectronClient/app/gui/PromptDialog.jsx
Normal file
107
ElectronClient/app/gui/PromptDialog.jsx
Normal file
@ -0,0 +1,107 @@
|
||||
const React = require('react');
|
||||
const { connect } = require('react-redux');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { themeStyle } = require('../theme.js');
|
||||
|
||||
class PromptDialog extends React.Component {
|
||||
|
||||
componentWillMount() {
|
||||
this.setState({
|
||||
visible: false,
|
||||
answer: '',
|
||||
});
|
||||
this.focusInput_ = true;
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
if ('visible' in newProps) {
|
||||
this.setState({ visible: newProps.visible });
|
||||
if (newProps.visible) this.focusInput_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.focusInput_ && this.answerInput_) this.answerInput_.focus();
|
||||
this.focusInput_ = false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const style = this.props.style;
|
||||
const theme = themeStyle(this.props.theme);
|
||||
|
||||
const modalLayerStyle = {
|
||||
zIndex: 9999,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: style.width,
|
||||
height: style.height,
|
||||
backgroundColor: 'rgba(0,0,0,0.6)',
|
||||
display: this.state.visible ? 'flex' : 'none',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
};
|
||||
|
||||
const promptDialogStyle = {
|
||||
backgroundColor: 'white',
|
||||
padding: 10,
|
||||
display: 'inline-block',
|
||||
boxShadow: '6px 6px 20px rgba(0,0,0,0.5)',
|
||||
};
|
||||
|
||||
const buttonStyle = {
|
||||
minWidth: theme.buttonMinWidth,
|
||||
minHeight: theme.buttonMinHeight,
|
||||
marginLeft: 5,
|
||||
};
|
||||
|
||||
const inputStyle = {
|
||||
width: 0.5 * style.width,
|
||||
maxWidth: 400,
|
||||
};
|
||||
|
||||
const onAccept = () => {
|
||||
if (this.props.onAccept) this.props.onAccept(this.state.answer);
|
||||
this.setState({ visible: false, answer: '' });
|
||||
}
|
||||
|
||||
const onReject = () => {
|
||||
if (this.props.onReject) this.props.onReject();
|
||||
this.setState({ visible: false, answer: '' });
|
||||
}
|
||||
|
||||
const onChange = (event) => {
|
||||
this.setState({ answer: event.target.value });
|
||||
}
|
||||
|
||||
const onKeyDown = (event) => {
|
||||
if (event.key === 'Enter') {
|
||||
onAccept();
|
||||
} else if (event.key === 'Escape') {
|
||||
onReject();
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={modalLayerStyle}>
|
||||
<div style={promptDialogStyle}>
|
||||
<label style={{ marginRight: 5 }}>{this.props.message ? this.props.message : ''}</label>
|
||||
<input
|
||||
style={inputStyle}
|
||||
ref={input => this.answerInput_ = input}
|
||||
value={this.state.answer}
|
||||
type="text"
|
||||
onChange={(event) => onChange(event)}
|
||||
onKeyDown={(event) => onKeyDown(event)} />
|
||||
<div style={{ textAlign: 'right', marginTop: 10 }}>
|
||||
<button style={buttonStyle} onClick={() => onAccept()}>OK</button>
|
||||
<button style={buttonStyle} onClick={() => onReject()}>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = { PromptDialog };
|
@ -2,9 +2,27 @@ const React = require('react');
|
||||
const { connect } = require('react-redux');
|
||||
const shared = require('lib/components/shared/side-menu-shared.js');
|
||||
const { Synchronizer } = require('lib/synchronizer.js');
|
||||
const { themeStyle } = require('../theme.js');
|
||||
|
||||
class SideBarComponent extends React.Component {
|
||||
|
||||
style() {
|
||||
const theme = themeStyle(this.props.theme);
|
||||
|
||||
const itemHeight = 20;
|
||||
|
||||
let style = {
|
||||
root: {},
|
||||
listItem: {
|
||||
display: 'block',
|
||||
cursor: 'pointer',
|
||||
height: itemHeight,
|
||||
},
|
||||
};
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
folderItem_click(folder) {
|
||||
this.props.dispatch({
|
||||
type: 'FOLDERS_SELECT',
|
||||
@ -24,15 +42,17 @@ class SideBarComponent extends React.Component {
|
||||
}
|
||||
|
||||
folderItem(folder, selected) {
|
||||
let classes = [];
|
||||
if (selected) classes.push('selected');
|
||||
return <div key={folder.id} className={classes.join(' ')} onClick={() => {this.folderItem_click(folder)}}>{folder.title}</div>
|
||||
const style = Object.assign({}, this.style().listItem, {
|
||||
fontWeight: selected ? 'bold' : 'normal',
|
||||
});
|
||||
return <a href="#" key={folder.id} style={style} onClick={() => {this.folderItem_click(folder)}}>{folder.title}</a>
|
||||
}
|
||||
|
||||
tagItem(tag, selected) {
|
||||
let classes = [];
|
||||
if (selected) classes.push('selected');
|
||||
return <div key={tag.id} className={classes.join(' ')} onClick={() => {this.tagItem_click(tag)}}>Tag: {tag.title}</div>
|
||||
const style = Object.assign({}, this.style().listItem, {
|
||||
fontWeight: selected ? 'bold' : 'normal',
|
||||
});
|
||||
return <a href="#" key={tag.id} style={style} onClick={() => {this.tagItem_click(tag)}}>Tag: {tag.title}</a>
|
||||
}
|
||||
|
||||
makeDivider(key) {
|
||||
@ -44,6 +64,9 @@ class SideBarComponent extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const theme = themeStyle(this.props.theme);
|
||||
const style = Object.assign({}, this.style().root, this.props.style);
|
||||
|
||||
let items = [];
|
||||
|
||||
if (this.props.folders.length) {
|
||||
@ -69,7 +92,7 @@ class SideBarComponent extends React.Component {
|
||||
items.push(<div key='sync_report'>{syncReportText}</div>);
|
||||
|
||||
return (
|
||||
<div className="side-bar" style={this.props.style}>
|
||||
<div className="side-bar" style={style}>
|
||||
{items}
|
||||
</div>
|
||||
);
|
||||
|
@ -2,12 +2,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<title>Joplin</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="react-root"></div>
|
||||
<!-- <script src="gui/Root.min.js"></script> -->
|
||||
<script src="main-html.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
87
ElectronClient/app/package-lock.json
generated
87
ElectronClient/app/package-lock.json
generated
@ -1360,6 +1360,25 @@
|
||||
"yargs": "10.0.3"
|
||||
}
|
||||
},
|
||||
"electron-context-menu": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-context-menu/-/electron-context-menu-0.9.1.tgz",
|
||||
"integrity": "sha1-7U3yDAgEkcPJlqv8s2MVmUajgFg=",
|
||||
"requires": {
|
||||
"electron-dl": "1.10.0",
|
||||
"electron-is-dev": "0.1.2"
|
||||
}
|
||||
},
|
||||
"electron-dl": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-dl/-/electron-dl-1.10.0.tgz",
|
||||
"integrity": "sha1-+UQWBkBW/G8qhq5JhhTJNSaJCvk=",
|
||||
"requires": {
|
||||
"ext-name": "5.0.0",
|
||||
"pupa": "1.0.0",
|
||||
"unused-filename": "1.0.0"
|
||||
}
|
||||
},
|
||||
"electron-download-tf": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/electron-download-tf/-/electron-download-tf-4.3.4.tgz",
|
||||
@ -1377,6 +1396,11 @@
|
||||
"sumchecker": "2.0.2"
|
||||
}
|
||||
},
|
||||
"electron-is-dev": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.1.2.tgz",
|
||||
"integrity": "sha1-ihBD4ys6HaHD9VPc4oznZCRhZ+M="
|
||||
},
|
||||
"electron-osx-sign": {
|
||||
"version": "0.4.7",
|
||||
"resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.7.tgz",
|
||||
@ -1617,6 +1641,23 @@
|
||||
"integrity": "sha512-kkjwkMqj0h4w/sb32ERCDxCQkREMCAgS39DscDnSwDsbxnwwM1BTZySdC3Bn1lhY7vL08n9GoO/fVTynjDgRyQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ext-list": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
|
||||
"integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
|
||||
"requires": {
|
||||
"mime-db": "1.30.0"
|
||||
}
|
||||
},
|
||||
"ext-name": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
|
||||
"integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
|
||||
"requires": {
|
||||
"ext-list": "2.2.2",
|
||||
"sort-keys-length": "1.0.1"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
|
||||
@ -2275,6 +2316,11 @@
|
||||
"path-is-inside": "1.0.2"
|
||||
}
|
||||
},
|
||||
"is-plain-obj": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
|
||||
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
|
||||
},
|
||||
"is-posix-bracket": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
|
||||
@ -2719,8 +2765,7 @@
|
||||
"mime-db": {
|
||||
"version": "1.30.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
|
||||
"integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
|
||||
"dev": true
|
||||
"integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.17",
|
||||
@ -2769,6 +2814,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"modify-filename": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/modify-filename/-/modify-filename-1.1.0.tgz",
|
||||
"integrity": "sha1-mi3sg4Bvuy2XXyK+7IWcoms5OqE="
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.19.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.19.1.tgz",
|
||||
@ -3134,8 +3184,7 @@
|
||||
"path-exists": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
|
||||
"dev": true
|
||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
@ -3317,6 +3366,11 @@
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
|
||||
"dev": true
|
||||
},
|
||||
"pupa": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pupa/-/pupa-1.0.0.tgz",
|
||||
"integrity": "sha1-mpVopa9+ZXuEYqbp1TKHQ1YM7/Y="
|
||||
},
|
||||
"q": {
|
||||
"version": "0.9.7",
|
||||
"resolved": "https://registry.npmjs.org/q/-/q-0.9.7.tgz",
|
||||
@ -3771,6 +3825,22 @@
|
||||
"hoek": "4.2.0"
|
||||
}
|
||||
},
|
||||
"sort-keys": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
|
||||
"integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
|
||||
"requires": {
|
||||
"is-plain-obj": "1.1.0"
|
||||
}
|
||||
},
|
||||
"sort-keys-length": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
|
||||
"integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=",
|
||||
"requires": {
|
||||
"sort-keys": "1.1.2"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
@ -4890,6 +4960,15 @@
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
|
||||
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc="
|
||||
},
|
||||
"unused-filename": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-1.0.0.tgz",
|
||||
"integrity": "sha1-00CID3GuIRXrqhMlvvBcxmhEacY=",
|
||||
"requires": {
|
||||
"modify-filename": "1.1.0",
|
||||
"path-exists": "3.0.0"
|
||||
}
|
||||
},
|
||||
"unzip-response": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz",
|
||||
|
@ -26,6 +26,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"app-module-path": "^2.2.0",
|
||||
"electron-context-menu": "^0.9.1",
|
||||
"fs-extra": "^4.0.2",
|
||||
"html-entities": "^1.2.1",
|
||||
"lodash": "^4.17.4",
|
||||
|
@ -6,6 +6,7 @@ const globalStyle = {
|
||||
itemMarginTop: 10,
|
||||
itemMarginBottom: 10,
|
||||
backgroundColor: "#ffffff",
|
||||
oddBackgroundColor: "#dddddd",
|
||||
color: "#555555", // For regular text
|
||||
colorError: "red",
|
||||
colorWarn: "#9A5B00",
|
||||
@ -15,17 +16,21 @@ const globalStyle = {
|
||||
selectedColor: '#e5e5e5',
|
||||
disabledOpacity: 0.3,
|
||||
headerHeight: 20,
|
||||
buttonMinWidth: 50,
|
||||
buttonMinHeight: 30,
|
||||
textAreaLineHeight: 17,
|
||||
|
||||
raisedBackgroundColor: "#0080EF",
|
||||
raisedColor: "#003363",
|
||||
raisedHighlightedColor: "#ffffff",
|
||||
|
||||
// For WebView - must correspond to the properties above
|
||||
htmlFontSize: '20x',
|
||||
htmlFontSize: '16px',
|
||||
htmlColor: 'black', // Note: CSS in WebView component only supports named colors or rgb() notation
|
||||
htmlBackgroundColor: 'white',
|
||||
htmlDividerColor: 'Gainsboro',
|
||||
htmlLinkColor: 'blue',
|
||||
htmlLineHeight: '20px',
|
||||
};
|
||||
|
||||
globalStyle.marginRight = globalStyle.margin;
|
||||
|
@ -203,6 +203,8 @@ class MdToHtml {
|
||||
if (!options) options = {};
|
||||
if (!options.postMessageSyntax) options.postMessageSyntax = 'postMessage';
|
||||
|
||||
console.info(style);
|
||||
|
||||
const cacheKey = this.makeContentKey(this.loadedResources_, body, style, options);
|
||||
if (this.cachedContentKey_ === cacheKey) return this.cachedContent_;
|
||||
|
||||
@ -255,8 +257,13 @@ class MdToHtml {
|
||||
body {
|
||||
font-size: ` + style.htmlFontSize + `;
|
||||
color: ` + style.htmlColor + `;
|
||||
line-height: 1.5em;
|
||||
line-height: ` + style.htmlLineHeight + `;
|
||||
background-color: ` + style.htmlBackgroundColor + `;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
p, h1, h2, h3, h4, ul {
|
||||
margin-top: 14px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.2em;
|
||||
|
@ -20,11 +20,12 @@ const globalStyle = {
|
||||
raisedHighlightedColor: "#ffffff",
|
||||
|
||||
// For WebView - must correspond to the properties above
|
||||
htmlFontSize: '20x',
|
||||
htmlFontSize: '16px',
|
||||
htmlColor: 'black', // Note: CSS in WebView component only supports named colors or rgb() notation
|
||||
htmlBackgroundColor: 'white',
|
||||
htmlDividerColor: 'Gainsboro',
|
||||
htmlLinkColor: 'blue',
|
||||
htmlLineHeight: '20px',
|
||||
};
|
||||
|
||||
globalStyle.marginRight = globalStyle.margin;
|
||||
|
9
ReactNativeClient/lib/urlUtils.js
Normal file
9
ReactNativeClient/lib/urlUtils.js
Normal file
@ -0,0 +1,9 @@
|
||||
const urlUtils = {};
|
||||
|
||||
urlUtils.hash = function(url) {
|
||||
const s = url.split('#');
|
||||
if (s.length <= 1) return '';
|
||||
return s[s.length - 1];
|
||||
}
|
||||
|
||||
module.exports = urlUtils;
|
Loading…
Reference in New Issue
Block a user