Compare commits

...
Author SHA1 Message Date
StandardNotes CI ac28b29d65 chore(release): publish
- @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected].7
 - @standardnotes/[email protected].7
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
2022-10-21 16:52:42 +00:00
Mo 18235751d4 ci: ios fix 2022-10-21 11:22:04 -05:00
Mo cbd0063926 feat: ability to favorite tags + customize icon (#1858) 2022-10-21 11:11:31 -05:00
StandardNotes CI 3b048a31aa chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
2022-10-21 14:06:04 +00:00
Aman Harwara 4a2dc1ef7a chore: lint 2022-10-21 18:59:07 +05:30
Aman Harwara 21f725bb2a feat: "create new note" floating button on mobile (#1857) 2022-10-21 18:36:55 +05:30
StandardNotes CI 173bacdfa3 chore(release): publish
- @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].6
2022-10-21 13:01:13 +00:00
Karol Sójko c503d781ae fix(web): event observer interface import 2022-10-21 14:31:07 +02:00
Karol Sójko 9fb85cd77a fix: refactor application event observing on web 2022-10-21 14:28:11 +02:00
StandardNotes CI bd40a49484 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
2022-10-21 12:07:49 +00:00
Aman Harwara 4a1612c7dc fix: item selection/unselection on deleting 2022-10-21 17:09:24 +05:30
Aman Harwara d3ed4391b7 fix: template note getting unselected after typing 2022-10-21 16:58:28 +05:30
StandardNotes CI 856e499d89 chore(release): publish
- @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
2022-10-21 08:55:09 +00:00
Karol Sójko 4f0805d5b0 feat(api): add accepting invites by the client 2022-10-21 10:24:49 +02:00
Karol Sójko 401a35f4db fix(ui-services): add route type getter 2022-10-21 10:15:13 +02:00
Karol Sójko 83b484002c feat: add accepting subscription invite route type 2022-10-21 10:05:52 +02:00
StandardNotes CI 30310dbb45 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
2022-10-21 07:23:34 +00:00
Aman Harwara c6e3580678 fix: tag collapse/expand not persisting 2022-10-21 12:24:46 +05:30
Aman Harwara ea285a36d8 Merge branch 'main' of github.com:standardnotes/app 2022-10-21 12:18:22 +05:30
Aman Harwara 1addaf4c39 fix: default auto-dark theme 2022-10-21 12:17:58 +05:30
StandardNotes CI 92bba942f1 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
2022-10-21 06:45:01 +00:00
Aman Harwara f71e6fe703 fix: improve plaintext editor performance on mobile (#1855) 2022-10-21 11:49:23 +05:30
StandardNotes CI 143b528b73 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
2022-10-20 18:35:14 +00:00
Mo 5d202a823e Revert "feat: ability to favorite tags (#1852)"
This reverts commit 4f3b258363.
2022-10-20 13:00:22 -05:00
StandardNotes CI 8d7d577b1c chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
2022-10-20 15:23:16 +00:00
Aman Harwara 76f23e13ec fix: mobx warnings and react render phase set state error 2022-10-20 20:24:56 +05:30
Mo 4f3b258363 feat: ability to favorite tags (#1852) 2022-10-20 09:28:35 -05:00
StandardNotes CI 9cc3304741 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
2022-10-20 13:54:34 +00:00
Aman Harwara 4432f1cb4c feat: persist selected tag & note locally (#1851) 2022-10-20 18:56:59 +05:30
StandardNotes CI 6c47f95748 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
2022-10-20 11:34:22 +00:00
Aman Harwara 57fab4f670 fix: "Forgot passcode" and "Switch workspace" lock screen options not working on mobile (#1850) 2022-10-20 16:26:21 +05:30
StandardNotes CI fb7b9350b2 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
2022-10-20 09:09:38 +00:00
Aman Harwara fb72c2fdae fix: help & feedback links on mobile (#1849) 2022-10-20 14:10:23 +05:30
Aman Harwara 050fa9cabc feat: make sans-serif font default 2022-10-20 13:36:00 +05:30
Aman Harwara a8535cfa23 fix: make tags non-tabbable 2022-10-20 13:34:28 +05:30
Aman Harwara 27bb4ebdae fix: remove tinted border from change note type button 2022-10-20 13:29:59 +05:30
Aman Harwara 60a8e8b92b fix: links for template notes 2022-10-20 13:06:38 +05:30
Aman Harwara 1f07d9fa17 Merge branch 'main' of github.com:standardnotes/app 2022-10-20 12:45:03 +05:30
Aman Harwara d333d4f188 fix: file not linking to note when uploaded by dragging on note 2022-10-20 12:44:50 +05:30
StandardNotes CI 7e3d7a8825 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
2022-10-19 21:18:20 +00:00
Aman Harwara e99c7b7c51 feat: improved file drag-n-drop experience (#1848) 2022-10-20 02:18:52 +05:30
StandardNotes CI 0282a7958a chore(release): publish
- @standardnotes/[email protected].5
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].4
 - @standardnotes/[email protected].6
 - @standardnotes/[email protected].6
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
2022-10-19 20:15:08 +00:00
Mo 4030953b00 fix: issue with not being able to unlink a file from a note (#1836) 2022-10-19 14:36:30 -05:00
Mo ba9a9f8d01 ci: conditional (skip e2e) 2022-10-19 06:56:52 -05:00
Mo 80e76ee52c ci: conditional (skip e2e) 2022-10-19 06:56:00 -05:00
StandardNotes CI bbebfb42fd chore(release): publish
- @standardnotes/[email protected].4
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected].5
 - @standardnotes/[email protected].9
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
2022-10-18 16:21:13 +00:00
Mo 9954bdc29f feat: authorize notes for listed (#1823) 2022-10-18 10:49:30 -05:00
Aman Harwara e4de9c1be7 fix: hide dynamic panels & focused mode options on mobile 2022-10-18 21:02:41 +05:30
Mo 07ffc01ede refactor: add redundant protection checks (#1822) 2022-10-18 10:15:14 -05:00
Aman Harwara eec7ae1589 fix: use mobx action for setting state 2022-10-18 20:30:39 +05:30
Aman Harwara 361f773f2c fix: editor width on mobile 2022-10-18 20:20:01 +05:30
Aman Harwara 5ffd37d447 fix: context menu opening when swiping up from bottom on iOS 2022-10-18 20:04:36 +05:30
Mo 2b66ff82ee refactor: note editor relationships (#1821) 2022-10-18 08:59:24 -05:00
Mo c83dc48d3f ci: pr linking (skip e2e) 2022-10-18 06:39:33 -05:00
StandardNotes CI 8dc7eaf3a4 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected].8
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
2022-10-18 09:00:14 +00:00
Aman Harwara e40cd157b6 fix: remove switch to classic mx option 2022-10-18 13:54:45 +05:30
Mo 66805fa552 ci: no PRs if depandabot (skip e2e) 2022-10-17 17:00:47 -05:00
203 changed files with 3362 additions and 2457 deletions
+3
View File
@@ -1,4 +1,7 @@
{
"extends": ["./node_modules/@standardnotes/config/src/.eslintrc"],
"rules": {
"max-classes-per-file": ["error", 1]
},
"ignorePatterns": [".eslintrc.js", "*.webpack.*.js", "webpack-defaults.js", "jest.config.js", "__mocks__", "**/**/coverage"]
}
+12
View File
@@ -36,11 +36,23 @@ jobs:
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
id: extract_branch
- name: Find open PR
uses: juliangruber/find-pull-request-action@v1
id: find-pull-request
with:
branch: ${{ steps.extract_branch.outputs.branch }}
- run: echo "Pull Request ${number} (${sha})"
env:
number: ${{ steps.find-pull-request.outputs.number }}
sha: ${{ steps.find-pull-request.outputs.head-sha }}
- uses: peter-evans/create-pull-request@v4
if: startsWith(github.event.head_commit.message, 'chore(deps)') == false && startsWith(github.event.head_commit.message, 'chore(deps-dev)') == false
with:
token: ${{ secrets.CI_PAT_TOKEN }}
branch: ${{ github.ref }}
base: main
title: ${{ steps.extract_branch.outputs.branch }}
body: "Public PR: https://github.com/standardnotes/app/pull/${{ steps.find-pull-request.outputs.number }}"
assignees: ${{ github.actor }}
reviewers: ${{ github.actor }}
@@ -70,6 +70,8 @@ jobs:
packages/mobile/android/app/build/outputs/apk/prod/release/app-prod-release.apk
ios:
env:
ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD: true
defaults:
run:
working-directory: packages/mobile
@@ -49,6 +49,8 @@ jobs:
with:
path: packages/mobile
ios:
env:
ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD: true
defaults:
run:
working-directory: packages/mobile
+1 -1
View File
@@ -66,7 +66,7 @@
"css-loader": "^6.7.1",
"eslint": "^8.17.0",
"eslint-plugin-prettier": "^4.2.1",
"husky": "^8.0.0",
"husky": "^8.0.1",
"lint-staged": "^13.0.1",
"npm-check-updates": "^14.1.1",
"prettier": "^2.6.2",
+24
View File
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.17.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/api
## [1.17.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
### Bug Fixes
* refactor application event observing on web ([9fb85cd](https://github.com/standardnotes/app/commit/9fb85cd77a627364738a9c21706431d2a01e9c44))
# [1.17.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
### Features
* **api:** add accepting invites by the client ([4f0805d](https://github.com/standardnotes/app/commit/4f0805d5b078e5a3524f5d6699b45dfd7e3456f3))
## [1.16.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
**Note:** Version bump only for package @standardnotes/api
## [1.16.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/api
## [1.16.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
**Note:** Version bump only for package @standardnotes/api
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api",
"version": "1.16.3",
"version": "1.17.2",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -2,4 +2,5 @@ export enum SubscriptionApiOperations {
Inviting,
CancelingInvite,
ListingInvites,
AcceptingInvite,
}
@@ -1,5 +1,6 @@
import { Invitation } from '@standardnotes/models'
import { SubscriptionInviteAcceptResponse } from '../../Response/Subscription/SubscriptionInviteAcceptResponse'
import { SubscriptionInviteCancelResponse } from '../../Response/Subscription/SubscriptionInviteCancelResponse'
import { SubscriptionInviteListResponse } from '../../Response/Subscription/SubscriptionInviteListResponse'
import { SubscriptionInviteResponse } from '../../Response/Subscription/SubscriptionInviteResponse'
@@ -24,6 +25,9 @@ describe('SubscriptionApiService', () => {
subscriptionServer.listInvites = jest.fn().mockReturnValue({
data: { invitations: [{} as jest.Mocked<Invitation>] },
} as jest.Mocked<SubscriptionInviteListResponse>)
subscriptionServer.acceptInvite = jest.fn().mockReturnValue({
data: { success: true },
} as jest.Mocked<SubscriptionInviteAcceptResponse>)
})
it('should invite a user', async () => {
@@ -160,4 +164,48 @@ describe('SubscriptionApiService', () => {
expect(error).not.toBeNull()
})
it('should accept an invite', async () => {
const response = await createService().acceptInvite('1-2-3')
expect(response).toEqual({
data: {
success: true,
},
})
expect(subscriptionServer.acceptInvite).toHaveBeenCalledWith({
inviteUuid: '1-2-3',
})
})
it('should not accept an invite if it is already accepting', async () => {
const service = createService()
Object.defineProperty(service, 'operationsInProgress', {
get: () => new Map([[SubscriptionApiOperations.AcceptingInvite, true]]),
})
let error = null
try {
await service.acceptInvite('1-2-3')
} catch (caughtError) {
error = caughtError
}
expect(error).not.toBeNull()
})
it('should not accept an invite if the server fails', async () => {
subscriptionServer.acceptInvite = jest.fn().mockImplementation(() => {
throw new Error('Oops')
})
let error = null
try {
await createService().acceptInvite('1-2-3')
} catch (caughtError) {
error = caughtError
}
expect(error).not.toBeNull()
})
})
@@ -6,9 +6,11 @@ import { SubscriptionServerInterface } from '../../Server/Subscription/Subscript
import { SubscriptionInviteResponse } from '../../Response/Subscription/SubscriptionInviteResponse'
import { SubscriptionInviteListResponse } from '../../Response/Subscription/SubscriptionInviteListResponse'
import { SubscriptionInviteCancelResponse } from '../../Response/Subscription/SubscriptionInviteCancelResponse'
import { SubscriptionInviteAcceptResponse } from '../../Response/Subscription/SubscriptionInviteAcceptResponse'
import { SubscriptionApiServiceInterface } from './SubscriptionApiServiceInterface'
import { SubscriptionApiOperations } from './SubscriptionApiOperations'
import { Uuid } from '@standardnotes/common'
export class SubscriptionApiService implements SubscriptionApiServiceInterface {
private operationsInProgress: Map<SubscriptionApiOperations, boolean>
@@ -78,4 +80,24 @@ export class SubscriptionApiService implements SubscriptionApiServiceInterface {
throw new ApiCallError(ErrorMessage.GenericFail)
}
}
async acceptInvite(inviteUuid: Uuid): Promise<SubscriptionInviteAcceptResponse> {
if (this.operationsInProgress.get(SubscriptionApiOperations.AcceptingInvite)) {
throw new ApiCallError(ErrorMessage.GenericInProgress)
}
this.operationsInProgress.set(SubscriptionApiOperations.AcceptingInvite, true)
try {
const response = await this.subscriptionServer.acceptInvite({
inviteUuid,
})
this.operationsInProgress.set(SubscriptionApiOperations.AcceptingInvite, false)
return response
} catch (error) {
throw new ApiCallError(ErrorMessage.GenericFail)
}
}
}
@@ -1,5 +1,6 @@
import { Uuid } from '@standardnotes/common'
import { SubscriptionInviteAcceptResponse } from '../../Response/Subscription/SubscriptionInviteAcceptResponse'
import { SubscriptionInviteCancelResponse } from '../../Response/Subscription/SubscriptionInviteCancelResponse'
import { SubscriptionInviteListResponse } from '../../Response/Subscription/SubscriptionInviteListResponse'
import { SubscriptionInviteResponse } from '../../Response/Subscription/SubscriptionInviteResponse'
@@ -8,4 +9,5 @@ export interface SubscriptionApiServiceInterface {
invite(inviteeEmail: string): Promise<SubscriptionInviteResponse>
listInvites(): Promise<SubscriptionInviteListResponse>
cancelInvite(inviteUuid: Uuid): Promise<SubscriptionInviteCancelResponse>
acceptInvite(inviteUuid: Uuid): Promise<SubscriptionInviteAcceptResponse>
}
@@ -1,10 +1,6 @@
import { Uuid } from '@standardnotes/common'
import { ApiEndpointParam } from '../ApiEndpointParam'
import { ApiVersion } from '../../Api/ApiVersion'
export type SubscriptionInviteAcceptRequestParams = {
[ApiEndpointParam.ApiVersion]: ApiVersion.v0
inviteUuid: Uuid
[additionalParam: string]: unknown
}
@@ -1,3 +1 @@
export type SubscriptionInviteAcceptResponseBody = {
success: boolean
}
export type SubscriptionInviteAcceptResponseBody = { success: true } | { success: false; message: string }
+7
View File
@@ -3,6 +3,13 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.7.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
### Reverts
* Revert "chore: remove deprecated editors folder" ([fc00b5c](https://github.com/standardnotes/app/commit/fc00b5c4996045750589c3e08c139d5d39bf4140))
* Revert "chore: fix code editor build" ([bb8ac49](https://github.com/standardnotes/app/commit/bb8ac49052136b3f688f19df5c71c2c32a85ed51))
## [2.7.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-13)
**Note:** Version bump only for package @standardnotes/components-meta
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/components-meta",
"version": "2.7.20",
"version": "2.7.21",
"private": true,
"author": "Standard Notes.",
"main": "dist",
+64
View File
@@ -3,6 +3,70 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.23.236](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.235](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.234](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.233](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.232](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.231](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.230](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.229](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.228](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.227](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.226](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.225](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.224](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.223](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.222](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.221](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.220](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
**Note:** Version bump only for package @standardnotes/desktop
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/desktop",
"main": "./app/dist/index.js",
"version": "3.23.220",
"version": "3.23.236",
"license": "AGPL-3.0-or-later",
"author": "Standard Notes.",
"private": true,
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.18.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/encryption
## [1.18.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
**Note:** Version bump only for package @standardnotes/encryption
## [1.18.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/encryption
## [1.18.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
**Note:** Version bump only for package @standardnotes/encryption
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/encryption",
"version": "1.18.2",
"version": "1.18.5",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.53.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/features
## [1.53.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-13)
**Note:** Version bump only for package @standardnotes/features
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/features",
"version": "1.53.1",
"version": "1.53.2",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -5,4 +5,5 @@ export enum NoteType {
RichText = 'rich-text',
Spreadsheet = 'spreadsheet',
Task = 'task',
Plain = 'plain-text',
}
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.24.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.24.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.24.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/filepicker
## [1.24.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
**Note:** Version bump only for package @standardnotes/filepicker
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/filepicker",
"version": "1.24.4",
"version": "1.24.7",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+12
View File
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.11.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/files
## [1.11.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
**Note:** Version bump only for package @standardnotes/files
## [1.11.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/files
## [1.11.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
**Note:** Version bump only for package @standardnotes/files
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files",
"version": "1.11.4",
"version": "1.11.7",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+66
View File
@@ -3,6 +3,72 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.43.23](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.22](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.19](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
### Bug Fixes
* help & feedback links on mobile ([#1849](https://github.com/standardnotes/app/issues/1849)) ([fb72c2f](https://github.com/standardnotes/app/commit/fb72c2fdae277cb4e348ce5ee550f0545f281dcd))
## [3.43.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/mobile
## [3.43.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
**Note:** Version bump only for package @standardnotes/mobile
@@ -49,6 +49,10 @@
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https"/>
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="mailto"/>
</intent>
</queries>
</manifest>
@@ -74,6 +74,7 @@
<array>
<string>http</string>
<string>https</string>
<string>mailto</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
@@ -52,6 +52,7 @@
<array>
<string>http</string>
<string>https</string>
<string>mailto</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/mobile",
"version": "3.43.7",
"version": "3.43.23",
"author": "Standard Notes.",
"private": true,
"license": "AGPL-3.0-or-later",
+18
View File
@@ -3,6 +3,24 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.30.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
### Features
* ability to favorite tags + customize icon ([#1858](https://github.com/standardnotes/app/issues/1858)) ([cbd0063](https://github.com/standardnotes/app/commit/cbd0063926a416c23225242a4a1796712b6b224e))
## [1.29.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
### Bug Fixes
* issue with not being able to unlink a file from a note ([#1836](https://github.com/standardnotes/app/issues/1836)) ([4030953](https://github.com/standardnotes/app/commit/4030953b00ad609dc2b0f5b66cfd971d449f6121))
# [1.29.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
### Features
* authorize notes for listed ([#1823](https://github.com/standardnotes/app/issues/1823)) ([9954bdc](https://github.com/standardnotes/app/commit/9954bdc29f9de2a42c4539d55749991d86a72943))
# [1.28.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
### Features
+2 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/models",
"version": "1.28.0",
"version": "1.30.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -25,6 +25,7 @@
"@types/jest": "^28.1.5",
"@types/lodash": "^4.14.182",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"eslint": "*",
"eslint-plugin-prettier": "*",
"jest": "^28.1.2",
"ts-jest": "^28.0.5",
@@ -8,6 +8,6 @@ export enum AppDataField {
NotAvailableOnMobile = 'notAvailableOnMobile',
MobileActive = 'mobileActive',
LastSize = 'lastSize',
PrefersPlainEditor = 'prefersPlainEditor',
LegacyPrefersPlainEditor = 'prefersPlainEditor',
ComponentInstallError = 'installError',
}
@@ -5,6 +5,7 @@ import { FillItemContent } from '../../Abstract/Content/ItemContent'
import { SNComponent } from './Component'
import { ComponentContent } from './ComponentContent'
import { PayloadTimestampDefaults } from '../../Abstract/Payload'
import { NoteType } from '@standardnotes/features'
describe('component model', () => {
it('valid hosted url should ignore url', () => {
@@ -46,4 +47,42 @@ describe('component model', () => {
expect(component.hasValidHostedUrl()).toBe(true)
expect(component.hosted_url).toBe('http://foo.com')
})
it('should return noteType as specified in package_info', () => {
const component = new SNComponent(
new DecryptedPayload(
{
uuid: String(Math.random()),
content_type: ContentType.Component,
content: FillItemContent({
package_info: {
note_type: NoteType.Authentication,
},
} as ComponentContent),
...PayloadTimestampDefaults(),
},
PayloadSource.Constructor,
),
)
expect(component.noteType).toEqual(NoteType.Authentication)
})
it('should return plain as noteType if no note type defined in package_info', () => {
const component = new SNComponent(
new DecryptedPayload(
{
uuid: String(Math.random()),
content_type: ContentType.Component,
content: FillItemContent({
package_info: {},
} as ComponentContent),
...PayloadTimestampDefaults(),
},
PayloadSource.Constructor,
),
)
expect(component.noteType).toEqual(NoteType.Plain)
})
})
@@ -7,6 +7,7 @@ import {
ComponentFlag,
ComponentPermission,
FindNativeFeature,
NoteType,
} from '@standardnotes/features'
import { AppDataField } from '../../Abstract/Item/Types/AppDataField'
import { ComponentContent, ComponentInterface } from './ComponentContent'
@@ -177,6 +178,10 @@ export class SNComponent extends DecryptedItem<ComponentContent> implements Comp
return this.package_info as ThirdPartyFeatureDescription
}
public get noteType(): NoteType {
return this.package_info.note_type || NoteType.Plain
}
public get isDeprecated(): boolean {
let flags: string[] = this.package_info.flags ?? []
flags = flags.map((flag: string) => flag.toLowerCase())
@@ -4,7 +4,8 @@ import { DecryptedPayloadInterface } from '../../Abstract/Payload/Interfaces/Dec
import { FileMetadata } from './FileMetadata'
import { FileProtocolV1 } from './FileProtocolV1'
import { SortableItem } from '../../Runtime/Collection/CollectionSort'
import { ConflictStrategy } from '../../Abstract/Item'
import { ConflictStrategy, ItemInterface } from '../../Abstract/Item'
import { ContentType } from '@standardnotes/common'
type EncryptedBytesLength = number
type DecryptedBytesLength = number
@@ -31,6 +32,8 @@ export type FileContentSpecialized = FileContentWithoutSize & FileMetadata & Siz
export type FileContent = FileContentSpecialized & ItemContent
export const isFile = (x: ItemInterface): x is FileItem => x.content_type === ContentType.File
export class FileItem
extends DecryptedItem<FileContent>
implements FileContentWithoutSize, Sizes, FileProtocolV1, FileMetadata, SortableItem
@@ -29,14 +29,9 @@ describe('SNNote Tests', () => {
expect(note.preview_html).toBeFalsy()
})
it('should set mobilePrefersPlainEditor when given a valid choice', () => {
const selected = createNote({
mobilePrefersPlainEditor: true,
})
it('should not set default value for note type if none is provided', () => {
const note = createNote({})
const unselected = createNote()
expect(selected.mobilePrefersPlainEditor).toBeTruthy()
expect(unselected.mobilePrefersPlainEditor).toBe(undefined)
expect(note.noteType).toBe(undefined)
})
})
@@ -1,7 +1,8 @@
import { AppDataField } from './../../Abstract/Item/Types/AppDataField'
import { ContentType } from '@standardnotes/common'
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
import { DecryptedItem } from '../../Abstract/Item/Implementations/DecryptedItem'
import { ItemInterface } from '../../Abstract/Item/Interfaces/ItemInterface'
import { AppDataField } from '../../Abstract/Item/Types/AppDataField'
import { DecryptedPayloadInterface } from '../../Abstract/Payload/Interfaces/DecryptedPayload'
import { NoteContent, NoteContentSpecialized } from './NoteContent'
@@ -10,12 +11,15 @@ export const isNote = (x: ItemInterface): x is SNNote => x.content_type === Cont
export class SNNote extends DecryptedItem<NoteContent> implements NoteContentSpecialized {
public readonly title: string
public readonly text: string
public readonly mobilePrefersPlainEditor?: boolean
public readonly hidePreview: boolean = false
public readonly preview_plain: string
public readonly preview_html: string
public readonly prefersPlainEditor: boolean
public readonly spellcheck?: boolean
public readonly noteType?: NoteType
public readonly authorizedForListed: boolean
/** The package_info.identifier of the editor (not its uuid), such as org.standardnotes.advanced-markdown */
public readonly editorIdentifier?: FeatureIdentifier | string
constructor(payload: DecryptedPayloadInterface<NoteContent>) {
super(payload)
@@ -26,9 +30,15 @@ export class SNNote extends DecryptedItem<NoteContent> implements NoteContentSpe
this.preview_html = String(this.payload.content.preview_html || '')
this.hidePreview = Boolean(this.payload.content.hidePreview)
this.spellcheck = this.payload.content.spellcheck
this.noteType = this.payload.content.noteType
this.editorIdentifier = this.payload.content.editorIdentifier
this.authorizedForListed = this.payload.content.authorizedForListed || false
this.prefersPlainEditor = this.getAppDomainValueWithDefault(AppDataField.PrefersPlainEditor, false)
this.mobilePrefersPlainEditor = this.payload.content.mobilePrefersPlainEditor
if (!this.noteType) {
const prefersPlain = this.getAppDomainValueWithDefault(AppDataField.LegacyPrefersPlainEditor, false)
if (prefersPlain) {
this.noteType = NoteType.Plain
}
}
}
}
@@ -1,13 +1,16 @@
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
import { ItemContent } from '../../Abstract/Content/ItemContent'
export interface NoteContentSpecialized {
title: string
text: string
mobilePrefersPlainEditor?: boolean
hidePreview?: boolean
preview_plain?: string
preview_html?: string
spellcheck?: boolean
noteType?: NoteType
editorIdentifier?: FeatureIdentifier | string
authorizedForListed?: boolean
}
export type NoteContent = NoteContentSpecialized & ItemContent
@@ -0,0 +1,24 @@
import { NoteMutator } from './NoteMutator'
import { createNote } from './../../Utilities/Test/SpecUtils'
import { MutationType } from '../../Abstract/Item'
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
describe('note mutator', () => {
it('sets noteType', () => {
const note = createNote({})
const mutator = new NoteMutator(note, MutationType.NoUpdateUserTimestamps)
mutator.noteType = NoteType.Authentication
const result = mutator.getResult()
expect(result.content.noteType).toEqual(NoteType.Authentication)
})
it('sets editorIdentifier', () => {
const note = createNote({})
const mutator = new NoteMutator(note, MutationType.NoUpdateUserTimestamps)
mutator.editorIdentifier = FeatureIdentifier.MarkdownProEditor
const result = mutator.getResult()
expect(result.content.editorIdentifier).toEqual(FeatureIdentifier.MarkdownProEditor)
})
})
@@ -1,10 +1,10 @@
import { AppDataField } from '../../Abstract/Item/Types/AppDataField'
import { NoteContent } from './NoteContent'
import { DecryptedItemMutator } from '../../Abstract/Item/Mutator/DecryptedItemMutator'
import { SNNote } from './Note'
import { NoteToNoteReference } from '../../Abstract/Reference/NoteToNoteReference'
import { ContentType } from '@standardnotes/common'
import { ContentReferenceType } from '../../Abstract/Item'
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
export class NoteMutator extends DecryptedItemMutator<NoteContent> {
set title(title: string) {
@@ -27,14 +27,22 @@ export class NoteMutator extends DecryptedItemMutator<NoteContent> {
this.mutableContent.preview_html = preview_html
}
set prefersPlainEditor(prefersPlainEditor: boolean) {
this.setAppDataItem(AppDataField.PrefersPlainEditor, prefersPlainEditor)
}
set spellcheck(spellcheck: boolean) {
this.mutableContent.spellcheck = spellcheck
}
set noteType(noteType: NoteType) {
this.mutableContent.noteType = noteType
}
set editorIdentifier(identifier: FeatureIdentifier | string | undefined) {
this.mutableContent.editorIdentifier = identifier
}
set authorizedForListed(authorizedForListed: boolean) {
this.mutableContent.authorizedForListed = authorizedForListed
}
toggleSpellcheck(): void {
if (this.mutableContent.spellcheck == undefined) {
this.mutableContent.spellcheck = false
@@ -1,41 +1,33 @@
import { DecryptedItem } from '../../Abstract/Item/Implementations/DecryptedItem'
import { PredicateInterface, PredicateJsonForm } from '../../Runtime/Predicate/Interface'
import { PredicateInterface } from '../../Runtime/Predicate/Interface'
import { predicateFromJson } from '../../Runtime/Predicate/Generators'
import { ItemContent } from '../../Abstract/Content/ItemContent'
import { DecryptedPayloadInterface } from '../../Abstract/Payload/Interfaces/DecryptedPayload'
import { SystemViewId } from './SystemViewId'
import { EmojiString, IconType } from '../../Utilities/Icon/IconType'
import { SmartViewDefaultIconName, systemViewIcon } from './SmartViewIcons'
import { SmartViewContent } from './SmartViewContent'
export const SMART_TAG_DSL_PREFIX = '!['
export enum SystemViewId {
AllNotes = 'all-notes',
Files = 'files',
ArchivedNotes = 'archived-notes',
TrashedNotes = 'trashed-notes',
UntaggedNotes = 'untagged-notes',
StarredNotes = 'starred-notes',
}
export interface SmartViewContent extends ItemContent {
title: string
predicate: PredicateJsonForm
}
export function isSystemView(view: SmartView): boolean {
return Object.values(SystemViewId).includes(view.uuid as SystemViewId)
}
/**
* A tag that defines a predicate that consumers can use
* to retrieve a dynamic list of items.
*/
export class SmartView extends DecryptedItem<SmartViewContent> {
public readonly predicate!: PredicateInterface<DecryptedItem>
public readonly title: string
public readonly iconString: IconType | EmojiString
constructor(payload: DecryptedPayloadInterface<SmartViewContent>) {
super(payload)
this.title = String(this.content.title || '')
if (isSystemView(this)) {
this.iconString = systemViewIcon(this.uuid as SystemViewId)
} else {
this.iconString = this.payload.content.iconString || SmartViewDefaultIconName
}
try {
this.predicate = this.content.predicate && predicateFromJson(this.content.predicate)
} catch (error) {
@@ -1,6 +1,8 @@
import { DecryptedPayload } from './../../Abstract/Payload/Implementations/DecryptedPayload'
import { SNNote } from '../Note/Note'
import { SmartViewContent, SmartView, SystemViewId } from './SmartView'
import { SmartView } from './SmartView'
import { SmartViewContent } from './SmartViewContent'
import { SystemViewId } from './SystemViewId'
import { ItemWithTags } from '../../Runtime/Display/Search/ItemWithTags'
import { ContentType } from '@standardnotes/common'
import { FillItemContent } from '../../Abstract/Content/ItemContent'
@@ -0,0 +1,6 @@
import { TagContent } from './../Tag/TagContent'
import { PredicateJsonForm } from '../../Runtime/Predicate/Interface'
export interface SmartViewContent extends TagContent {
predicate: PredicateJsonForm
}
@@ -0,0 +1,17 @@
import { SystemViewId } from './SystemViewId'
import { IconType } from '../../Utilities/Icon/IconType'
export const SmartViewIcons: Record<SystemViewId, IconType> = {
[SystemViewId.AllNotes]: 'notes',
[SystemViewId.Files]: 'folder',
[SystemViewId.ArchivedNotes]: 'archive',
[SystemViewId.TrashedNotes]: 'trash',
[SystemViewId.UntaggedNotes]: 'hashtag-off',
[SystemViewId.StarredNotes]: 'star-filled',
}
export function systemViewIcon(id: SystemViewId): IconType {
return SmartViewIcons[id]
}
export const SmartViewDefaultIconName: IconType = 'restore'
@@ -0,0 +1,8 @@
export enum SystemViewId {
AllNotes = 'all-notes',
Files = 'files',
ArchivedNotes = 'archived-notes',
TrashedNotes = 'trashed-notes',
UntaggedNotes = 'untagged-notes',
StarredNotes = 'starred-notes',
}
@@ -1,2 +1,4 @@
export * from './SmartView'
export * from './SmartViewBuilder'
export * from './SystemViewId'
export * from './SmartViewContent'
@@ -1,10 +1,11 @@
import { PayloadSource } from './../../Abstract/Payload/Types/PayloadSource'
import { DecryptedPayload } from './../../Abstract/Payload/Implementations/DecryptedPayload'
import { SNTag, TagContent } from './Tag'
import { SNTag } from './Tag'
import { ContentType } from '@standardnotes/common'
import { FillItemContent } from '../../Abstract/Content/ItemContent'
import { ContentReference } from '../../Abstract/Reference/ContentReference'
import { PayloadTimestampDefaults } from '../../Abstract/Payload'
import { TagContent } from './TagContent'
const randUuid = () => String(Math.random())
+6 -10
View File
@@ -1,32 +1,28 @@
import { VectorIconNameOrEmoji, IconType } from './../../Utilities/Icon/IconType'
import { ContentType, Uuid } from '@standardnotes/common'
import { DecryptedItem } from '../../Abstract/Item/Implementations/DecryptedItem'
import { ItemInterface } from '../../Abstract/Item/Interfaces/ItemInterface'
import { ItemContent } from '../../Abstract/Content/ItemContent'
import { ContentReference } from '../../Abstract/Reference/ContentReference'
import { isTagToParentTagReference } from '../../Abstract/Reference/Functions'
import { DecryptedPayloadInterface } from '../../Abstract/Payload/Interfaces/DecryptedPayload'
import { TagContent, TagContentSpecialized } from './TagContent'
export const TagFolderDelimitter = '.'
interface TagInterface {
title: string
expanded: boolean
}
export type TagContent = TagInterface & ItemContent
export const DefaultTagIconName: IconType = 'hashtag'
export const isTag = (x: ItemInterface): x is SNTag => x.content_type === ContentType.Tag
export class SNTag extends DecryptedItem<TagContent> implements TagInterface {
export class SNTag extends DecryptedItem<TagContent> implements TagContentSpecialized {
public readonly title: string
/** Whether to render child tags in view hierarchy. Opposite of collapsed. */
public readonly iconString: VectorIconNameOrEmoji
public readonly expanded: boolean
constructor(payload: DecryptedPayloadInterface<TagContent>) {
super(payload)
this.title = this.payload.content.title || ''
this.expanded = this.payload.content.expanded != undefined ? this.payload.content.expanded : true
this.iconString = this.payload.content.iconString || DefaultTagIconName
}
get noteReferences(): ContentReference[] {
@@ -0,0 +1,11 @@
import { IconType } from './../../Utilities/Icon/IconType'
import { ItemContent } from '../../Abstract/Content/ItemContent'
import { EmojiString } from '../../Utilities/Icon/IconType'
export interface TagContentSpecialized {
title: string
expanded: boolean
iconString: IconType | EmojiString
}
export type TagContent = TagContentSpecialized & ItemContent
@@ -1,5 +1,6 @@
import { ContentType } from '@standardnotes/common'
import { TagContent, SNTag } from './Tag'
import { SNTag } from './Tag'
import { TagContent } from './TagContent'
import { FileItem } from '../File'
import { SNNote } from '../Note'
import { isTagToParentTagReference } from '../../Abstract/Reference/Functions'
@@ -17,6 +18,10 @@ export class TagMutator extends DecryptedItemMutator<TagContent> {
this.mutableContent.expanded = expanded
}
set iconString(iconString: string) {
this.mutableContent.iconString = iconString
}
public makeChildOf(tag: SNTag): void {
const references = this.immutableItem.references.filter((ref) => !isTagToParentTagReference(ref))
@@ -1,2 +1,3 @@
export * from './Tag'
export * from './TagMutator'
export * from './TagContent'
@@ -1,3 +1,7 @@
export type VectorIconNameOrEmoji = EmojiString | IconType
export type EmojiString = string
export type IconType =
| 'accessibility'
| 'account-card-details-outline'
@@ -1,55 +0,0 @@
import { DecryptedPayloadInterface } from './../../Abstract/Payload/Interfaces/DecryptedPayload'
import { ComponentContent } from '../../Syncable/Component/ComponentContent'
import { ComponentArea } from '@standardnotes/features'
import { ContentType } from '@standardnotes/common'
import { ComponentMutator, SNComponent } from '../../Syncable/Component'
import { CreateDecryptedItemFromPayload } from '../Item/ItemGenerator'
import { ImmutablePayloadCollection } from '../../Runtime/Collection/Payload/ImmutablePayloadCollection'
import { MutationType } from '../../Abstract/Item/Types/MutationType'
import { FullyFormedPayloadInterface } from '../../Abstract/Payload/Interfaces/UnionTypes'
import { isDecryptedPayload } from '../../Abstract/Payload'
import { SyncResolvedPayload } from '../../Runtime/Deltas/Utilities/SyncResolvedPayload'
export type AffectorFunction = (
basePayload: FullyFormedPayloadInterface,
duplicatePayload: FullyFormedPayloadInterface,
baseCollection: ImmutablePayloadCollection<FullyFormedPayloadInterface>,
) => SyncResolvedPayload[]
const NoteDuplicationAffectedPayloads: AffectorFunction = (
basePayload: FullyFormedPayloadInterface,
duplicatePayload: FullyFormedPayloadInterface,
baseCollection: ImmutablePayloadCollection<FullyFormedPayloadInterface>,
) => {
/** If note has editor, maintain editor relationship in duplicate note */
const components = baseCollection
.all(ContentType.Component)
.filter(isDecryptedPayload)
.map((payload) => {
return CreateDecryptedItemFromPayload<ComponentContent, SNComponent>(
payload as DecryptedPayloadInterface<ComponentContent>,
)
})
const editor = components
.filter((c) => c.area === ComponentArea.Editor)
.find((e) => {
return e.isExplicitlyEnabledForItem(basePayload.uuid)
})
if (!editor) {
return []
}
/** Modify the editor to include new note */
const mutator = new ComponentMutator(editor, MutationType.NoUpdateUserTimestamps)
mutator.associateWithItem(duplicatePayload.uuid)
const result = mutator.getResult() as SyncResolvedPayload
return [result]
}
export const AffectorMapping = {
[ContentType.Note]: NoteDuplicationAffectedPayloads,
} as Partial<Record<ContentType, AffectorFunction>>
@@ -2,7 +2,6 @@ import { PayloadSource } from './../../Abstract/Payload/Types/PayloadSource'
import { extendArray, UuidGenerator } from '@standardnotes/utils'
import { ImmutablePayloadCollection } from '../../Runtime/Collection/Payload/ImmutablePayloadCollection'
import { ItemContent } from '../../Abstract/Content/ItemContent'
import { AffectorMapping } from './AffectorFunction'
import { PayloadsByUpdatingReferencingPayloadReferences } from './PayloadsByUpdatingReferencingPayloadReferences'
import { isDecryptedPayload } from '../../Abstract/Payload/Interfaces/TypeCheck'
import { FullyFormedPayloadInterface } from '../../Abstract/Payload/Interfaces/UnionTypes'
@@ -69,13 +68,5 @@ export function PayloadsByDuplicating<C extends ItemContent = ItemContent>(dto:
extendArray(results, updatedReferencing)
}
const affector = AffectorMapping[payload.content_type]
if (affector) {
const affected = affector(payload, copy, baseCollection)
if (affected) {
extendArray(results, affected)
}
}
return results
}
@@ -1,4 +1,4 @@
import { TagContent } from './../../Syncable/Tag/Tag'
import { TagContent } from './../../Syncable/Tag/TagContent'
import { ContentType } from '@standardnotes/common'
import { FillItemContent, ItemContent } from '../../Abstract/Content/ItemContent'
import { DecryptedPayload, PayloadSource, PayloadTimestampDefaults } from '../../Abstract/Payload'
+4 -4
View File
@@ -1,7 +1,7 @@
export * from './Abstract/Component/ActionObserver'
export * from './Abstract/Component/ComponentViewerEvent'
export * from './Abstract/Component/ComponentMessage'
export * from './Abstract/Component/ComponentEventObserver'
export * from './Abstract/Component/ComponentMessage'
export * from './Abstract/Component/ComponentViewerEvent'
export * from './Abstract/Component/IncomingComponentItemPayload'
export * from './Abstract/Component/KeyboardModifier'
export * from './Abstract/Component/MessageData'
@@ -43,9 +43,9 @@ export * from './Runtime/Collection/Payload/ImmutablePayloadCollection'
export * from './Runtime/Collection/Payload/PayloadCollection'
export * from './Runtime/Deltas'
export * from './Runtime/DirtyCounter/DirtyCounter'
export * from './Runtime/Display'
export * from './Runtime/Display/ItemDisplayController'
export * from './Runtime/Display/Types'
export * from './Runtime/Display'
export * from './Runtime/History'
export * from './Runtime/Index/ItemDelta'
export * from './Runtime/Index/SNIndex'
@@ -70,11 +70,11 @@ export * from './Syncable/SmartView'
export * from './Syncable/Tag'
export * from './Syncable/Theme'
export * from './Syncable/UserPrefs'
export * from './Utilities/Icon/IconType'
export * from './Utilities/Item/FindItem'
export * from './Utilities/Item/ItemContentsDiffer'
export * from './Utilities/Item/ItemContentsEqual'
export * from './Utilities/Item/ItemGenerator'
export * from './Utilities/Payload/AffectorFunction'
export * from './Utilities/Payload/CopyPayloadWithContentOverride'
export * from './Utilities/Payload/CreatePayload'
export * from './Utilities/Payload/FindPayload'
+64
View File
@@ -3,6 +3,70 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.165](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.164](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.163](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.162](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.161](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.160](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.159](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.158](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.157](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.156](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.155](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.154](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.153](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.152](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.151](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.150](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.149](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
**Note:** Version bump only for package @standardnotes/releases
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/releases",
"version": "1.3.149",
"version": "1.3.165",
"license": "AGPL-3.0-or-later",
"main": "dist/releases.json",
"types": "dist/index.d.ts",
+4
View File
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.11.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/responses
## [1.11.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-13)
**Note:** Version bump only for package @standardnotes/responses
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/responses",
"version": "1.11.1",
"version": "1.11.2",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+24
View File
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.34.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/services
## [1.34.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/services
## [1.34.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/services
## [1.34.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
### Bug Fixes
* issue with not being able to unlink a file from a note ([#1836](https://github.com/standardnotes/app/issues/1836)) ([4030953](https://github.com/standardnotes/app/commit/4030953b00ad609dc2b0f5b66cfd971d449f6121))
# [1.34.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
### Features
* authorize notes for listed ([#1823](https://github.com/standardnotes/app/issues/1823)) ([9954bdc](https://github.com/standardnotes/app/commit/9954bdc29f9de2a42c4539d55749991d86a72943))
## [1.33.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
**Note:** Version bump only for package @standardnotes/services
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/services",
"version": "1.33.1",
"version": "1.34.4",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -24,4 +24,5 @@ export enum ChallengeReason {
UnprotectFile,
UnprotectNote,
DeleteAccount,
AuthorizeNoteForListed,
}
@@ -20,5 +20,5 @@ export interface ComponentManagerInterface {
urlOverride?: string,
): ComponentViewerInterface
presentPermissionsDialog(_dialog: PermissionDialog): void
getDefaultEditor(): SNComponent
getDefaultEditor(): SNComponent | undefined
}
@@ -0,0 +1,7 @@
/* istanbul ignore file */
export enum ItemRelationshipDirection {
AReferencesB,
BReferencesA,
NoRelationship,
}
@@ -1,3 +1,5 @@
/* istanbul ignore file */
import { ContentType, Uuid } from '@standardnotes/common'
import {
SNNote,
@@ -76,9 +78,9 @@ export interface ItemsClientInterface {
linkNoteToNote(note: SNNote, otherNote: SNNote): Promise<SNNote>
linkFileToFile(file: FileItem, otherFile: FileItem): Promise<FileItem>
unlinkItem(
item: DecryptedItemInterface<ItemContent>,
itemToUnlink: DecryptedItemInterface<ItemContent>,
unlinkItems(
itemOne: DecryptedItemInterface<ItemContent>,
itemTwo: DecryptedItemInterface<ItemContent>,
): Promise<DecryptedItemInterface<ItemContent>>
/**
@@ -115,12 +117,6 @@ export interface ItemsClientInterface {
*/
getSortedTagsForItem(item: DecryptedItemInterface<ItemContent>): SNTag[]
getSortedLinkedFilesForItem(item: DecryptedItemInterface<ItemContent>): FileItem[]
getSortedFilesLinkingToItem(item: DecryptedItemInterface<ItemContent>): FileItem[]
getSortedLinkedNotesForItem(item: DecryptedItemInterface<ItemContent>): SNNote[]
getSortedNotesLinkingToItem(item: DecryptedItemInterface<ItemContent>): SNNote[]
isSmartViewTitle(title: string): boolean
getSmartViews(): SmartView[]
@@ -152,12 +148,4 @@ export interface ItemsClientInterface {
* @returns Whether the item is a template (unmanaged)
*/
isTemplateItem(item: DecryptedItemInterface): boolean
/**
* @returns `'direct'` if `itemOne` has the reference to `itemTwo`, `'indirect'` if `itemTwo` has the reference to `itemOne`, `'unlinked'` if neither reference each other
*/
relationshipTypeForItems(
itemOne: DecryptedItemInterface,
itemTwo: DecryptedItemInterface,
): 'direct' | 'indirect' | 'unlinked'
}
+1
View File
@@ -54,6 +54,7 @@ export * from './Item/ItemCounterInterface'
export * from './Item/ItemManagerInterface'
export * from './Item/ItemsClientInterface'
export * from './Item/ItemsServerInterface'
export * from './Item/ItemRelationshipDirection'
export * from './Mutator/MutatorClientInterface'
export * from './Payloads/PayloadManagerInterface'
export * from './Preferences/PreferenceServiceInterface'
+28
View File
@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [2.143.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
### Features
* ability to favorite tags + customize icon ([#1858](https://github.com/standardnotes/app/issues/1858)) ([cbd0063](https://github.com/standardnotes/app/commit/cbd0063926a416c23225242a4a1796712b6b224e))
## [2.142.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
### Bug Fixes
* refactor application event observing on web ([9fb85cd](https://github.com/standardnotes/app/commit/9fb85cd77a627364738a9c21706431d2a01e9c44))
## [2.142.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/snjs
## [2.142.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
### Bug Fixes
* issue with not being able to unlink a file from a note ([#1836](https://github.com/standardnotes/app/issues/1836)) ([4030953](https://github.com/standardnotes/app/commit/4030953b00ad609dc2b0f5b66cfd971d449f6121))
# [2.142.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
### Features
* authorize notes for listed ([#1823](https://github.com/standardnotes/app/issues/1823)) ([9954bdc](https://github.com/standardnotes/app/commit/9954bdc29f9de2a42c4539d55749991d86a72943))
## [2.141.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
**Note:** Version bump only for package @standardnotes/snjs
+10 -25
View File
@@ -68,7 +68,7 @@ import { ClientDisplayableError } from '@standardnotes/responses'
import { SnjsVersion } from './../Version'
import { SNLog } from '../Log'
import { Challenge, ChallengeResponse } from '../Services'
import { Challenge, ChallengeResponse, ListedClientInterface } from '../Services'
import { ApplicationConstructorOptions, FullyResolvedApplicationOptions } from './Options/ApplicationOptions'
import { ApplicationOptionsDefaults } from './Options/Defaults'
@@ -86,9 +86,7 @@ type ApplicationObserver = {
type ObserverRemover = () => void
export class SNApplication
implements ApplicationInterface, AppGroupManagedApplication, InternalServices.ListedClientInterface
{
export class SNApplication implements ApplicationInterface, AppGroupManagedApplication {
onDeinit!: ExternalServices.DeinitCallback
/**
@@ -273,6 +271,10 @@ export class SNApplication
return this.componentManagerService
}
public get listed(): ListedClientInterface {
return this.listedService
}
public computePrivateUsername(username: string): Promise<string | undefined> {
return ComputePrivateUsername(this.options.crypto, username)
}
@@ -682,25 +684,6 @@ export class SNApplication
return this.protectionService.authorizeSearchingProtectedNotesText()
}
public canRegisterNewListedAccount(): boolean {
return this.listedService.canRegisterNewListedAccount()
}
public async requestNewListedAccount(): Promise<Responses.ListedAccount | undefined> {
return this.listedService.requestNewListedAccount()
}
public async getListedAccounts(): Promise<Responses.ListedAccount[]> {
return this.listedService.getListedAccounts()
}
public getListedAccountInfo(
account: Responses.ListedAccount,
inContextOfItem?: UuidString,
): Promise<Responses.ListedAccountInfo | undefined> {
return this.listedService.getListedAccountInfo(account, inContextOfItem)
}
public async createEncryptedBackupFileForAutomatedDesktopBackups(): Promise<BackupFile | undefined> {
return this.protocolService.createEncryptedBackupFile()
}
@@ -1096,11 +1079,11 @@ export class SNApplication
this.createComponentManager()
this.createMigrationService()
this.createMfaService()
this.createListedService()
this.createActionsManager()
this.createFileService()
this.createIntegrityService()
this.createMutatorService()
this.createListedService()
this.createActionsManager()
this.createStatusService()
if (isDesktopDevice(this.deviceInterface)) {
@@ -1175,6 +1158,8 @@ export class SNApplication
this.itemManager,
this.settingsService,
this.deprecatedHttpService,
this.protectionService,
this.mutator,
this.internalEventBus,
)
this.services.push(this.listedService)
+1 -1
View File
@@ -1,5 +1,5 @@
import { NoteType } from '@standardnotes/features'
import { IconType } from '@Lib/Types/IconType'
import { IconType } from '@standardnotes/models'
export class IconsController {
getIconForFileType(type: string): IconType {
@@ -0,0 +1,33 @@
import { SNApplication } from './../Application/Application'
import { ContentType } from '@standardnotes/common'
import { MutatorService } from './../Services/Mutator/MutatorService'
import { SNComponentManager } from './../Services/ComponentManager/ComponentManager'
import { NoteType } from '@standardnotes/features'
import { NoteViewController } from './NoteViewController'
describe('note view controller', () => {
let application: SNApplication
beforeEach(() => {
application = {} as jest.Mocked<SNApplication>
application.streamItems = jest.fn()
const componentManager = {} as jest.Mocked<SNComponentManager>
componentManager.getDefaultEditor = jest.fn()
Object.defineProperty(application, 'componentManager', { value: componentManager })
const mutator = {} as jest.Mocked<MutatorService>
mutator.createTemplateItem = jest.fn()
Object.defineProperty(application, 'mutator', { value: mutator })
})
it('should create notes with plaintext note type', async () => {
const controller = new NoteViewController(application)
await controller.initialize(false)
expect(application.mutator.createTemplateItem).toHaveBeenCalledWith(
ContentType.Note,
expect.objectContaining({ noteType: NoteType.Plain }),
)
})
})
@@ -1,3 +1,4 @@
import { NoteType } from '@standardnotes/features'
import {
NoteMutator,
SNNote,
@@ -66,9 +67,12 @@ export class NoteViewController implements ItemViewControllerInterface {
async initialize(addTagHierarchy: boolean): Promise<void> {
if (!this.item) {
const editor = this.application.componentManager.getDefaultEditor()
const note = this.application.mutator.createTemplateItem<NoteContent, SNNote>(ContentType.Note, {
text: '',
title: this.defaultTitle || '',
noteType: editor?.noteType || NoteType.Plain,
editorIdentifier: editor?.identifier,
references: [],
})
@@ -167,6 +167,7 @@ export const ChallengeStrings = {
SelectProtectedNote: 'Authentication is required to select a protected note',
DisableMfa: 'Authentication is required to disable two-factor authentication',
DeleteAccount: 'Authentication is required to delete your account',
ListedAuthorization: 'Authentication is required to approve this note for Listed',
}
export const ErrorAlertStrings = {
@@ -79,6 +79,8 @@ export class Challenge implements ChallengeInterface {
return ChallengeStrings.DisableMfa
case ChallengeReason.DeleteAccount:
return ChallengeStrings.DeleteAccount
case ChallengeReason.AuthorizeNoteForListed:
return ChallengeStrings.ListedAuthorization
case ChallengeReason.Custom:
return ''
default:
@@ -3,12 +3,14 @@
*/
import { SNPreferencesService } from '../Preferences/PreferencesService'
import { createNote } from './../../Spec/SpecUtils'
import {
ComponentAction,
ComponentPermission,
FeatureDescription,
FindNativeFeature,
FeatureIdentifier,
NoteType,
} from '@standardnotes/features'
import { ContentType } from '@standardnotes/common'
import { GenericItem, SNComponent, Environment, Platform } from '@standardnotes/models'
@@ -306,6 +308,26 @@ describe('featuresService', () => {
})
})
describe('editors', () => {
it('getEditorForNote should return undefined is note type is plain', () => {
const note = createNote({
noteType: NoteType.Plain,
})
const manager = createManager(Environment.Web, Platform.MacWeb)
expect(manager.editorForNote(note)).toBe(undefined)
})
it('getEditorForNote should call legacy function if no note editorIdentifier or noteType', () => {
const note = createNote({})
const manager = createManager(Environment.Web, Platform.MacWeb)
manager['legacyGetEditorForNote'] = jest.fn()
manager.editorForNote(note)
expect(manager['legacyGetEditorForNote']).toHaveBeenCalled()
})
})
describe('editor change alert', () => {
it('should not require alert switching from plain editor', () => {
const manager = createManager(Environment.Web, Platform.MacWeb)
@@ -17,7 +17,14 @@ import {
import { SNSyncService } from '@Lib/Services/Sync/SyncService'
import find from 'lodash/find'
import uniq from 'lodash/uniq'
import { ComponentArea, ComponentAction, ComponentPermission, FindNativeFeature } from '@standardnotes/features'
import {
ComponentArea,
ComponentAction,
ComponentPermission,
FindNativeFeature,
NoteType,
FeatureIdentifier,
} from '@standardnotes/features'
import { Copy, filterFromArray, removeFromArray, sleep, assert } from '@standardnotes/utils'
import { UuidString } from '@Lib/Types/UuidString'
import { AllowedBatchContentTypes } from '@Lib/Services/ComponentManager/Types'
@@ -112,6 +119,10 @@ export class SNComponentManager
})
}
componentWithIdentifier(identifier: FeatureIdentifier | string): SNComponent | undefined {
return this.components.find((component) => component.identifier === identifier)
}
override deinit(): void {
super.deinit()
@@ -569,13 +580,6 @@ export class SNComponentManager
}
allComponentIframes(): HTMLIFrameElement[] {
if (this.isMobile) {
/**
* Retrieving all iframes is typically related to lifecycle management of
* non-editor components. So this function is not useful to mobile.
*/
return []
}
return Array.from(document.getElementsByTagName('iframe'))
}
@@ -584,23 +588,29 @@ export class SNComponentManager
}
editorForNote(note: SNNote): SNComponent | undefined {
if (note.editorIdentifier) {
return this.componentWithIdentifier(note.editorIdentifier)
}
if (note.noteType === NoteType.Plain) {
return undefined
}
return this.legacyGetEditorForNote(note)
}
/**
* Uses legacy approach of note/editor association. New method uses note.editorIdentifier and note.noteType directly.
*/
private legacyGetEditorForNote(note: SNNote): SNComponent | undefined {
const editors = this.componentsForArea(ComponentArea.Editor)
for (const editor of editors) {
if (editor.isExplicitlyEnabledForItem(note.uuid)) {
return editor
}
}
let defaultEditor
/* No editor found for note. Use default editor, if note does not prefer system editor */
if (this.isMobile) {
if (!note.mobilePrefersPlainEditor) {
defaultEditor = this.getDefaultEditor()
}
} else {
if (!note.prefersPlainEditor) {
defaultEditor = this.getDefaultEditor()
}
}
const defaultEditor = this.getDefaultEditor()
if (defaultEditor && !defaultEditor.isExplicitlyDisabledForItem(note.uuid)) {
return defaultEditor
} else {
@@ -608,15 +618,9 @@ export class SNComponentManager
}
}
getDefaultEditor(): SNComponent {
getDefaultEditor(): SNComponent | undefined {
const editors = this.componentsForArea(ComponentArea.Editor)
if (this.isMobile) {
return editors.filter((e) => {
return e.isMobileDefault
})[0]
} else {
return editors.filter((e) => e.isDefaultEditor())[0]
}
return editors.filter((e) => e.isDefaultEditor())[0]
}
permissionsStringForPermissions(permissions: ComponentPermission[], component: SNComponent): string {
@@ -1,5 +1,5 @@
import { ContentType } from '@standardnotes/common'
import { InternalEventBusInterface } from '@standardnotes/services'
import { InternalEventBusInterface, ItemRelationshipDirection } from '@standardnotes/services'
import { ItemManager } from './ItemManager'
import { PayloadManager } from '../Payloads/PayloadManager'
import { UuidGenerator } from '@standardnotes/utils'
@@ -14,6 +14,7 @@ import {
SmartView,
SystemViewId,
} from '@standardnotes/models'
import { createNoteWithTitle } from '../../Spec/SpecUtils'
const setupRandomUuid = () => {
UuidGenerator.SetGenerator(() => String(Math.random()))
@@ -83,19 +84,6 @@ describe('itemManager', () => {
)
}
const createNote = (title: string) => {
return new Models.SNNote(
new Models.DecryptedPayload({
uuid: String(Math.random()),
content_type: ContentType.Note,
content: Models.FillItemContent<Models.NoteContent>({
title: title,
}),
...PayloadTimestampDefaults(),
}),
)
}
const createFile = (name: string) => {
return new Models.FileItem(
new Models.DecryptedPayload({
@@ -168,7 +156,7 @@ describe('itemManager', () => {
it('viewing notes with tag', async () => {
itemManager = createService()
const tag = createTag('parent')
const note = createNote('note')
const note = createNoteWithTitle('note')
await itemManager.insertItems([tag, note])
await itemManager.addTagToNote(note, tag, false)
@@ -185,9 +173,9 @@ describe('itemManager', () => {
it('viewing trashed notes smart view should include archived notes', async () => {
itemManager = createService()
const archivedNote = createNote('archived')
const trashedNote = createNote('trashed')
const archivedAndTrashedNote = createNote('archived&trashed')
const archivedNote = createNoteWithTitle('archived')
const trashedNote = createNoteWithTitle('trashed')
const archivedAndTrashedNote = createNoteWithTitle('archived&trashed')
await itemManager.insertItems([archivedNote, trashedNote, archivedAndTrashedNote])
@@ -389,8 +377,8 @@ describe('itemManager', () => {
await itemManager.insertItems([parentTag, childTag])
await itemManager.setTagParent(parentTag, childTag)
const parentNote = createNote('parentNote')
const childNote = createNote('childNote')
const parentNote = createNoteWithTitle('parentNote')
const childNote = createNoteWithTitle('childNote')
await itemManager.insertItems([parentNote, childNote])
await itemManager.addTagToNote(parentNote, parentTag, false)
@@ -477,7 +465,7 @@ describe('itemManager', () => {
const fooDelimiter = await itemManager.createTag('bar.foo')
const barFooDelimiter = await itemManager.createTag('baz.bar.foo')
const fooAttached = await itemManager.createTag('Foo')
const note = createNote('note')
const note = createNoteWithTitle('note')
await itemManager.insertItems([foo, foobar, bar, barfoo, fooDelimiter, barFooDelimiter, fooAttached, note])
await itemManager.addTagToNote(note, fooAttached, false)
@@ -501,8 +489,8 @@ describe('itemManager', () => {
await itemManager.insertItems([parentTag, childTag])
await itemManager.setTagParent(parentTag, childTag)
const parentNote = createNote('parentNote')
const childNote = createNote('childNote')
const parentNote = createNoteWithTitle('parentNote')
const childNote = createNoteWithTitle('childNote')
await itemManager.insertItems([parentNote, childNote])
await itemManager.addTagToNote(parentNote, parentTag, false)
@@ -519,8 +507,8 @@ describe('itemManager', () => {
const tag1 = createTag('tag 1')
await itemManager.insertItems([tag1])
const note1 = createNote('note 1')
const note2 = createNote('note 2')
const note1 = createNoteWithTitle('note 1')
const note2 = createNoteWithTitle('note 2')
await itemManager.insertItems([note1, note2])
await itemManager.addTagToNote(note1, tag1, false)
@@ -654,8 +642,8 @@ describe('itemManager', () => {
const view = itemManager.untaggedNotesSmartView
const tag = createTag('tag')
const untaggedNote = createNote('note')
const taggedNote = createNote('taggedNote')
const untaggedNote = createNoteWithTitle('note')
const taggedNote = createNoteWithTitle('taggedNote')
await itemManager.insertItems([tag, untaggedNote, taggedNote])
expect(itemManager.notesMatchingSmartView(view)).toHaveLength(2)
@@ -704,7 +692,7 @@ describe('itemManager', () => {
itemManager = createService()
const parentTag = createTag('parent')
const childTag = createTag('child')
const note = createNote('note')
const note = createNoteWithTitle('note')
await itemManager.insertItems([parentTag, childTag, note])
await itemManager.setTagParent(parentTag, childTag)
@@ -722,7 +710,7 @@ describe('itemManager', () => {
itemManager = createService()
const parentTag = createTag('parent')
const childTag = createTag('child')
const note = createNote('note')
const note = createNoteWithTitle('note')
await itemManager.insertItems([parentTag, childTag, note])
await itemManager.setTagParent(parentTag, childTag)
@@ -772,7 +760,7 @@ describe('itemManager', () => {
it('should link file with note', async () => {
itemManager = createService()
const note = createNote('invoices')
const note = createNoteWithTitle('invoices')
const file = createFile('invoice_1.pdf')
await itemManager.insertItems([note, file])
@@ -785,7 +773,7 @@ describe('itemManager', () => {
it('should unlink file from note', async () => {
itemManager = createService()
const note = createNote('invoices')
const note = createNoteWithTitle('invoices')
const file = createFile('invoice_1.pdf')
await itemManager.insertItems([note, file])
@@ -796,25 +784,10 @@ describe('itemManager', () => {
expect(references).toHaveLength(0)
})
it('should get files linked with note', async () => {
itemManager = createService()
const note = createNote('invoices')
const file = createFile('invoice_1.pdf')
const secondFile = createFile('unrelated-file.xlsx')
await itemManager.insertItems([note, file, secondFile])
await itemManager.associateFileWithNote(file, note)
const filesAssociatedWithNote = itemManager.getSortedFilesLinkingToItem(note)
expect(filesAssociatedWithNote).toHaveLength(1)
expect(filesAssociatedWithNote[0].uuid).toBe(file.uuid)
})
it('should link note to note', async () => {
itemManager = createService()
const note = createNote('research')
const note2 = createNote('citation')
const note = createNoteWithTitle('research')
const note2 = createNoteWithTitle('citation')
await itemManager.insertItems([note, note2])
const resultingNote = await itemManager.linkNoteToNote(note, note2)
@@ -839,108 +812,56 @@ describe('itemManager', () => {
it('should get the relationship type for two items', async () => {
itemManager = createService()
const firstNote = createNote('First note')
const secondNote = createNote('Second note')
const unlinkedNote = createNote('Unlinked note')
const firstNote = createNoteWithTitle('First note')
const secondNote = createNoteWithTitle('Second note')
const unlinkedNote = createNoteWithTitle('Unlinked note')
await itemManager.insertItems([firstNote, secondNote, unlinkedNote])
const firstNoteLinkedToSecond = await itemManager.linkNoteToNote(firstNote, secondNote)
const relationshipOfFirstNoteToSecond = itemManager.relationshipTypeForItems(firstNoteLinkedToSecond, secondNote)
const relationshipOfSecondNoteToFirst = itemManager.relationshipTypeForItems(secondNote, firstNoteLinkedToSecond)
const relationshipOfFirstNoteToUnlinked = itemManager.relationshipTypeForItems(
const relationshipOfFirstNoteToSecond = itemManager.relationshipDirectionBetweenItems(
firstNoteLinkedToSecond,
secondNote,
)
const relationshipOfSecondNoteToFirst = itemManager.relationshipDirectionBetweenItems(
secondNote,
firstNoteLinkedToSecond,
)
const relationshipOfFirstNoteToUnlinked = itemManager.relationshipDirectionBetweenItems(
firstNoteLinkedToSecond,
unlinkedNote,
)
expect(relationshipOfFirstNoteToSecond).toBe('direct')
expect(relationshipOfSecondNoteToFirst).toBe('indirect')
expect(relationshipOfFirstNoteToUnlinked).toBe('unlinked')
expect(relationshipOfFirstNoteToSecond).toBe(ItemRelationshipDirection.AReferencesB)
expect(relationshipOfSecondNoteToFirst).toBe(ItemRelationshipDirection.BReferencesA)
expect(relationshipOfFirstNoteToUnlinked).toBe(ItemRelationshipDirection.NoRelationship)
})
it('should unlink itemToUnlink from item', async () => {
it('should unlink itemOne from itemTwo if relation is direct', async () => {
itemManager = createService()
const note = createNote('Note 1')
const note2 = createNote('Note 2')
const note = createNoteWithTitle('Note 1')
const note2 = createNoteWithTitle('Note 2')
await itemManager.insertItems([note, note2])
const linkedItem = await itemManager.linkNoteToNote(note, note2)
const unlinkedItem = await itemManager.unlinkItem(linkedItem, note2)
const unlinkedItem = await itemManager.unlinkItems(linkedItem, note2)
const references = unlinkedItem.references
expect(unlinkedItem.uuid).toBe(note.uuid)
expect(references).toHaveLength(0)
})
it('should get all linked files for item', async () => {
it('should unlink itemTwo from itemOne if relation is indirect', async () => {
itemManager = createService()
const file = createFile('A1')
const file2 = createFile('B2')
const file3 = createFile('C3')
const note = createNoteWithTitle('Note 1')
const note2 = createNoteWithTitle('Note 2')
await itemManager.insertItems([note, note2])
await itemManager.insertItems([file, file2, file3])
const linkedItem = await itemManager.linkNoteToNote(note, note2)
const changedItem = await itemManager.unlinkItems(linkedItem, note2)
await itemManager.linkFileToFile(file, file3)
await itemManager.linkFileToFile(file, file2)
const sortedFilesForItem = itemManager.getSortedLinkedFilesForItem(file)
expect(sortedFilesForItem).toHaveLength(2)
expect(sortedFilesForItem[0].uuid).toEqual(file2.uuid)
expect(sortedFilesForItem[1].uuid).toEqual(file3.uuid)
})
it('should get all files linking to item', async () => {
itemManager = createService()
const baseFile = createFile('file')
const fileToLink1 = createFile('A1')
const fileToLink2 = createFile('B2')
await itemManager.insertItems([baseFile, fileToLink1, fileToLink2])
await itemManager.linkFileToFile(fileToLink2, baseFile)
await itemManager.linkFileToFile(fileToLink1, baseFile)
const sortedFilesForItem = itemManager.getSortedFilesLinkingToItem(baseFile)
expect(sortedFilesForItem).toHaveLength(2)
expect(sortedFilesForItem[0].uuid).toEqual(fileToLink1.uuid)
expect(sortedFilesForItem[1].uuid).toEqual(fileToLink2.uuid)
})
it('should get all linked notes for item', async () => {
itemManager = createService()
const baseNote = createNote('note')
const noteToLink1 = createNote('A1')
const noteToLink2 = createNote('B2')
await itemManager.insertItems([baseNote, noteToLink1, noteToLink2])
await itemManager.linkNoteToNote(baseNote, noteToLink2)
await itemManager.linkNoteToNote(baseNote, noteToLink1)
const sortedFilesForItem = itemManager.getSortedLinkedNotesForItem(baseNote)
expect(sortedFilesForItem).toHaveLength(2)
expect(sortedFilesForItem[0].uuid).toEqual(noteToLink1.uuid)
expect(sortedFilesForItem[1].uuid).toEqual(noteToLink2.uuid)
})
it('should get all notes linking to item', async () => {
itemManager = createService()
const baseNote = createNote('note')
const noteToLink1 = createNote('A1')
const noteToLink2 = createNote('B2')
await itemManager.insertItems([baseNote, noteToLink1, noteToLink2])
await itemManager.linkNoteToNote(noteToLink2, baseNote)
await itemManager.linkNoteToNote(noteToLink1, baseNote)
const sortedFilesForItem = itemManager.getSortedNotesLinkingToItem(baseNote)
expect(sortedFilesForItem).toHaveLength(2)
expect(sortedFilesForItem[0].uuid).toEqual(noteToLink1.uuid)
expect(sortedFilesForItem[1].uuid).toEqual(noteToLink2.uuid)
expect(changedItem.uuid).toBe(note.uuid)
expect(changedItem.references).toHaveLength(0)
})
})
})
+24 -69
View File
@@ -7,7 +7,7 @@ import { UuidString } from '../../Types/UuidString'
import * as Models from '@standardnotes/models'
import * as Services from '@standardnotes/services'
import { PayloadManagerChangeData } from '../Payloads'
import { DiagnosticInfo, ItemsClientInterface } from '@standardnotes/services'
import { DiagnosticInfo, ItemsClientInterface, ItemRelationshipDirection } from '@standardnotes/services'
import { ApplicationDisplayOptions } from '@Lib/Application/Options/OptionalOptions'
import { CollectionSort, DecryptedItemInterface, ItemContent } from '@standardnotes/models'
@@ -1169,12 +1169,18 @@ export class ItemManager
})
}
public async unlinkItem(
item: DecryptedItemInterface<ItemContent>,
itemToUnlink: DecryptedItemInterface<ItemContent>,
) {
return this.changeItem(item, (mutator) => {
mutator.removeItemAsRelationship(itemToUnlink)
public async unlinkItems(itemA: DecryptedItemInterface<ItemContent>, itemB: DecryptedItemInterface<ItemContent>) {
const relationshipDirection = this.relationshipDirectionBetweenItems(itemA, itemB)
if (relationshipDirection === ItemRelationshipDirection.NoRelationship) {
throw new Error('Trying to unlink already unlinked items')
}
const itemToChange = relationshipDirection === ItemRelationshipDirection.AReferencesB ? itemA : itemB
const itemToRemove = itemToChange === itemA ? itemB : itemA
return this.changeItem(itemToChange, (mutator) => {
mutator.removeItemAsRelationship(itemToRemove)
})
}
@@ -1192,54 +1198,6 @@ export class ItemManager
)
}
public getSortedLinkedFilesForItem(item: DecryptedItemInterface<ItemContent>): Models.FileItem[] {
if (this.isTemplateItem(item)) {
return []
}
const filesReferencedByItem = this.referencesForItem(item).filter(
(ref) => ref.content_type === ContentType.File,
) as Models.FileItem[]
return naturalSort(filesReferencedByItem, 'title')
}
public getSortedFilesLinkingToItem(item: DecryptedItemInterface<ItemContent>): Models.FileItem[] {
if (this.isTemplateItem(item)) {
return []
}
const filesReferencingItem = this.itemsReferencingItem(item).filter(
(ref) => ref.content_type === ContentType.File,
) as Models.FileItem[]
return naturalSort(filesReferencingItem, 'title')
}
public getSortedLinkedNotesForItem(item: DecryptedItemInterface<ItemContent>): Models.SNNote[] {
if (this.isTemplateItem(item)) {
return []
}
const notesReferencedByItem = this.referencesForItem(item).filter(
(ref) => ref.content_type === ContentType.Note,
) as Models.SNNote[]
return naturalSort(notesReferencedByItem, 'title')
}
public getSortedNotesLinkingToItem(item: Models.DecryptedItemInterface<Models.ItemContent>): Models.SNNote[] {
if (this.isTemplateItem(item)) {
return []
}
const notesReferencingItem = this.itemsReferencingItem(item).filter(
(ref) => ref.content_type === ContentType.Note,
) as Models.SNNote[]
return naturalSort(notesReferencingItem, 'title')
}
public async createTag(title: string, parentItemToLookupUuidFor?: Models.SNTag): Promise<Models.SNTag> {
const newTag = await this.createItem<Models.SNTag>(
ContentType.Tag,
@@ -1433,21 +1391,18 @@ export class ItemManager
return this.findAnyItems(uuids) as (Models.DecryptedItemInterface | Models.DeletedItemInterface)[]
}
/**
* @returns `'direct'` if `itemOne` has the reference to `itemTwo`, `'indirect'` if `itemTwo` has the reference to `itemOne`, `'unlinked'` if neither reference each other
*/
public relationshipTypeForItems(
itemOne: Models.DecryptedItemInterface<Models.ItemContent>,
itemTwo: Models.DecryptedItemInterface<Models.ItemContent>,
): 'direct' | 'indirect' | 'unlinked' {
const itemOneReferencesItemTwo = this.isTemplateItem(itemOne)
? false
: !!this.referencesForItem(itemOne).find((reference) => reference.uuid === itemTwo.uuid)
const itemTwoReferencesItemOne = this.isTemplateItem(itemTwo)
? false
: !!this.referencesForItem(itemTwo).find((reference) => reference.uuid === itemOne.uuid)
public relationshipDirectionBetweenItems(
itemA: Models.DecryptedItemInterface<Models.ItemContent>,
itemB: Models.DecryptedItemInterface<Models.ItemContent>,
): ItemRelationshipDirection {
const itemAReferencesItemB = !!itemA.references.find((reference) => reference.uuid === itemB.uuid)
const itemBReferencesItemA = !!itemB.references.find((reference) => reference.uuid === itemA.uuid)
return itemOneReferencesItemTwo ? 'direct' : itemTwoReferencesItemOne ? 'indirect' : 'unlinked'
return itemAReferencesItemB
? ItemRelationshipDirection.AReferencesB
: itemBReferencesItemA
? ItemRelationshipDirection.BReferencesA
: ItemRelationshipDirection.NoRelationship
}
override getDiagnostics(): Promise<DiagnosticInfo | undefined> {
@@ -1,3 +1,4 @@
import { SNNote } from '@standardnotes/models'
import { Uuid } from '@standardnotes/common'
import { ListedAccount, ListedAccountInfo } from '@standardnotes/responses'
@@ -6,4 +7,6 @@ export interface ListedClientInterface {
requestNewListedAccount: () => Promise<ListedAccount | undefined>
getListedAccounts(): Promise<ListedAccount[]>
getListedAccountInfo(account: ListedAccount, inContextOfItem?: Uuid): Promise<ListedAccountInfo | undefined>
isNoteAuthorizedForListed(note: SNNote): boolean
authorizeNoteForListed(note: SNNote): Promise<boolean>
}
@@ -8,8 +8,9 @@ import { SNSettingsService } from '../Settings/SNSettingsService'
import { ListedClientInterface } from './ListedClientInterface'
import { SNApiService } from '../Api/ApiService'
import { ListedAccount, ListedAccountInfo, ListedAccountInfoResponse } from '@standardnotes/responses'
import { SNActionsExtension } from '@standardnotes/models'
import { AbstractService, InternalEventBusInterface } from '@standardnotes/services'
import { NoteMutator, SNActionsExtension, SNNote } from '@standardnotes/models'
import { AbstractService, InternalEventBusInterface, MutatorClientInterface } from '@standardnotes/services'
import { SNProtectionService } from '../Protection'
export class ListedService extends AbstractService implements ListedClientInterface {
constructor(
@@ -17,6 +18,8 @@ export class ListedService extends AbstractService implements ListedClientInterf
private itemManager: ItemManager,
private settingsService: SNSettingsService,
private httpSerivce: SNHttpService,
private protectionService: SNProtectionService,
private mutatorService: MutatorClientInterface,
protected override internalEventBus: InternalEventBusInterface,
) {
super(internalEventBus)
@@ -27,6 +30,8 @@ export class ListedService extends AbstractService implements ListedClientInterf
;(this.settingsService as unknown) = undefined
;(this.apiService as unknown) = undefined
;(this.httpSerivce as unknown) = undefined
;(this.protectionService as unknown) = undefined
;(this.mutatorService as unknown) = undefined
super.deinit()
}
@@ -34,6 +39,23 @@ export class ListedService extends AbstractService implements ListedClientInterf
return this.apiService.user != undefined
}
public isNoteAuthorizedForListed(note: SNNote): boolean {
return note.authorizedForListed
}
public async authorizeNoteForListed(note: SNNote): Promise<boolean> {
const result = await this.protectionService.authorizeListedPublishing()
if (result === false) {
return false
}
await this.mutatorService.changeAndSaveItem<NoteMutator>(note, (mutator) => {
mutator.authorizedForListed = true
})
return true
}
/**
* Account creation is asyncronous on the backend due to message-based nature of architecture.
* In order to get the newly created account, we poll the server to check for new accounts.
@@ -73,8 +95,11 @@ export class ListedService extends AbstractService implements ListedClientInterf
if (inContextOfItem) {
url += `&item_uuid=${inContextOfItem}`
}
const response = (await this.httpSerivce.getAbsolute(url)) as ListedAccountInfoResponse
if (response.error || !response.data || isString(response.data)) {
const response = (await this.httpSerivce.getAbsolute(url).catch((error) => {
console.error(error)
})) as ListedAccountInfoResponse
if (!response || response.error || !response.data || isString(response.data)) {
return undefined
}
@@ -219,13 +219,18 @@ export class SNProtectionService extends AbstractService<ProtectionEvent> implem
return this.authorizeAction(ChallengeReason.RevokeSession)
}
async authorizeListedPublishing(): Promise<boolean> {
return this.authorizeAction(ChallengeReason.AuthorizeNoteForListed, { forcePrompt: true })
}
async authorizeAction(
reason: ChallengeReason,
{ fallBackToAccountPassword = true, requireAccountPassword = false } = {},
{ fallBackToAccountPassword = true, requireAccountPassword = false, forcePrompt = false } = {},
): Promise<boolean> {
return this.validateOrRenewSession(reason, {
requireAccountPassword,
fallBackToAccountPassword,
forcePrompt,
})
}
@@ -295,9 +300,9 @@ export class SNProtectionService extends AbstractService<ProtectionEvent> implem
private async validateOrRenewSession(
reason: ChallengeReason,
{ fallBackToAccountPassword = true, requireAccountPassword = false } = {},
{ fallBackToAccountPassword = true, requireAccountPassword = false, forcePrompt = false } = {},
): Promise<boolean> {
if (this.getSessionExpiryDate() > new Date()) {
if (this.getSessionExpiryDate() > new Date() && !forcePrompt) {
return true
}
@@ -139,7 +139,7 @@ export class SNSessionManager extends AbstractService<SessionEvent> implements S
return isNullOrUndefined(this.apiService.getSession())
}
public getUser() {
public getUser(): Responses.User | undefined {
return this.user
}
@@ -1,8 +1,8 @@
import { ClientDisplayableError } from '@standardnotes/responses'
import { ClientDisplayableError, User } from '@standardnotes/responses'
import { Base64String } from '@standardnotes/sncrypto-common'
export interface SessionsClientInterface {
createDemoShareToken(): Promise<Base64String | ClientDisplayableError>
populateSessionFromDemoShareToken(token: Base64String): Promise<void>
getUser(): User | undefined
}
+29
View File
@@ -0,0 +1,29 @@
import { ContentType } from '@standardnotes/common'
import * as Models from '@standardnotes/models'
export const createNote = (payload?: Partial<Models.NoteContent>): Models.SNNote => {
return new Models.SNNote(
new Models.DecryptedPayload(
{
uuid: String(Math.random()),
content_type: ContentType.Note,
content: Models.FillItemContent({ ...payload }),
...Models.PayloadTimestampDefaults(),
},
Models.PayloadSource.Constructor,
),
)
}
export const createNoteWithTitle = (title: string) => {
return new Models.SNNote(
new Models.DecryptedPayload({
uuid: String(Math.random()),
content_type: ContentType.Note,
content: Models.FillItemContent<Models.NoteContent>({
title: title,
}),
...Models.PayloadTimestampDefaults(),
}),
)
}
-1
View File
@@ -1,3 +1,2 @@
export * from './ApplicationEventPayload'
export * from './IconType'
export * from './UuidString'
@@ -356,14 +356,13 @@ describe('app models', () => {
})
it('maintains editor reference when duplicating note', async function () {
const note = await Factory.createMappedNote(this.application)
const editor = await this.application.itemManager.createItem(
ContentType.Component,
{ area: ComponentArea.Editor },
{ area: ComponentArea.Editor, package_info: { identifier: 'foo-editor' } },
true,
)
await this.application.itemManager.changeComponent(editor, (mutator) => {
mutator.associateWithItem(note.uuid)
const note = await Factory.insertItemWithOverride(this.application, ContentType.Note, {
editorIdentifier: 'foo-editor',
})
expect(this.application.componentManager.editorForNote(note).uuid).to.equal(editor.uuid)
@@ -114,59 +114,6 @@ describe('online conflict handling', function () {
await this.sharedFinalAssertions()
})
it('duplicating note should maintain editor ref', async function () {
const note = await Factory.createSyncedNote(this.application)
this.expectedItemCount++
const basePayload = createDirtyPayload(ContentType.Component)
const payload = basePayload.copy({
content: {
...basePayload.content,
area: ComponentArea.Editor,
},
})
const editor = await this.application.itemManager.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
this.expectedItemCount++
await this.application.syncService.sync(syncOptions)
await this.application.mutator.changeAndSaveItem(
editor,
(mutator) => {
mutator.associateWithItem(note.uuid)
},
undefined,
undefined,
syncOptions,
)
expect(this.application.componentManager.editorForNote(note)).to.be.ok
/** Conflict the note */
/** First modify the item without saving so that
* our local contents digress from the server's */
await this.application.mutator.changeItem(note, (mutator) => {
mutator.title = `${Math.random()}`
})
await Factory.changePayloadTimeStampAndSync(
this.application,
note.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{
title: 'zar',
},
syncOptions,
)
this.expectedItemCount++
const duplicate = this.application.itemManager.getDisplayableNotes().find((n) => {
return n.uuid !== note.uuid
})
expect(duplicate).to.be.ok
expect(this.application.componentManager.editorForNote(duplicate)).to.be.ok
await this.sharedFinalAssertions()
})
it('should create conflicted copy if incoming server item attempts to overwrite local dirty item', async function () {
// create an item and sync it
const note = await Factory.createMappedNote(this.application)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/snjs",
"version": "2.141.1",
"version": "2.143.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+28
View File
@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.9.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.9.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
### Bug Fixes
* refactor application event observing on web ([9fb85cd](https://github.com/standardnotes/app/commit/9fb85cd77a627364738a9c21706431d2a01e9c44))
# [1.9.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
### Bug Fixes
* **ui-services:** add route type getter ([401a35f](https://github.com/standardnotes/app/commit/401a35f4db9e7f090ad84c2d9e0ce5b465c7e790))
### Features
* add accepting subscription invite route type ([83b4840](https://github.com/standardnotes/app/commit/83b484002c066675e58625d7c0a1f7a7566df787))
## [1.8.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.8.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
**Note:** Version bump only for package @standardnotes/ui-services
## [1.8.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
**Note:** Version bump only for package @standardnotes/ui-services
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/ui-services",
"version": "1.8.3",
"version": "1.9.2",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -0,0 +1,3 @@
export type DemoParams = {
token: string
}
@@ -0,0 +1,3 @@
export type OnboardingParams = {
fromHomepage: boolean
}
@@ -0,0 +1,4 @@
export type PurchaseParams = {
plan: string
period: string
}
@@ -0,0 +1,5 @@
import { PreferenceId } from '../../Preferences/PreferenceId'
export type SettingsParams = {
panel: PreferenceId
}
@@ -0,0 +1,5 @@
import { Uuid } from '@standardnotes/common'
export type SubscriptionInviteParams = {
inviteUuid: Uuid
}
@@ -0,0 +1,6 @@
export enum RootQueryParam {
Purchase = 'purchase',
Settings = 'settings',
DemoToken = 'demo-token',
AcceptSubscriptionInvite = 'accept-subscription-invite',
}
@@ -0,0 +1,4 @@
export enum RootRoutes {
Onboarding = '/onboard',
None = '/',
}
@@ -1,18 +0,0 @@
import { PreferenceId } from '../Preferences/PreferenceId'
export type OnboardingParams = {
fromHomepage: boolean
}
export type SettingsParams = {
panel: PreferenceId
}
export type DemoParams = {
token: string
}
export type PurchaseParams = {
plan: string
period: string
}

Some files were not shown because too many files have changed in this diff Show More