Code Monkey home page Code Monkey logo

pamet's People

Contributors

v-ko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

pamet's Issues

Implement note and arrow selection

  • Alter PageViewState...done

  • Integrate paper.js for intersection calculations and canvas rendering...done

    • Local state for the note rects and arrow paths (for selection calculations)...done
  • Implement click selection...done

    • selectedChildren changes don't trigger a canvas update...done
    • note selection...done
    • arrow selection...done
      • Circle intersection testing...done
  • Implement drag selection

    • PageViewState add props...done
    • Start, update, finish actions...done
    • View rendering of the selection rect...done
    • View user action handling to trigger drag select...done
  • Test

    • Bug: Windows resize breaks canvas coordinate system....done
    • Fix drag select rendering issues...done
    • Stress test...done

AC:

  • Click on an item selects it, deselects all else
  • Click on item with ctrl toggles selection
  • Click on item with shift adds the item to selection
  • Click on canvas clears selection
  • Mouse drag with ctrl+shift pressed, shows a selection rect and selects items under it on release
  • Stress test

Story points:
8 / L

Implement edit window and related functionality

Note editing, at least for the core note types, will happen via a single note edit component. Any interactive integrations will open in a separate modal window.

  • Design the window...done, mostly reusing the desktop design

    • Consider integrations (e.g. script note, audio, video) settings - as a separate panel?...no, as a modal window
    • Consider the mobile interface...done
  • Implement note text editing

    • Implement a minimal component/window...done

    • Add the edit window state as part of the page view state...done

      • Structure the component hierarchy app-mid?-page...done
    • Implement an action to show the edit window and call it on the N button press...done

      • Should be a command, so setup the commands lib...done
        • Mouse position is needed, so setup tracking in the page view state...done
    • Fix the basic layout...done

      • Implement window dragging...done
        • Implement restrictions on drag/resize positions and sizes. Hopefully in css...done, not in css but accetably easy
      • add close button, title and move handle icon...done
    • Text edit related

      • Add text area and fix main content layout...done
      • Pass the note data and populate the text area...done
    • Fix react image element duplicates...done

    • Actions to save/cancel editing...done

      • Add a note() method to the editWindowState...done
      • Implement the saveEditedNote action
        • Add default method to TextNote...done
          • Refactor own/page id storage logic...done
        • Autosize function translate to ts...done
          • Implement Size class...done
      • Note does not update on size change...will be fixed in another issue
      • Add autosize command and shortcut (also a large size shortcut for testing)...done
    • Add E edit window shortcut in page...done

    • Add Esc shortcut for edit window close...done

    • Shortcuts interfere with text typing in the edit window...done

    • Scroll events should also probably be stopped to not bubble...done

    • Double click to edit/new note...done

Acceptance criteria:

  • Edited notes get updated as expected
  • Edit window opens on double-click and N shortcut
  • Closes on Esc

Story tonnage:
3 / S -> 5 / M

Implement deleting the selected items

Add the action, shortcut, command.

Acceptance criteria:
All selected notes and links are deleted. Also the non-selected links, that are connected to deleted notes - are also deleted.

Story points:
S / 3

