1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-21 09:38:01 +02:00

Chore: Desktop: Convert last JSX files to TSX

This commit is contained in:
Laurent Cozic 2023-01-19 17:19:06 +00:00
parent ff79ca8781
commit 27bec674a0
32 changed files with 468 additions and 1111 deletions

View File

@ -142,7 +142,12 @@ packages/app-desktop/gui/EditFolderDialog/IconSelector.js
packages/app-desktop/gui/EmojiBox.js
packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.js
packages/app-desktop/gui/ErrorBoundary.js
packages/app-desktop/gui/ExtensionBadge.js
packages/app-desktop/gui/FolderIconBox.js
packages/app-desktop/gui/HelpButton.js
packages/app-desktop/gui/IconButton.js
packages/app-desktop/gui/ImportScreen.js
packages/app-desktop/gui/ItemList.js
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js
packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.js
packages/app-desktop/gui/KeymapConfig/styles/index.js
@ -193,6 +198,7 @@ packages/app-desktop/gui/MainScreen/commands/toggleVisiblePanes.js
packages/app-desktop/gui/MasterPasswordDialog/Dialog.js
packages/app-desktop/gui/MenuBar.js
packages/app-desktop/gui/MultiNoteActions.js
packages/app-desktop/gui/Navigator.js
packages/app-desktop/gui/NoteContentPropertiesDialog.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/Editor.js
@ -252,6 +258,10 @@ packages/app-desktop/gui/NoteListControls/commands/focusSearch.js
packages/app-desktop/gui/NoteListControls/commands/index.js
packages/app-desktop/gui/NoteListItem.js
packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.js
packages/app-desktop/gui/NotePropertiesDialog.js
packages/app-desktop/gui/NoteRevisionViewer.js
packages/app-desktop/gui/NoteSearchBar.js
packages/app-desktop/gui/NoteStatusBar.js
packages/app-desktop/gui/NoteTextViewer.js
packages/app-desktop/gui/NoteToolbar/NoteToolbar.js
packages/app-desktop/gui/OneDriveLoginScreen.js
@ -290,12 +300,14 @@ packages/app-desktop/gui/Sidebar/styles/index.js
packages/app-desktop/gui/StatusScreen/StatusScreen.js
packages/app-desktop/gui/StyleSheets/StyleSheetContainer.js
packages/app-desktop/gui/SyncWizard/Dialog.js
packages/app-desktop/gui/TagItem.js
packages/app-desktop/gui/TagList.js
packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.js
packages/app-desktop/gui/ToggleEditorsButton/styles/index.js
packages/app-desktop/gui/ToolbarBase.js
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
packages/app-desktop/gui/ToolbarButton/styles/index.js
packages/app-desktop/gui/ToolbarSpace.js
packages/app-desktop/gui/dialogs.js
packages/app-desktop/gui/hooks/useEffectDebugger.js
packages/app-desktop/gui/hooks/useImperativeHandlerDebugger.js

12
.gitignore vendored
View File

@ -130,7 +130,12 @@ packages/app-desktop/gui/EditFolderDialog/IconSelector.js
packages/app-desktop/gui/EmojiBox.js
packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.js
packages/app-desktop/gui/ErrorBoundary.js
packages/app-desktop/gui/ExtensionBadge.js
packages/app-desktop/gui/FolderIconBox.js
packages/app-desktop/gui/HelpButton.js
packages/app-desktop/gui/IconButton.js
packages/app-desktop/gui/ImportScreen.js
packages/app-desktop/gui/ItemList.js
packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.js
packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.js
packages/app-desktop/gui/KeymapConfig/styles/index.js
@ -181,6 +186,7 @@ packages/app-desktop/gui/MainScreen/commands/toggleVisiblePanes.js
packages/app-desktop/gui/MasterPasswordDialog/Dialog.js
packages/app-desktop/gui/MenuBar.js
packages/app-desktop/gui/MultiNoteActions.js
packages/app-desktop/gui/Navigator.js
packages/app-desktop/gui/NoteContentPropertiesDialog.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/CodeMirror.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/Editor.js
@ -240,6 +246,10 @@ packages/app-desktop/gui/NoteListControls/commands/focusSearch.js
packages/app-desktop/gui/NoteListControls/commands/index.js
packages/app-desktop/gui/NoteListItem.js
packages/app-desktop/gui/NoteListWrapper/NoteListWrapper.js
packages/app-desktop/gui/NotePropertiesDialog.js
packages/app-desktop/gui/NoteRevisionViewer.js
packages/app-desktop/gui/NoteSearchBar.js
packages/app-desktop/gui/NoteStatusBar.js
packages/app-desktop/gui/NoteTextViewer.js
packages/app-desktop/gui/NoteToolbar/NoteToolbar.js
packages/app-desktop/gui/OneDriveLoginScreen.js
@ -278,12 +288,14 @@ packages/app-desktop/gui/Sidebar/styles/index.js
packages/app-desktop/gui/StatusScreen/StatusScreen.js
packages/app-desktop/gui/StyleSheets/StyleSheetContainer.js
packages/app-desktop/gui/SyncWizard/Dialog.js
packages/app-desktop/gui/TagItem.js
packages/app-desktop/gui/TagList.js
packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.js
packages/app-desktop/gui/ToggleEditorsButton/styles/index.js
packages/app-desktop/gui/ToolbarBase.js
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
packages/app-desktop/gui/ToolbarButton/styles/index.js
packages/app-desktop/gui/ToolbarSpace.js
packages/app-desktop/gui/dialogs.js
packages/app-desktop/gui/hooks/useEffectDebugger.js
packages/app-desktop/gui/hooks/useImperativeHandlerDebugger.js

View File

