Skip to content

Commit

Permalink
Rewrite app core to remove data races and fix data flow
Browse files Browse the repository at this point in the history
Trap account name when connecting
Type Simperium for real
Re-connect note editing to Simperium; bounce updated notes
Add sync indicators on note-level
remove pending ccid list; small cleanup
Fix or skip or delete failing tests
Bow to the linting gatekeepers
Bow to the linting gatekeepers
Try: remove arm builds to get electron-builder to go
Move all checkbox translation into the editor component
Adjust editor cursor/selection in response to remote updates
Fix edge cases with tasks and selection tracking
Track editor selection direction
Earmark selection tracking on undo/redo for later
Debounce search when receiving updates
Select first note that loads in app
Use search sort index instead of sorting on every search
Fix performance and display issues with note list previews
Allow syncing new notes
Add revision panel back in
Start making tag list sortable and editable
Inline checkbox/task font

I tried using a file-loader and things got complicated with Monaco's fonts
By inlining the font as a data-uri there's no complexity other than maintaining
the font, but it's trivial enough to recreate the font and convert it into
base64 that I felt it was sufficient to let this be.

Continue restoring functionality to tag list
Add some types to tag list interface
Connect to remote tag updates

Small cluterr
Start tracking tag changes
More tag tracking
Add back has-loaded
Allow tag reordering
Allow deleting tags
Fix title formatting/decorations
Remove syntax highlighting and set auto-indent
Support renaming tags; small font fix and type error fix
Allow escaping from preview mode if note un-markdownd
Fix revisions display issue
Reconnect settings to Electron
Add back "insert task" via hotkey
Extract generic bucket providers; sync tag renames
Synchronize preferences
Converge to a single ghost provider
Remove old noteChangeVersion reducer
Start introducing offline persistence
Load and persist revisions separately from the state
Disable revisions button if no revisions are avialable
Fix typo
Defer loading editor and fetching revisions for performance while switching notes
Fix Safari matchMedia bug

Fix Safari Monaco issue: advanced text-wrap crashes

Degrade gracefully in the absence of indexedDB (private mode)

Remove constraint on having indexedDB in platform support

Doubt relevance of test

Refactor code to avoid lint issue

Use published @types/simperium

Sync changes with bucket-queue worker

Use queue function not setTimeout for note sync

Create Note Doctor to find discrepancies with note sync

Warn when logging out with unconfirmed changes

Reconnect the rest of the menu options/settings