Remove mobx domain stores and reintroduce the InMemoryStore

  • Fix the domain store related code - it will be used for propagating the changes to the in-mem storage or other (persistence) adapters.. also services like search/undo-redo. Let's leave the mobx store to be used only for views. That's what it's for. Other stuff will be handled by the custom store and channels. Ok, so if i'll pass evereything through the pametCRUD anyway - I might as well make the .note accessor methods return a note copy to be modified in the actions (e.g. refactor the .note to note(), which under the hood calls the computed _note mobx property or whatever). then the updated note/arrow/element gets passed to pametCRUD via the facade methods. I'm taking ownage of the domain store management, so only add a mapping function to update view states on note changes (synchronously, in-action, in the facade, right after the inMemStore update).
    • setCurrentPage action to directly create (or reuse) the PVS , instead of just chanigng the currentPageId...done
    • Reintroduce the InMemoryStore (move methods from facade?)...done
    • Fix facade methods to use the InMemRepo...done
      • Load duplicate errors...done
      • Decide on PametInMemRepo implementation - compose, rather than inherit...not needed. The facade does that. In other words: done
    • applyChangesToViewStates(app_state, changes) reducer-like function will go through all the ViewStates in the app state and swap the data objects on update (fcit no diffing needed. It's only for actual entity changes).
    • add/remove/update EVS methods in the page view state...done
    • Implement applyChangesToViewStates...done
    • Call it after pushing the changes (synchronously) to the inMemStore (so that that mapping happens in-action, and without increased complexity, side-effects etc)...done
    • Test with note creation...done
      • Image note update after loading is broken...resolved in meantime
      • New note change is not reflected...done
    • refactor NVS.note to note() + get _note():computed
    • Rename sync repo to store if it still seems appropriate...not for now

Acceptance criteria:

  • No regressions

Story points:
5 / M

Implement touchpad navigation

  • Two-finger pan
    • Touchpad/mouse mode auto-switch service...done
      • Switch to left-mouse nav...done
        • Fix click selection...done
      • Apply scroll to pan in touchpad mode...done
  • Switch navigation to right-mouse-nav and left-mouse-select

Acceptance criteria:

  • Using the touchpad switches to the respective navigation mode (interpret scrolling as panning)
  • Using the mouse scroll or right-mouse pan switches to mouse mode
  • Page zoom shortcuts (ctrl+plus/minus and ctrl+scroll) are intercepted and interpreted as zoom

Story tonnage:
5 / M

Plan for the local persistence and device sync machinery (that would be compatible with sharing and real-time collab services)

  • Use cases relevant to the problem
    • Offline work and device sync
    • Inter-tab sync, desktop server sync
    • Sharing
    • Real-time collab
    • Undo/redo - not really, will be handled on the change-set level
    • Backups - not really, could use commits, but should be handled in a separate on-device (non-synced) service
    • Full change history retention - not really, should be on-device, non-synced. Again - possibly a separate service or part of the backup
    • Media sync
      • The fetch source can be swapped by intercepting the requests in a service worker. So the browser cache will be used naturally, while the source of the media can be swapped.
  • Constraints/requirements
    • Possibly without accurate time sync for every node
    • Able to tollerate long offline periods and multiple changes (offline work)
    • Multi device multi-user state syncing with automatic conflict resolution. Data loss on conflict is acceptable and resolved on a node seniority principle
    • Worst case scenario merkle-tree hashing tests (200 changed hashes for 750char content leafs + 15000 unchanged content leafs to be recalculated into node-hashes) on "low-end mobile hardware" (chrome dev-tools throttling) take ~160ms. Therefore commit creation cannot be in the main-thread, but can be done on every commit

Story points:
XL / 13 (were expected to be M to L)

Project icon

It will be nice if you can ask Mila to make some simple icon for the project that will be seen in GitHub, Taskbar, Desktop etc.
She will be able to add "Works on several open source projects." to her CV then ;)

Color changing for notes and arrows

Change the note color model to use named styles and add the color editing feature to the GUI - shortcut, command, menu entry.

The model should be changed from the current entity.style.{color, backgroundColor} to somthing like entity.namedColor

Acceptance criteria:
Successful and persistent color changes to the selected notes/arrows on pressing 1,2,3,4,5 keys

Story points:
L / 8