@ -1,7 +1,7 @@
const React = require('react');
const { connect } = require('react-redux');
const { clipboard } = require('electron');
const ExtensionBadge = require('./ExtensionBadge.min');
import ExtensionBadge from './ExtensionBadge';
import bridge from '../services/bridge';
import { themeStyle } from '@joplin/lib/theme';
import { _ } from '@joplin/lib/locale';

View File

@ -1,45 +0,0 @@
const React = require('react');
const bridge = require('@electron/remote').require('./bridge').default;
const styleSelector = require('./style/ExtensionBadge');
const { _ } = require('@joplin/lib/locale');
function platformAssets(type) {
if (type === 'firefox') {
return {
logoImage: `${bridge().buildDir()}/images/firefox-logo.svg`,
locationLabel: _('Firefox Extension'),
};
}
if (type === 'chrome') {
return {
logoImage: `${bridge().buildDir()}/images/chrome-logo.svg`,
locationLabel: _('Chrome Web Store'),
};
}
throw new Error(`Invalid type:${type}`);
}
function ExtensionBadge(props) {
const style = styleSelector(null, props);
const assets = platformAssets(props.type);
const onClick = () => {
bridge().openExternal(props.url);
};
const rootStyle = props.style ? Object.assign({}, style.root, props.style) : style.root;
return (
<a style={rootStyle} onClick={onClick} href="#">
<img style={style.logo} src={assets.logoImage}/>
<div style={style.labelGroup} >
<div>{_('Get it now:')}</div>
<div style={style.locationLabel}>{assets.locationLabel}</div>
</div>
</a>
);
}
module.exports = ExtensionBadge;

View File

@ -0,0 +1,98 @@
import * as React from 'react';
import bridge from '../services/bridge';
import { _ } from '@joplin/lib/locale';
import { themeStyle } from '@joplin/lib/theme';
const { createSelector } = require('reselect');
interface Props {
themeId: number;
type: string;
url: string;
style?: any;
}
const themeSelector = (_state: any, props: any) => themeStyle(props.themeId);
const styleSelector = createSelector(
themeSelector,
(theme: any) => {
const output = {
root: {
width: 220,
height: 60,
borderRadius: 4,
border: '1px solid',
borderColor: theme.dividerColor,
backgroundColor: theme.backgroundColor,
paddingLeft: 14,
paddingRight: 14,
paddingTop: 8,
paddingBottom: 8,
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'row',
boxShadow: '0px 1px 1px rgba(0,0,0,0.3)',
},
logo: {
width: 42,
height: 42,
},
labelGroup: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
marginLeft: 14,
fontFamily: theme.fontFamily,
color: theme.color,
fontSize: theme.fontSize,
},
locationLabel: {
fontSize: theme.fontSize * 1.2,
fontWeight: 'bold',
},
};
return output;
}
);
function platformAssets(type: string) {
if (type === 'firefox') {
return {
logoImage: `${bridge().buildDir()}/images/firefox-logo.svg`,
locationLabel: _('Firefox Extension'),
};
}
if (type === 'chrome') {
return {
logoImage: `${bridge().buildDir()}/images/chrome-logo.svg`,
locationLabel: _('Chrome Web Store'),
};
}
throw new Error(`Invalid type:${type}`);
}
function ExtensionBadge(props: Props) {
const style = styleSelector(null, props);
const assets = platformAssets(props.type);
const onClick = () => {
void bridge().openExternal(props.url);
};
const rootStyle = props.style ? Object.assign({}, style.root, props.style) : style.root;
return (
<a style={rootStyle} onClick={onClick} href="#">
<img style={style.logo} src={assets.logoImage}/>
<div style={style.labelGroup} >
<div>{_('Get it now:')}</div>
<div style={style.locationLabel}>{assets.locationLabel}</div>
</div>
</a>
);
}
export default ExtensionBadge;

View File