Fix Export (#2180)

Fix export on rewrite/no-races

Send notification on note update

Send message when note trashed

Limit notification length and provide default text

Allow logging out when no changes are unconfirmed

Move notifications code into new module

Separate local confirmations from remote updates

(dev) expose buckets to console

Add (un)publish notifications; skip some notification spam

restore tag icons, add overflow for scrolling (#2183)

Fix/search case sensitivity (#2182)

* search should be case insensitive

* fix missing search results due to column alignment

* lowercase term instead of regex

Rewrite tags

Confirm new tags on note creation; delete old tag on rename

Replace Monaco with textarea

Fix: Copy all html if nothing selected (#2184)

* first hack at this, broken

* pass state to useEffect and rename it

* this div is still not working and i am mad

* hook to promise chain, realize clipboard things are hard

* make it work in Safari too

Maintain consistency of login sessions across browser sessions

Fix notifications permissions requests: stop spamming

Fix tag-suggestion tests

Fix lint issues

More lint issues

Add beta warning

Allow exporiting unsyced notes on logout (Electron)

Add logout confirmation dialog

Warn before closing tab with synced changes

Marginally improve cursor when entering task item from hotkey

Stop resizing content editor

Linting issues

Use slightly-faster checkbox replacement

Style last synced indicator (#2203)

Update note list note status icons (#2204)

Add safety for broken/missing indexedDB props: @codebykat

Empty trash (#2209)

* got the basics, not working

* typos in comments

* make it go

Fix tag list CSS (#2210)

* move scrolling to child list

* add some right padding to avoid overlapping with scrollbar

* more small fixes

Reset some optimizations in the editor

Removes bottom border in the tag list (#2214)

Updates CSS for server connection (#2213)

Fix scroll bars on narrow line length (#2211)

When the narrow line length is set the scroll bar was not on the edge of the screen. This moves it back to the edge.

Update/offline badge (#2202)

Moves the offline badge from the bottom right to the note toolbar.

Filter collaboration (email) tags from tag list (#2205)

Updates unsynced notes log out dialog (#2206)

Display unknown in last updated when it is unknown (#2212)

Display unknown in the last synced indicator when we do not know when it was last synced.

Move all tasklist insertion into the editor itself

Use function-ref to boot editor; update text transform in reducer

Insert checkboxes through editor

Continue lists

Fix interaction of lists and tasks

Fix font issues

Add indent/outdent support

Stop indenting lines that follow blank lines

Show checkboxes in previews

Preserve some markdown settings

[rewrite branch] Change the unsynced notes icon to a less-scary one (#2218)

This changes the icon when a note has unsynced changes to the cloud sync icon.

Also changes it to blue and changes both this and the pin to simplenote-blue-20 in dark mode.

Fixes missing ids in note export (#2220)

Clear note list height cache when window width changes

Stop crashing when viewing a trashed note

Remove all text processing

make condensed actually condense (#2222)

[rewrite branch] update note list status icons (#2221)

* add smaller icons and restyle

* forgot to commit the style fix for the bottom border

* larger icons more padding

* clean up styles

Bring back Monaco

Spin sync indicator

only spin the sync icon, not the publish icon

Stop sync spinner when offline

Only load window-close-confirmation to browser

Update the editor width css to allow narrow/wide views (#2224)

Remove the add/confirm step which isn't necessary

Remove confirm step for tags

Fixes styling of offline badge (#2234)

Updates the color of the link in the logout confirm dialog (#2235)

Dont scroll editor past last line (#2238)

When you scroll a note it currently scrolls the note completely off the screen. This PR changes it so it does not scroll past the end of the note. I like the current behavior and think we should add this back as an option.

Allow scroll bar to be any height fixing it only scrolling partially to the bottom (#2239)

We had a fixed height on the scroll bar. This caused it to look like it hadn't scrolled all the way to the bottom. This removes that max height so that the scroll bar displays correctly.

Fixes editor width when narrow line length is selected (#2237)

My previous fix for the editor width only worked on the left margin. This fixes it so the editor width is constrained on both sides. It does however cause the scroll bar to be just inside the narrow view and not on the edge of the screen, see screenshot. I am not sure how to fix it to push it to the side.

This PR also fixes the jerkiness of the note when it opens. The padding applied to the content before the editor is ready is now the same as it is once Monaco renders.

Update height of note list item when condensed (#2246)

Clean up disable restore note button when is newset revision (#2248)

The disable on the restore note button when you are currently on the most recent revision is CSS and was not actually disabling the functionality. Additionally, the logic failed when you first opened the revisions panel. This gets everything into tip top.

Use distinct name for indexedDB persistence

Checks for Notification on window (#2225)

* Checks for Notification on window

* Use optional chaioning

* Dynamically load change announcer

Co-authored-by: Dennis Snell <dennis.snell@automattic.com>

Try for some easy wins on optimizing load

Hides last syncd message when it is unknown (#2236)

Hides the last syncd when it is unknown

Autolist behavior

Only use fast edit mode for long notes

Continue task lists too

Allow bullets at start of line, stop logging actions

Remove some pre-prod TODO items

Transform note content properly when clicking on tasks

Stop trying to fully-load an editor when it's gone

Updates to version 2.0.0-beta1 (#2252)

Disable note doctor for now; uncover bugs easier

Refactor some tag rename logic

[rewrite branch] Add analytics as middleware (#2223)

* centralize analytics again
 - not working attempt to convert to meta key
 - fixed addCollaborator args
 - add removeCollaborator reducer with withEvent
 - Add COLLABORATOR actions
 - remove invalid comments
 - remove unused setAccountName and some more comments
 - trying event queue to add application_opened before preferences are loaded
 - documented bugs :[

* Update analytics setting when bucket connects

* Set initial accountName in Redux init vs. dispatched action

* Send index request for preferences

* Persist account name properly

Co-authored-by: Dennis Snell <dennis.snell@automattic.com>

Remove tri-state analytics toggle

Sequence analytics updates
  • Loading branch information
dmsnell committed Aug 4, 2020
1 parent 2ea1d3d commit 5ec55c2
Show file tree
Hide file tree
Showing 179 changed files with 12,409 additions and 9,904 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ release/
.idea
.DS_Store
dev-app-update.yml
lib/state/data/test_account.json
9 changes: 3 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type OwnProps = {
}

type StateProps = {
notes: T.NoteEntity[];
notes: T.Note[];
}

type DispatchProps = {
Expand Down Expand Up @@ -156,17 +156,14 @@ const loginAttempts: A.Reducer<number> = (state = 0, action) => {
}
}

const selectedNote: A.Reducer<T.NoteEntity[] | null> = (state = null, action) => {
const selectedNote: A.Reducer<T.EntityId | null> = (state = null, action) => {
switch (action.type) {
case 'CREATE_NOTE':
return makeNote();
return action.noteId;

case 'TRASH_NOTE':
return null;

case 'FILTER_NOTES':
return action.filteredNotes.has(state) ? state : null;

default:
return state;
}
Expand Down
2 changes: 1 addition & 1 deletion desktop/menus/file-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const buildFileMenu = (isAuthenticated) => {
visible: isAuthenticated,
accelerator: 'CommandOrControl+Shift+E',
click: appCommandSender({
action: 'exportZipArchive',
action: 'exportNotes',
}),
},
{ type: 'separator' },
Expand Down
28 changes: 27 additions & 1 deletion desktop/preload.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { contextBridge, ipcRenderer } = require('electron');
const { contextBridge, ipcRenderer, remote } = require('electron');

const validChannels = [
'appCommand',
Expand All @@ -11,6 +11,32 @@ const validChannels = [
];

contextBridge.exposeInMainWorld('electron', {
confirmLogout: (changes) => {
const response = remote.dialog.showMessageBoxSync({
type: 'warning',
buttons: [
'Export Unsynced Notes',
"Don't Logout Yet",
'Lose Changes and Logout',
],
title: 'Unsynced Notes Detected',
message:
'Logging out will delete any unsynced notes. ' +
'Do you want to continue or give it a little more time to finish trying to sync?\n\n' +
changes,
});

switch (response) {
case 0:
return 'export';

case 1:
return 'reconsider';

case 2:
return 'logout';
}
},
send: (channel, data) => {
// whitelist channels
if (validChannels.includes(channel)) {
Expand Down
2 changes: 1 addition & 1 deletion e2e/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const waitForEvent = async (
return new Promise((resolve, reject) => {
const f = async () => {
const result = await app.client.execute(function () {
var events = window.testEvents;
const events = window.testEvents;

if (!events.length) {
return undefined;
Expand Down
8 changes: 4 additions & 4 deletions electron-builder.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,19 @@
"target": [
{
"target": "AppImage",
"arch": ["x64", "ia32", "armv7l", "arm64"]
"arch": ["x64", "ia32"]
},
{
"target": "deb",
"arch": ["x64", "ia32", "armv7l", "arm64"]
"arch": ["x64", "ia32"]
},
{
"target": "rpm",
"arch": ["x64", "ia32", "armv7l", "arm64"]
"arch": ["x64", "ia32"]
},
{
"target": "tar.gz",
"arch": ["x64", "ia32", "armv7l", "arm64"]
"arch": ["x64", "ia32"]
}
],
"synopsis": "The simplest way to keep notes",
Expand Down
9 changes: 5 additions & 4 deletions lib/analytics/tracks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function buildTracks() {
let userLogin: string | null | undefined;
const localCache: { [key: string]: string } = {};
let context = {};
let pixel = 'https://pixel.wp.com/t.gif';
const pixel = 'https://pixel.wp.com/t.gif';
let cookieDomain: string | null = null;
const cookiePrefix = 'tk_';
const testCookie = 'tc';
Expand Down Expand Up @@ -129,6 +129,7 @@ function buildTracks() {
}
}

// eslint-disable-next-line
return btoa(String.fromCharCode.apply(String, randomBytes as number[]));
};

Expand All @@ -150,7 +151,7 @@ function buildTracks() {
};

const getQueries = function () {
var queries = get(queriesCookie);
const queries = get(queriesCookie);
return queries ? queries.split(' ') : [];
};

Expand Down Expand Up @@ -181,7 +182,7 @@ function buildTracks() {

const saveQuery = function (query: string) {
removeQuery(query);
let queries = getQueries();
const queries = getQueries();
queries.push(query);
saveQueries(queries);
};
Expand Down Expand Up @@ -244,7 +245,7 @@ function buildTracks() {
if (userLogin) {
query._ul = userLogin;
}
let date = new Date();
const date = new Date();
query._ts = date.getTime();
query._tz = date.getTimezoneOffset() / 60;

Expand Down
79 changes: 44 additions & 35 deletions lib/app-layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import React, { Component, Suspense } from 'react';
import classNames from 'classnames';
import { connect } from 'react-redux';

import NoteToolbarContainer from '../note-toolbar-container';
import NoteToolbar from '../note-toolbar';
import RevisionSelector from '../revision-selector';
import SearchBar from '../search-bar';
import SimplenoteCompactLogo from '../icons/simplenote-compact';
import TransitionDelayEnter from '../components/transition-delay-enter';
import actions from '../state/actions';
import * as selectors from '../state/selectors';

import * as S from '../state';
import * as T from '../types';
Expand All @@ -21,30 +21,31 @@ const NoteEditor = React.lazy(() =>
import(/* webpackChunkName: 'note-editor' */ '../note-editor')
);

type OwnProps = {
const NotePreview = React.lazy(() =>
import(/* webpackChunkName: 'note-preview' */ '../components/note-preview')
);

type StateProps = {
hasRevisions: boolean;
isFocusMode: boolean;
isNavigationOpen: boolean;
isNoteInfoOpen: boolean;
isSmallScreen: boolean;
note: T.NoteEntity;
noteBucket: T.Bucket<T.Note>;
onUpdateContent: Function;
syncNote: Function;
};

type StateProps = {
isNoteOpen: boolean;
isSmallScreen: boolean;
keyboardShortcuts: boolean;
keyboardShortcutsAreOpen: boolean;
openedNote: T.EntityId | null;
openedRevision: number | null;
showNoteList: boolean;
showRevisions: boolean;
};

type DispatchProps = {
hideKeyboardShortcuts: () => any;
showKeyboardShortcuts: () => any;
};

type Props = OwnProps & StateProps & DispatchProps;
type Props = StateProps & DispatchProps;

export class AppLayout extends Component<Props> {
componentDidMount() {
Expand Down Expand Up @@ -81,14 +82,15 @@ export class AppLayout extends Component<Props> {
render = () => {
const {
showNoteList,
hasRevisions,
isFocusMode = false,
isNavigationOpen,
isNoteInfoOpen,
isNoteOpen,
isSmallScreen,
noteBucket,
onUpdateContent,
syncNote,
openedNote,
openedRevision,
showRevisions,
} = this.props;

const mainClasses = classNames('app-layout', {
Expand All @@ -112,22 +114,18 @@ export class AppLayout extends Component<Props> {
<div className={mainClasses}>
<Suspense fallback={placeholder}>
<div className="app-layout__source-column theme-color-bg theme-color-fg">
<SearchBar noteBucket={noteBucket} />
<NoteList noteBucket={noteBucket} isSmallScreen={isSmallScreen} />
<SearchBar />
<NoteList />
</div>
{editorVisible && (
<div className="app-layout__note-column theme-color-bg theme-color-fg theme-color-border">
<RevisionSelector onUpdateContent={onUpdateContent} />
<NoteToolbarContainer
noteBucket={noteBucket}
toolbar={<NoteToolbar />}
/>
<NoteEditor
isSmallScreen={isSmallScreen}
noteBucket={noteBucket}
onUpdateContent={onUpdateContent}
syncNote={syncNote}
/>
{hasRevisions && <RevisionSelector />}
<NoteToolbar />
{showRevisions ? (
<NotePreview noteId={openedNote} note={openedRevision} />
) : (
<NoteEditor />
)}
</div>
)}
</Suspense>
Expand All @@ -136,14 +134,25 @@ export class AppLayout extends Component<Props> {
};
}

const mapStateToProps: S.MapState<StateProps> = ({
ui: { dialogs, showNoteList },
settings: { keyboardShortcuts },
}) => ({
keyboardShortcutsAreOpen: dialogs.includes('KEYBINDINGS'),
keyboardShortcuts,
isNoteOpen: !showNoteList,
showNoteList,
const mapStateToProps: S.MapState<StateProps> = (state) => ({
hasRevisions:
state.ui.showRevisions && state.data.noteRevisions.has(state.ui.openedNote),
keyboardShortcutsAreOpen: state.ui.dialogs.includes('KEYBINDINGS'),
keyboardShortcuts: state.settings.keyboardShortcuts,
isFocusMode: state.settings.focusModeEnabled,
isNavigationOpen: state.ui.showNavigation,
isNoteInfoOpen: state.ui.showNoteInfo,
isNoteOpen: !state.ui.showNoteList,
isSmallScreen: selectors.isSmallScreen(state),
openedRevision:
state.ui.openedRevision?.[0] === state.ui.openedNote
? state.data.noteRevisions
.get(state.ui.openedNote)
?.get(state.ui.openedRevision?.[1]) ?? null
: null,
openedNote: state.ui.openedNote,
showNoteList: state.ui.showNoteList,
showRevisions: state.ui.showRevisions,
});

const mapDispatchToProps: S.MapDispatch<DispatchProps> = {
Expand Down
24 changes: 0 additions & 24 deletions lib/app.test.tsx

This file was deleted.

Loading

0 comments on commit 5ec55c2

Please sign in to comment.