Implement canvas rendering

  • PixiJS research...no, doesn't include path intersection API, and is heavier

  • Optimize rendering...done

    • Drawing cache service...done
    • Urgent rendering logic...done
    • Testing...done
      • Draw cache rect and add sanity check logging in the untested functions. It's probably the projection matrix...done
      • Test arrow disappearance - probably bad ctx management...done
      • Fix dpr rendering issues...done
        • Fix viewport projection calculation - makes no sense to keep the 0,0 real coords in the viewport center...done
          • Project to topleft in Viewport...done
          • Init vieportCenter in PVS to the element center...done
          • Fix realTopLeft argument in calls...done
      • Fix denovo updates on translate (bad cache rect I guess)...done
      • No patterns appear ever....done
      • Cache rects are variable on DPR!=1 (notes wiggle on panning)...done
        • Add DPR to the Viewport ...done
      • Don't cache on closeup...done
      • There's still rendering artefacts on some scales. Translation invariant...done , fixed by increasing the cache rect padding
      • Initial render update not happening...done
      • Remove PaperJS (and pixi), replace bezier intersection functionality...no, there's no alternative and I fixed performance issues and memory leaks...done
      • Skip redundant queued renders...done
  • Note rendering

    • TextLayout remove empty lines...done

    • Fix notes with new lines...done

    • Call next render if unfinished items...done

    • Plan image rendering...done

      • Take advantage of browser cache

      • Add a lazy image loading service - notes will query it when rendering and will provide fallback container size. The service will either return the image or a placeholder depiction

        • The lazy image service keeps its state in the appState (queued downloads)
        • Well the whole service has to be a queue with cache. I.e. keep most frequently accessed in memory (that is optional actually, but preferable) and regardless if retrieved from cache or abroad - deliver each item to be "consumed" by the renderer. This may be implicitly achieved through the image access method. This means the image disappears on scaling tho.. But only if there's too many images (>cache), which is ok. Which means I don't need a strict consumption mechanism/queue, neither the implicit freeing. Just a cache, and an on-screen warning for "too many images. Will not render all".
        • Alternatively: Since I'll have a boundary on the acceptable image count (for full rendering) - I can implement that in react and not deal with the service. I only need to synchronize react rendering with the canvas rendering to avoid artefacts
        • Final? a lazy image service that queues images for download (+/- in a service worker) upon calling the access method. The service has a view-state: on each finished download a counter is incremented to trigger page rerender, a flag indicates if the queue is empty (shows a spinner otherwise?)

        Final:

        • Upon further consideration - the max note size is 1920x1920. That will be the max image preview size too, which with adequate compression means acceptable memory requirements. The server will provide images with the size of the note (on each note resize - the backend updates its cache). On the cloud/desktop backend the original file is kept (subject to size restrictions). On the PWA backend - files are resized on upload (to 1920x1920, lossy) and kept in the indexDB. On page render - the notes with images will be added as hidden elements (with a placeholder fallback) and their references will be mapped to their NVS/url in the canvas-renderer. The canvasDraw will accept not ctx, but the renderer as a parameter (and will access images by retrieving its ref via some method)
          • since we'll be keeping references (i.e. note view react state) - we can go ahead and add all notes for SEO (invisible) and call the canvasDraw in the component... NO, the two renderers (react, and my canvas-renderer) are separate concerns
            *On the PWA backend - files are resized on upload (to 1920x1920, lossy) and kept in the indexDB... NO , i don't want to deal with caring for the image life cycle
          • Write down the plan in a structured manner...done
    • Render the img tags for the media components with react

      • Will just create the elements hidden with react and query them at render time via the document API...done
      • parseMediaUrl error (mutable data mistake?)...done
    • Implement add/get/clear image element reference...no

    • Put note rendering logic in CanvasElementView components - functional (the simpler option) + leave only NoteViewState (no note-type-specific states). The mapping will be on the View level

      • Add ElementView registration...done
      • Rename the page renderer...done
    • Implement ImageView...done

      • Remove card notes?...yes
    • InternalLinkNote...done

    • Test...done

    • Implement CardView...no

    • Draw link borders when appropriate...done

  • Arrow rendering...done

    • Draw arrow head...done

Acceptance criteria:

  • Correct rendering for all types of notes and for arrows
  • Low latency when stress testing

Story points:
13 / XL

Improve the initial help note

The initial help note could contain a real help information like - "Pres right mouse button to create another note, page etc."