@ -1,10 +1,18 @@
const React = require('react');
import * as React from 'react';
const { connect } = require('react-redux');
const { themeStyle } = require('@joplin/lib/theme');
import { themeStyle } from '@joplin/lib/theme';
import { AppState } from '../app.reducer';
class HelpButtonComponent extends React.Component {
constructor() {
super();
interface Props {
tip: string;
onClick: Function;
themeId: number;
style: any;
}
class HelpButtonComponent extends React.Component<Props> {
constructor(props: Props) {
super(props);
this.onClick = this.onClick.bind(this);
}
@ -17,7 +25,7 @@ class HelpButtonComponent extends React.Component {
const theme = themeStyle(this.props.themeId);
const style = Object.assign({}, this.props.style, { color: theme.color, textDecoration: 'none' });
const helpIconStyle = { flex: 0, width: 16, height: 16, marginLeft: 10 };
const extraProps = {};
const extraProps: any = {};
if (this.props.tip) extraProps['data-tip'] = this.props.tip;
return (
<a href="#" style={style} onClick={this.onClick} {...extraProps}>
@ -27,7 +35,7 @@ class HelpButtonComponent extends React.Component {
}
}
const mapStateToProps = state => {
const mapStateToProps = (state: AppState) => {
return {
themeId: state.settings.theme,
};
@ -35,4 +43,4 @@ const mapStateToProps = state => {
const HelpButton = connect(mapStateToProps)(HelpButtonComponent);
module.exports = HelpButton;
export default HelpButton;

View File

@ -1,7 +1,14 @@
const React = require('react');
const { themeStyle } = require('@joplin/lib/theme');
import * as React from 'react';
import { themeStyle } from '@joplin/lib/theme';
class IconButton extends React.Component {
interface Props {
themeId: number;
style: any;
iconName: string;
onClick: Function;
}
class IconButton extends React.Component<Props> {
render() {
const style = this.props.style;
const theme = themeStyle(this.props.themeId);
@ -42,4 +49,4 @@ class IconButton extends React.Component {
}
}
module.exports = { IconButton };
export default IconButton;

View File

@ -1,12 +1,29 @@
const React = require('react');
import * as React from 'react';
import Folder from '@joplin/lib/models/Folder';
import { themeStyle } from '@joplin/lib/theme';
import { _ } from '@joplin/lib/locale';
import { filename, basename } from '@joplin/lib/path-utils';
import importEnex from '@joplin/lib/import-enex';
import { AppState } from '../app.reducer';
const { connect } = require('react-redux');
const Folder = require('@joplin/lib/models/Folder').default;
const { themeStyle } = require('@joplin/lib/theme');
const { _ } = require('@joplin/lib/locale');
const { filename, basename } = require('@joplin/lib/path-utils');
const importEnex = require('@joplin/lib/import-enex').default;
class ImportScreenComponent extends React.Component {
interface Props {
filePath: string;
themeId: number;
}
interface Message {
key: string;
text: string;
}
interface State {
filePath: string;
doImport: boolean;
messages: Message[];
}
class ImportScreenComponent extends React.Component<Props, State> {
UNSAFE_componentWillMount() {
this.setState({
doImport: true,
@ -15,7 +32,7 @@ class ImportScreenComponent extends React.Component {
});
}
UNSAFE_componentWillReceiveProps(newProps) {
UNSAFE_componentWillReceiveProps(newProps: Props) {
if (newProps.filePath) {
this.setState(
{
@ -24,7 +41,7 @@ class ImportScreenComponent extends React.Component {
messages: [],
},
() => {
this.doImport();
void this.doImport();
}
);
}
@ -32,11 +49,11 @@ class ImportScreenComponent extends React.Component {
componentDidMount() {
if (this.state.filePath && this.state.doImport) {
this.doImport();
void this.doImport();
}
}
addMessage(key, text) {
addMessage(key: string, text: string) {
const messages = this.state.messages.slice();
messages.push({ key: key, text: text });
@ -66,7 +83,7 @@ class ImportScreenComponent extends React.Component {
let lastProgress = '';
const options = {
onProgress: progressState => {
onProgress: (progressState: any) => {
const line = [];
line.push(_('Found: %d.', progressState.loaded));
line.push(_('Created: %d.', progressState.created));
@ -77,7 +94,7 @@ class ImportScreenComponent extends React.Component {
lastProgress = line.join(' ');
this.addMessage('progress', lastProgress);
},
onError: error => {
onError: (error: any) => {
// Don't display the error directly because most of the time it doesn't matter
// (eg. for weird broken HTML, but the note is still imported)
console.warn('When importing ENEX file', error);
@ -116,7 +133,7 @@ class ImportScreenComponent extends React.Component {
}
}
const mapStateToProps = state => {
const mapStateToProps = (state: AppState) => {
return {
themeId: state.settings.theme,
};
@ -124,4 +141,5 @@ const mapStateToProps = state => {
const ImportScreen = connect(mapStateToProps)(ImportScreenComponent);
module.exports = { ImportScreen };
export default ImportScreen;

View File

@ -1,8 +1,27 @@
const React = require('react');
import * as React from 'react';
class ItemList extends React.Component {
constructor() {
super();
interface Props {
style: any;
itemHeight: number;
items: any[];
disabled: boolean;
onKeyDown: Function;
itemRenderer: Function;
className: string;
}
interface State {
topItemIndex: number;
bottomItemIndex: number;
}
class ItemList extends React.Component<Props, State> {
private scrollTop_: number;
private listRef: any;
constructor(props: Props) {
super(props);
this.scrollTop_ = 0;
@ -12,12 +31,12 @@ class ItemList extends React.Component {
this.onKeyDown = this.onKeyDown.bind(this);
}
visibleItemCount(props) {
visibleItemCount(props: Props = undefined) {
if (typeof props === 'undefined') props = this.props;
return Math.ceil(props.style.height / props.itemHeight);
}
updateStateItemIndexes(props) {
updateStateItemIndexes(props: Props = undefined) {
if (typeof props === 'undefined') props = this.props;
const topItemIndex = Math.floor(this.scrollTop_ / props.itemHeight);
@ -44,20 +63,20 @@ class ItemList extends React.Component {
this.updateStateItemIndexes();
}
UNSAFE_componentWillReceiveProps(newProps) {
UNSAFE_componentWillReceiveProps(newProps: Props) {
this.updateStateItemIndexes(newProps);
}
onScroll(event) {
onScroll(event: any) {
this.scrollTop_ = event.target.scrollTop;
this.updateStateItemIndexes();
}
onKeyDown(event) {
onKeyDown(event: any) {
if (this.props.onKeyDown) this.props.onKeyDown(event);
}
makeItemIndexVisible(itemIndex) {
makeItemIndexVisible(itemIndex: number) {
const top = Math.min(this.props.items.length - 1, this.state.topItemIndex);
const bottom = Math.max(0, this.state.bottomItemIndex);
@ -105,7 +124,7 @@ class ItemList extends React.Component {
if (!this.props.itemHeight) throw new Error('itemHeight is required');
const blankItem = function(key, height) {
const blankItem = function(key: string, height: number) {
return <div key={key} style={{ height: height }}></div>;
};
@ -129,4 +148,4 @@ class ItemList extends React.Component {
}
}
module.exports = { ItemList };
export default ItemList;

View File

@ -43,7 +43,7 @@ import invitationRespond from '../../services/share/invitationRespond';
import restart from '../../services/restart';
const { connect } = require('react-redux');
import PromptDialog from '../PromptDialog';
const NotePropertiesDialog = require('../NotePropertiesDialog.min.js');
import NotePropertiesDialog from '../NotePropertiesDialog';
const PluginManager = require('@joplin/lib/services/PluginManager');
const ipcRenderer = require('electron').ipcRenderer;

View File

@ -1,11 +1,15 @@
const React = require('react');
const Component = React.Component;
const Setting = require('@joplin/lib/models/Setting').default;
const { connect } = require('react-redux');
import Setting from '@joplin/lib/models/Setting';
import { AppState } from '../app.reducer';
const bridge = require('@electron/remote').require('./bridge').default;
class NavigatorComponent extends Component {
UNSAFE_componentWillReceiveProps(newProps) {
interface Props {
route: any;
}
class NavigatorComponent extends React.Component<Props> {
UNSAFE_componentWillReceiveProps(newProps: Props) {
if (newProps.route) {
const screenInfo = this.props.screens[newProps.route.routeName];
const devMarker = Setting.value('env') === 'dev' ? ` (DEV - ${Setting.value('profileDir')})` : '';
@ -17,7 +21,7 @@ class NavigatorComponent extends Component {
}
}
updateWindowTitle(title) {
updateWindowTitle(title: string) {
try {
if (bridge().window()) bridge().window().setTitle(title);
} catch (error) {
@ -46,10 +50,10 @@ class NavigatorComponent extends Component {
}
}
const Navigator = connect(state => {
const Navigator = connect((state: AppState) => {
return {
route: state.route,
};
})(NavigatorComponent);
module.exports = { Navigator };
export default Navigator;

View File

@ -882,6 +882,7 @@ function CodeMirror(props: NoteBodyEditorProps, ref: any) {
<div style={cellViewerStyle}>
<NoteTextViewer
ref={webviewRef}
themeId={props.themeId}
viewerStyle={styles.viewer}
onIpcMessage={webview_ipcMessage}
onDomReady={webview_domReady}

View File

@ -34,12 +34,12 @@ import ExternalEditWatcher from '@joplin/lib/services/ExternalEditWatcher';
const { themeStyle } = require('@joplin/lib/theme');
const { substrWithEllipsis } = require('@joplin/lib/string-utils');
const NoteSearchBar = require('../NoteSearchBar.min.js');
import NoteSearchBar from '../NoteSearchBar';
import { reg } from '@joplin/lib/registry';
import Note from '@joplin/lib/models/Note';
import Folder from '@joplin/lib/models/Folder';
const bridge = require('@electron/remote').require('./bridge').default;
const NoteRevisionViewer = require('../NoteRevisionViewer.min');
import NoteRevisionViewer from '../NoteRevisionViewer';
const commands = [
require('./commands/showRevisions'),

View File

@ -13,7 +13,7 @@ import CommandService from '@joplin/lib/services/CommandService';
import shim from '@joplin/lib/shim';
import styled from 'styled-components';
import { themeStyle } from '@joplin/lib/theme';
const { ItemList } = require('../ItemList.min.js');
import ItemList from '../ItemList';
const { connect } = require('react-redux');
import Note from '@joplin/lib/models/Note';
import Folder from '@joplin/lib/models/Folder';

View File

@ -1,18 +1,38 @@
const React = require('react');
const { _ } = require('@joplin/lib/locale');
const { themeStyle } = require('@joplin/lib/theme');
const time = require('@joplin/lib/time').default;
const DialogButtonRow = require('./DialogButtonRow').default;
import * as React from 'react';
import { _ } from '@joplin/lib/locale';
import { themeStyle } from '@joplin/lib/theme';
import time from '@joplin/lib/time';
import DialogButtonRow from './DialogButtonRow';
import Note from '@joplin/lib/models/Note';
import bridge from '../services/bridge';
import shim from '@joplin/lib/shim';
import { NoteEntity } from '@joplin/lib/services/database/types';
const Datetime = require('react-datetime').default;
const Note = require('@joplin/lib/models/Note').default;
const formatcoords = require('formatcoords');
const bridge = require('@electron/remote').require('./bridge').default;
const shim = require('@joplin/lib/shim').default;
const { clipboard } = require('electron');
const formatcoords = require('formatcoords');
class NotePropertiesDialog extends React.Component {
constructor() {
super();
interface Props {
noteId: string;
onClose: Function;
onRevisionLinkClick: Function;
themeId: number;
}
interface State {
editedKey: string;
formNote: any;
editedValue: any;
}
class NotePropertiesDialog extends React.Component<Props, State> {
private okButton: any;
private keyToLabel_: Record<string, string>;
private styleKey_: number;
private styles_: any;
constructor(props: Props) {
super(props);
this.revisionsLink_click = this.revisionsLink_click.bind(this);
this.buttonRow_click = this.buttonRow_click.bind(this);
@ -37,7 +57,7 @@ class NotePropertiesDialog extends React.Component {
}
componentDidMount() {
this.loadNote(this.props.noteId);
void this.loadNote(this.props.noteId);
}
componentDidUpdate() {
@ -46,7 +66,7 @@ class NotePropertiesDialog extends React.Component {
}
}
async loadNote(noteId) {
async loadNote(noteId: string) {
if (!noteId) {
this.setState({ formNote: null });
} else {
@ -56,8 +76,8 @@ class NotePropertiesDialog extends React.Component {
}
}
latLongFromLocation(location) {
const o = {};
latLongFromLocation(location: string) {
const o: any = {};
const l = location.split(',');
if (l.length === 2) {
o.latitude = l[0].trim();
@ -69,8 +89,8 @@ class NotePropertiesDialog extends React.Component {
return o;
}
noteToFormNote(note) {
const formNote = {};
noteToFormNote(note: NoteEntity) {
const formNote: any = {};
formNote.user_updated_time = time.formatMsToLocal(note.user_updated_time);
formNote.user_created_time = time.formatMsToLocal(note.user_created_time);
@ -93,7 +113,7 @@ class NotePropertiesDialog extends React.Component {
return formNote;
}
formNoteToNote(formNote) {
formNoteToNote(formNote: any) {
const note = Object.assign({ id: formNote.id }, this.latLongFromLocation(formNote.location));
note.user_created_time = time.formatLocalToMs(formNote.user_created_time);
note.user_updated_time = time.formatLocalToMs(formNote.user_updated_time);
@ -107,7 +127,7 @@ class NotePropertiesDialog extends React.Component {
return note;
}
styles(themeId) {
styles(themeId: number) {
const styleKey = themeId;
if (styleKey === this.styleKey_) return this.styles_;
@ -148,7 +168,7 @@ class NotePropertiesDialog extends React.Component {
return this.styles_;
}
async closeDialog(applyChanges) {
async closeDialog(applyChanges: boolean) {
if (applyChanges) {
await this.saveProperty();
const note = this.formNoteToNote(this.state.formNote);
@ -163,26 +183,26 @@ class NotePropertiesDialog extends React.Component {
}
}
buttonRow_click(event) {
this.closeDialog(event.buttonName === 'ok');
buttonRow_click(event: any) {
void this.closeDialog(event.buttonName === 'ok');
}
revisionsLink_click() {
this.closeDialog(false);
void this.closeDialog(false);
if (this.props.onRevisionLinkClick) this.props.onRevisionLinkClick();
}
editPropertyButtonClick(key, initialValue) {
editPropertyButtonClick(key: string, initialValue: any) {
this.setState({
editedKey: key,
editedValue: initialValue,
});
shim.setTimeout(() => {
if (this.refs.editField.openCalendar) {
this.refs.editField.openCalendar();
if ((this.refs.editField as any).openCalendar) {
(this.refs.editField as any).openCalendar();
} else {
this.refs.editField.focus();
(this.refs.editField as any).focus();
}
}, 100);
}
@ -190,7 +210,7 @@ class NotePropertiesDialog extends React.Component {
async saveProperty() {
if (!this.state.editedKey) return;
return new Promise((resolve) => {
return new Promise((resolve: Function) => {
const newFormNote = Object.assign({}, this.state.formNote);
if (this.state.editedKey.indexOf('_time') >= 0) {
@ -214,7 +234,7 @@ class NotePropertiesDialog extends React.Component {
}
async cancelProperty() {
return new Promise((resolve) => {
return new Promise((resolve: Function) => {
this.okButton.current.focus();
this.setState({
editedKey: null,
@ -225,7 +245,7 @@ class NotePropertiesDialog extends React.Component {
});
}
createNoteField(key, value) {
createNoteField(key: string, value: any) {
const styles = this.styles(this.props.themeId);
const theme = themeStyle(this.props.themeId);
const labelComp = <label style={Object.assign({}, theme.textStyle, theme.controlBoxLabel)}>{this.formatLabel(key)}</label>;
@ -234,11 +254,11 @@ class NotePropertiesDialog extends React.Component {
let editCompHandler = null;
let editCompIcon = null;
const onKeyDown = event => {
const onKeyDown = (event: any) => {
if (event.keyCode === 13) {
this.saveProperty();
void this.saveProperty();
} else if (event.keyCode === 27) {
this.cancelProperty();
void this.cancelProperty();
}
};
@ -251,17 +271,17 @@ class NotePropertiesDialog extends React.Component {
dateFormat={time.dateFormat()}
timeFormat={time.timeFormat()}
inputProps={{
onKeyDown: event => onKeyDown(event, key),
onKeyDown: (event: any) => onKeyDown(event),
style: styles.input,
}}
onChange={momentObject => {
onChange={(momentObject: any) => {
this.setState({ editedValue: momentObject });
}}
/>
);
editCompHandler = () => {
this.saveProperty();
void this.saveProperty();
};
editCompIcon = 'fa-save';
} else {
@ -344,12 +364,12 @@ class NotePropertiesDialog extends React.Component {
);
}
formatLabel(key) {
formatLabel(key: string) {
if (this.keyToLabel_[key]) return this.keyToLabel_[key];
return key;
}
formatValue(key, note) {
formatValue(key: string, note: NoteEntity) {
if (key === 'location') {
if (!Number(note.latitude) && !Number(note.longitude)) return null;
const dms = formatcoords(Number(note.latitude), Number(note.longitude));
@ -357,10 +377,10 @@ class NotePropertiesDialog extends React.Component {
}
if (['user_updated_time', 'user_created_time', 'todo_completed'].indexOf(key) >= 0) {
return time.formatMsToLocal(note[key]);
return time.formatMsToLocal((note as any)[key]);
}
return note[key];
return (note as any)[key];
}
render() {
@ -389,4 +409,4 @@ class NotePropertiesDialog extends React.Component {
}
}
module.exports = NotePropertiesDialog;
export default NotePropertiesDialog;

View File

@ -1,25 +1,45 @@
const React = require('react');
const { connect } = require('react-redux');
const { themeStyle } = require('@joplin/lib/theme');
const { _ } = require('@joplin/lib/locale');
const NoteTextViewer = require('./NoteTextViewer').default;
const HelpButton = require('./HelpButton.min');
const BaseModel = require('@joplin/lib/BaseModel').default;
const Revision = require('@joplin/lib/models/Revision').default;
import * as React from 'react';
import { themeStyle } from '@joplin/lib/theme';
import { _ } from '@joplin/lib/locale';
import NoteTextViewer from './NoteTextViewer';
import HelpButton from './HelpButton';
import BaseModel from '@joplin/lib/BaseModel';
import Revision from '@joplin/lib/models/Revision';
import Setting from '@joplin/lib/models/Setting';
import RevisionService from '@joplin/lib/services/RevisionService';
import { MarkupToHtml } from '@joplin/renderer';
import time from '@joplin/lib/time';
import bridge from '../services/bridge';
import markupLanguageUtils from '../utils/markupLanguageUtils';
import { NoteEntity, RevisionEntity } from '@joplin/lib/services/database/types';
import { AppState } from '../app.reducer';
const urlUtils = require('@joplin/lib/urlUtils');
const Setting = require('@joplin/lib/models/Setting').default;
const RevisionService = require('@joplin/lib/services/RevisionService').default;
const shared = require('@joplin/lib/components/shared/note-screen-shared.js');
const { MarkupToHtml } = require('@joplin/renderer');
const time = require('@joplin/lib/time').default;
const ReactTooltip = require('react-tooltip');
const { urlDecode } = require('@joplin/lib/string-utils');
const bridge = require('@electron/remote').require('./bridge').default;
const markupLanguageUtils = require('../utils/markupLanguageUtils').default;
const { connect } = require('react-redux');
const shared = require('@joplin/lib/components/shared/note-screen-shared.js');
class NoteRevisionViewerComponent extends React.PureComponent {
constructor() {
super();
interface Props {
themeId: number;
noteId: string;
onBack: Function;
customCss: string;
}
interface State {
note: NoteEntity;
revisions: RevisionEntity[];
currentRevId: string;
restoring: boolean;
}
class NoteRevisionViewerComponent extends React.PureComponent<Props, State> {
private viewerRef_: any;
private helpButton_onClick: Function;
constructor(props: Props) {
super(props);
this.state = {
revisions: [],
@ -65,7 +85,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
currentRevId: revisions.length ? revisions[revisions.length - 1].id : '',
},
() => {
this.reloadNote();
void this.reloadNote();
}
);
}
@ -82,7 +102,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
if (this.props.onBack) this.props.onBack();
}
revisionList_onChange(event) {
revisionList_onChange(event: any) {
const value = event.target.value;
if (!value) {
@ -93,7 +113,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
currentRevId: value,
},
() => {
this.reloadNote();
void this.reloadNote();
}
);
}
@ -128,12 +148,12 @@ class NoteRevisionViewerComponent extends React.PureComponent {
});
this.viewerRef_.current.send('setHtml', result.html, {
cssFiles: result.cssFiles,
// cssFiles: result.cssFiles,
pluginAssets: result.pluginAssets,
});
}
async webview_ipcMessage(event) {
async webview_ipcMessage(event: any) {
// For the revision view, we only suppport a minimal subset of the IPC messages.
// For example, we don't need interactive checkboxes or sync between viewer and editor view.
// We try to get most links work though, except for internal (joplin://) links.
@ -148,9 +168,9 @@ class NoteRevisionViewerComponent extends React.PureComponent {
throw new Error(_('Unsupported link or message: %s', msg));
} else if (urlUtils.urlProtocol(msg)) {
if (msg.indexOf('file://') === 0) {
require('electron').shell.openExternal(urlDecode(msg));
void require('electron').shell.openExternal(urlDecode(msg));
} else {
require('electron').shell.openExternal(msg);
void require('electron').shell.openExternal(msg);
}
} else if (msg.indexOf('#') === 0) {
// This is an internal anchor, which is handled by the WebView so skip this case
@ -202,7 +222,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
const viewer = <NoteTextViewer themeId={this.props.themeId} viewerStyle={{ display: 'flex', flex: 1, borderLeft: 'none' }} ref={this.viewerRef_} onDomReady={this.viewer_domReady} onIpcMessage={this.webview_ipcMessage} />;
return (
<div style={style.root}>
<div style={style.root as any}>
{titleInput}
{viewer}
<ReactTooltip place="bottom" delayShow={300} className="help-tooltip" />
@ -211,7 +231,7 @@ class NoteRevisionViewerComponent extends React.PureComponent {
}
}
const mapStateToProps = state => {
const mapStateToProps = (state: AppState) => {
return {
themeId: state.settings.theme,
};
@ -219,4 +239,4 @@ const mapStateToProps = state => {
const NoteRevisionViewer = connect(mapStateToProps)(NoteRevisionViewerComponent);
module.exports = NoteRevisionViewer;
export default NoteRevisionViewer;

View File

@ -1,10 +1,27 @@
const React = require('react');
const { themeStyle } = require('@joplin/lib/theme');
const { _ } = require('@joplin/lib/locale');
import * as React from 'react';
import { themeStyle } from '@joplin/lib/theme';
import { _ } from '@joplin/lib/locale';
class NoteSearchBar extends React.Component {
constructor() {
super();
interface Props {
themeId: number;
onNext: Function;
onPrevious: Function;
onClose: Function;
onChange: Function;
query: string;
searching: boolean;
resultCount: number;
selectedIndex: number;
visiblePanes: string[];
style: any;
}
class NoteSearchBar extends React.Component<Props> {
private backgroundColor: any;
constructor(props: Props) {
super(props);
this.searchInput_change = this.searchInput_change.bind(this);
this.searchInput_keyDown = this.searchInput_keyDown.bind(this);
@ -29,7 +46,7 @@ class NoteSearchBar extends React.Component {
return style;
}
buttonIconComponent(iconName, clickHandler, isEnabled) {
buttonIconComponent(iconName: string, clickHandler: any, isEnabled: boolean) {
const theme = themeStyle(this.props.themeId);
const searchButton = {
@ -57,12 +74,12 @@ class NoteSearchBar extends React.Component {
);
}
searchInput_change(event) {
searchInput_change(event: any) {
const query = event.currentTarget.value;
this.triggerOnChange(query);
}
searchInput_keyDown(event) {
searchInput_keyDown(event: any) {
if (event.keyCode === 13) {
// ENTER
event.preventDefault();
@ -101,13 +118,13 @@ class NoteSearchBar extends React.Component {
if (this.props.onClose) this.props.onClose();
}
triggerOnChange(query) {
triggerOnChange(query: string) {
if (this.props.onChange) this.props.onChange(query);
}
focus() {
this.refs.searchInput.focus();
this.refs.searchInput.select();
(this.refs.searchInput as any).focus();
(this.refs.searchInput as any).select();
}
render() {
@ -177,4 +194,4 @@ class NoteSearchBar extends React.Component {
}
}
module.exports = NoteSearchBar;
export default NoteSearchBar;

View File

@ -1,9 +1,16 @@
const React = require('react');
import * as React from 'react';
import time from '@joplin/lib/time';
import { themeStyle } from '@joplin/lib/theme';
import { NoteEntity } from '@joplin/lib/services/database/types';
import { AppState } from '../app.reducer';
const { connect } = require('react-redux');
const time = require('@joplin/lib/time').default;
const { themeStyle } = require('@joplin/lib/theme');
class NoteStatusBarComponent extends React.Component {
interface Props {
themeId: number;
note: NoteEntity;
}
class NoteStatusBarComponent extends React.Component<Props> {
style() {
const theme = themeStyle(this.props.themeId);
@ -23,7 +30,7 @@ class NoteStatusBarComponent extends React.Component {
}
}
const mapStateToProps = state => {
const mapStateToProps = (state: AppState) => {
return {
// notes: state.notes,
// folders: state.folders,
@ -34,4 +41,4 @@ const mapStateToProps = state => {
const NoteStatusBar = connect(mapStateToProps)(NoteStatusBarComponent);
module.exports = { NoteStatusBar };
export default NoteStatusBar;

View File

@ -6,7 +6,8 @@ interface Props {
onDomReady: Function;
onIpcMessage: Function;
viewerStyle: any;
contentMaxWidth: number;
contentMaxWidth?: number;
themeId: number;
}
export default class NoteTextViewerComponent extends React.Component<Props, any> {

View File

@ -24,9 +24,9 @@ import MasterPasswordDialog from './MasterPasswordDialog/Dialog';
import EditFolderDialog from './EditFolderDialog/Dialog';
import PdfViewer from './PdfViewer';
import StyleSheetContainer from './StyleSheets/StyleSheetContainer';
const { ImportScreen } = require('./ImportScreen.min.js');
import ImportScreen from './ImportScreen';
const { ResourceScreen } = require('./ResourceScreen.js');
const { Navigator } = require('./Navigator.min.js');
import Navigator from './Navigator';
const WelcomeUtils = require('@joplin/lib/WelcomeUtils');
const { ThemeProvider, StyleSheetManager, createGlobalStyle } = require('styled-components');
const bridge = require('@electron/remote').require('./bridge').default;

View File

@ -1,7 +1,8 @@
const React = require('react');
const { connect } = require('react-redux');
const { themeStyle } = require('@joplin/lib/theme');
const CommandService = require('@joplin/lib/services/CommandService').default;
import { themeStyle } from '@joplin/lib/theme';
import CommandService from '@joplin/lib/services/CommandService';
import { AppState } from '../app.reducer';
class TagItemComponent extends React.Component {
render() {
@ -13,10 +14,8 @@ class TagItemComponent extends React.Component {
}
}
const mapStateToProps = state => {
const mapStateToProps = (state: AppState) => {
return { themeId: state.settings.theme };
};
const TagItem = connect(mapStateToProps)(TagItemComponent);
module.exports = TagItem;
export default connect(mapStateToProps)(TagItemComponent);

View File

@ -1,10 +1,10 @@
import * as React from 'react';
import { useMemo } from 'react';
import { AppState } from '../app.reducer';
import TagItem from './TagItem';
const { connect } = require('react-redux');
const { themeStyle } = require('@joplin/lib/theme');
const TagItem = require('./TagItem.min.js');
interface Props {
themeId: number;

View File

@ -1,9 +1,9 @@
import * as React from 'react';
import ToolbarButton from './ToolbarButton/ToolbarButton';
import ToggleEditorsButton, { Value } from './ToggleEditorsButton/ToggleEditorsButton';
const React = require('react');
import ToolbarSpace from './ToolbarSpace';
const { connect } = require('react-redux');
const { themeStyle } = require('@joplin/lib/theme');
const ToolbarSpace = require('./ToolbarSpace.min.js');
interface Props {
themeId: number;

View File

@ -1,14 +0,0 @@
const React = require('react');
const { themeStyle } = require('@joplin/lib/theme');
class ToolbarSpace extends React.Component {
render() {
const theme = themeStyle(this.props.themeId);
const style = Object.assign({}, theme.toolbarStyle);
style.minWidth = style.height / 2;
return <span style={style}></span>;
}
}
module.exports = ToolbarSpace;

View File

@ -0,0 +1,18 @@
import * as React from 'react';
import { themeStyle } from '@joplin/lib/theme';
interface Props {
themeId: number;
}
class ToolbarSpace extends React.Component<Props> {
render() {
const theme = themeStyle(this.props.themeId);
const style = Object.assign({}, theme.toolbarStyle);
style.minWidth = style.height / 2;
return <span style={style}></span>;
}
}
export default ToolbarSpace;

View File

@ -1,100 +0,0 @@
const React = require('react');
const bridge = require('@electron/remote').require('./bridge').default;
class VerticalResizer extends React.PureComponent {
constructor() {
super();
this.state = {
parentRight: 0,
parentHeight: 0,
parentWidth: 0,
drag: {
startX: 0,
lastX: 0,
},
};
this.onDragStart = this.onDragStart.bind(this);
this.onDrag = this.onDrag.bind(this);
this.onDragEnd = this.onDragEnd.bind(this);
this.document_onDragOver = this.document_onDragOver.bind(this);
}
document_onDragOver(event) {
// This is just to prevent the cursor from changing to a "+" as it's dragged
// over other elements. With this it stays a normal cursor.
event.dataTransfer.dropEffect = 'none';
}
onDragStart(event) {
document.addEventListener('dragover', this.document_onDragOver);
event.dataTransfer.dropEffect = 'none';
const cursor = bridge().screen().getCursorScreenPoint();
this.setState({
drag: {
startX: cursor.x,
lastX: cursor.x,
},
});
if (this.props.onDragStart) this.props.onDragStart({});
}
onDrag() {
// If we got a drag event with no buttons pressed, it's the last drag event
// that we should ignore, because it's sometimes use to put the dragged element
// back to its original position (if there was no valid drop target), which we don't want.
// Also if clientX, screenX, etc. are 0, it's also the last event and we want to ignore these buggy values.
// const e = event.nativeEvent;
// if (!e.buttons || (!e.clientX && !e.clientY && !e.screenX && !e.screenY)) return;
const cursor = bridge().screen().getCursorScreenPoint();
const newX = cursor.x;
const delta = newX - this.state.drag.lastX;
if (!delta) return;
this.setState(
{
drag: Object.assign({}, this.state.drag, { lastX: newX }),
},
() => {
this.props.onDrag({ deltaX: delta });
}
);
}
onDragEnd() {
document.removeEventListener('dragover', this.document_onDragOver);
}
componentWillUnmount() {
document.removeEventListener('dragover', this.document_onDragOver);
}
render() {
const debug = false;
const rootStyle = Object.assign(
{},
{
height: '100%',
width: 5,
borderColor: 'red',
borderWidth: debug ? 1 : 0,
borderStyle: 'solid',
cursor: 'col-resize',
boxSizing: 'border-box',
opacity: 0,
},
this.props.style
);
return <div style={rootStyle} draggable={true} onDragStart={this.onDragStart} onDrag={this.onDrag} onDragEnd={this.onDragEnd} />;
}
}
module.exports = VerticalResizer;

View File

@ -1,11 +1,8 @@
'use strict';
const { createSelector } = require('reselect');
const { themeStyle } = require('@joplin/lib/theme');
const themeSelector = (state, props) => themeStyle(props.themeId);
const style = createSelector(
themeSelector,
(theme) => {
const style = createSelector(themeSelector, (theme) => {
const output = {
root: {
width: 220,
@ -41,9 +38,7 @@ const style = createSelector(
fontWeight: 'bold',
},
};
return output;
}
);
});
module.exports = style;
// # sourceMappingURL=ExtensionBadge.js.map

View File

@ -113,8 +113,6 @@
"@types/react": "16.14.34",
"@types/react-redux": "7.1.25",
"@types/styled-components": "5.1.26",
"babel-cli": "6.26.0",
"babel-preset-react": "6.24.1",
"electron": "19.1.4",
"electron-builder": "23.6.0",
"electron-notarize": "1.2.2",

View File

@ -14,7 +14,7 @@ import Tag from '@joplin/lib/models/Tag';
import Folder from '@joplin/lib/models/Folder';
import Note from '@joplin/lib/models/Note';
const { ItemList } = require('../gui/ItemList.min');
const HelpButton = require('../gui/HelpButton.min');
import HelpButton from '../gui/HelpButton';
const { surroundKeywords, nextWhitespaceIndex, removeDiacritics } = require('@joplin/lib/string-utils.js');
import { mergeOverlappingIntervals } from '@joplin/lib/ArrayUtils';
import markupLanguageUtils from '../utils/markupLanguageUtils';

View File

@ -1,61 +1,8 @@
const fs = require('fs-extra');
const spawnSync = require('child_process').spawnSync;
const { chdir } = require('process');
const basePath = `${__dirname}/../../..`;
function fileIsNewerThan(path1, path2) {
if (!fs.existsSync(path2)) return true;
const stat1 = fs.statSync(path1);
const stat2 = fs.statSync(path2);
return stat1.mtime > stat2.mtime;
}
function convertJsx(paths) {
chdir(`${__dirname}/..`);
paths.forEach(path => {
fs.readdirSync(path).forEach((filename) => {
const jsxPath = `${path}/${filename}`;
const p = jsxPath.split('.');
if (p.length <= 1) return;
const ext = p[p.length - 1];
if (ext !== 'jsx') return;
p.pop();
const basePath = p.join('.');
const jsPath = `${basePath}.min.js`;
if (fileIsNewerThan(jsxPath, jsPath)) {
console.info(`Compiling ${jsxPath}...`);
// { shell: true } is needed to get it working on Windows:
// https://discourse.joplinapp.org/t/attempting-to-build-on-windows/22559/12
const result = spawnSync('yarn', ['run', 'babel', '--presets', 'react', '--out-file', jsPath, jsxPath], { shell: true });
if (result.status !== 0) {
const msg = [];
if (result.stdout) msg.push(result.stdout.toString());
if (result.stderr) msg.push(result.stderr.toString());
console.error(msg.join('\n'));
if (result.error) console.error(result.error);
process.exit(result.status);
}
}
});
});
}
module.exports = function() {
convertJsx([
`${__dirname}/../gui`,
`${__dirname}/../gui/MainScreen`,
`${__dirname}/../gui/NoteList`,
`${__dirname}/../plugins`,
]);
const libContent = [
fs.readFileSync(`${basePath}/packages/lib/string-utils-common.js`, 'utf8'),
fs.readFileSync(`${basePath}/packages/lib/markJsUtils.js`, 'utf8'),

View File

@ -3,7 +3,6 @@ import { _ } from '../../locale';
import BaseItem, { EncryptedItemsStats } from '../../models/BaseItem';
import useAsyncEffect, { AsyncEffectEvent } from '../../hooks/useAsyncEffect';
import { MasterKeyEntity } from '../../services/e2ee/types';
// import time from '../../time';
import { findMasterKeyPassword, getMasterPasswordStatus, masterPasswordIsValid, MasterPasswordStatus } from '../../services/e2ee/utils';
import EncryptionService from '../../services/e2ee/EncryptionService';
import { masterKeyEnabled, setMasterKeyEnabled } from '../../services/synchronizer/syncInfoUtils';

712
yarn.lock

File diff suppressed because it is too large Load Diff