Implement app config class

A key-value base class, and a proper class with property access methods. With adapters for localStorage and in-memory storage (the latter for testing).

Acceptance criteria:
Tests pass, manual tests pass.

Story points:
M / 5

Add WebWorker logging

Extend the logging interface to work in web workers via a broadcast channel.

Acceptance criteria:
A logger instantiated in a web-worker reports to the main thread via a broadcast channel.

Story points:
S / 3

Implement card, script, external link note rendering

  • Card note rendering:

    • Computed layout methods in the view state
  • Script note rendering - reuse text note and decorate

  • External link note - add

Acceptance criteria:

  • Correct rendering in all shapes and sizes
  • Correct text eliding where present
  • Error reporting (for missing script file, etc)

Story tonnage:
3 / S

Local persistence service

The storage service requires a relatively complex setup, since it should be compatible with real-time collaboration and sharing features. Also it should work in a non-blocking manner with a scenario with several open tabs.

Several options were taken into account for the synchronization logic and a number of requirements and constraints were defined (see #21 ).

The final setup includes the following:

  • Implement a VCS system, where the domain store state (pages/notes) is persisted in a repository. The latter holds commits (git-like). When the store is altered - a commit is generated with a content hash (based on the store contents) and a unique id (not based on the content or parent commit ids like in git).
  • Define a synchronisation scheme - The repo may have multiple branches, where each branch corresponds to a device. Each device should write only to its own branch. The repo info can be synced without conflicts in this manner - each device gets all commits and branch info. The merging of remote changes happens by seniority, where junior devices merge changes from the more senior ones and senior devices ignore conflicting changes.
  • The frontend code should not be concerned with that - the frontend operates by using the Frontend domain store (FDS) - an in-memory store, that is used synchronously in the actions triggered by the user.
  • Changes in the FDS trigger commit creation in the storage service. And remote changes received by the storage service are pushed to the frontend domain store and the GUI respectively.
  • The storage service should run in a service worker whenever possible in order to avoid blocking the main thread and to avoid memory/network overhead when many tabs are open and remote sync is happening. That's why it's separated into a StorageService (wrapper class) and a StorageServiceActual (that can be instantiated in a worker). The two communicate via a messaging interface.
  • The storage interface is implemented on the repo/project level. But the user may open several projects (in different tabs, etc). So the storage manager can load/unload Project storage managers (in the StorageServiceActual)
  • Each Project storage manager is instantiated with an adapter config - i.e. typically local persistence (indexedDB adapter) and in the future - a webRTC adapter (for real-time collab, sync) and/or cloud storage.

Overview of the save/receive-update flow:
Image

Acceptance criteria:
Changes persist over separate sessions.

Story points:
XL+ / 13

Implement the main panels in the GUI for desktop

Two panels on the upper left and right, that hold controls and indicators for some core functionality:

  • Pamet logo / projects button
  • Project name / project properties button
  • Help button
  • Page name / page properties button
  • Share button
  • Save/cloud backup indicator

Acceptance criteria:
Visually acceptable at the target form factor (desktop)

Story points:
L / 8

Test navigation rendering optimization options

Navigation lag noticeable in large note files. In theory pure translate/scale transformations should be efficient, so the lag may be alleviated via restricting state-tree diffing operations for the page.

  • Test if pure css var changes reduce the lag...yes, but on low-end devices and large pages that's not enough

Will have to implement canvas/webgl rendering instead of react components for notes/arrows

Remove CRA and fix tests for symlinked folders

  • Testing is broken (craco preserve symlink config stopped working at some point). CRA is a lot of trouble.
    • Migrate to Vite...done
    • Refactor to monorepo...done
      • Vite config problems...done, probably
      • multi-root error. remove node_modules from subfolders?...done
      • Python refactoring problems - cannot import fusion on debug (works from terminal)...done

Acceptance criteria:

  • Running InMemoryRepository tests

Story tonnage:
5 / M

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.