diff --git a/app/assets/javascripts/Components/Preferences/Panes/Account/Files.tsx b/app/assets/javascripts/Components/Preferences/Panes/Account/Files.tsx new file mode 100644 index 00000000000..237e099de23 --- /dev/null +++ b/app/assets/javascripts/Components/Preferences/Panes/Account/Files.tsx @@ -0,0 +1,37 @@ +import { AppState } from '@/UIModels/AppState' +import { formatSizeToReadableString } from '@standardnotes/filepicker' +import { observer } from 'mobx-react-lite' +import { FunctionComponent } from 'preact' +import { PreferencesGroup, PreferencesSegment, Subtitle, Title } from '../../PreferencesComponents' + +type Props = { + appState: AppState +} + +export const FilesSection: FunctionComponent = observer(({ appState }) => { + if (!appState.features.isEntitledToFiles) { + return null + } + + const filesQuotaUsed = appState.files.filesQuotaUsed + const filesQuotaTotal = appState.files.filesQuotaTotal + + return ( + + + Files + Storage Quota +
+ {formatSizeToReadableString(filesQuotaUsed)} of{' '} + {formatSizeToReadableString(filesQuotaTotal)} used +
+ +
+
+ ) +}) diff --git a/app/assets/javascripts/Components/Preferences/Panes/Account/index.tsx b/app/assets/javascripts/Components/Preferences/Panes/Account/index.tsx index ac39ef25138..3024047893e 100644 --- a/app/assets/javascripts/Components/Preferences/Panes/Account/index.tsx +++ b/app/assets/javascripts/Components/Preferences/Panes/Account/index.tsx @@ -7,6 +7,7 @@ import { Credentials } from './Credentials' import { Sync } from './Sync' import { Subscription } from './Subscription/Subscription' import { SignOutWrapper } from './SignOutView' +import { FilesSection } from './Files' type Props = { application: WebApplication @@ -24,6 +25,7 @@ export const AccountPreferences = observer(({ application, appState }: Props) => )} + )) diff --git a/app/assets/javascripts/UIModels/AppState/AppState.ts b/app/assets/javascripts/UIModels/AppState/AppState.ts index 2c616e1ed8e..49c9fe5b6b5 100644 --- a/app/assets/javascripts/UIModels/AppState/AppState.ts +++ b/app/assets/javascripts/UIModels/AppState/AppState.ts @@ -110,7 +110,7 @@ export class AppState { this.subscription = new SubscriptionState(application, this.appEventObserverRemovers) this.purchaseFlow = new PurchaseFlowState(application) this.notesView = new NotesViewState(application, this, this.appEventObserverRemovers) - this.files = new FilesState(application) + this.files = new FilesState(application, this.appEventObserverRemovers) this.addAppEventObserver() this.streamNotesAndTags() this.onVisibilityChange = () => { diff --git a/app/assets/javascripts/UIModels/AppState/FilesState.ts b/app/assets/javascripts/UIModels/AppState/FilesState.ts index d1a8b1bf2ca..1903f5c58c8 100644 --- a/app/assets/javascripts/UIModels/AppState/FilesState.ts +++ b/app/assets/javascripts/UIModels/AppState/FilesState.ts @@ -7,13 +7,61 @@ import { ClassicFileSaver, parseFileName, } from '@standardnotes/filepicker' -import { ClientDisplayableError, SNFile } from '@standardnotes/snjs' +import { + ApplicationEvent, + ClientDisplayableError, + ContentType, + SNFile, + SubscriptionSettingName, +} from '@standardnotes/snjs' import { addToast, dismissToast, ToastType } from '@standardnotes/stylekit' +import { action, makeObservable, observable } from 'mobx' import { WebApplication } from '../Application' export class FilesState { - constructor(private application: WebApplication) {} + filesQuotaUsed: number + filesQuotaTotal: number + + constructor(private application: WebApplication, appObservers: (() => void)[]) { + this.filesQuotaUsed = 0 + this.filesQuotaTotal = 0 + + makeObservable(this, { + filesQuotaUsed: observable, + filesQuotaTotal: observable, + getFilesQuota: action, + }) + + appObservers.push( + application.addEventObserver(async (event) => { + switch (event) { + case ApplicationEvent.Launched: + case ApplicationEvent.SignedIn: + this.getFilesQuota().catch(console.error) + } + }), + application.streamItems(ContentType.File, () => { + this.getFilesQuota().catch(console.error) + }), + ) + } + + public async getFilesQuota() { + const filesQuotaUsed = await this.application.settings.getSubscriptionSetting( + SubscriptionSettingName.FileUploadBytesUsed, + ) + const filesQuotaTotal = await this.application.settings.getSubscriptionSetting( + SubscriptionSettingName.FileUploadBytesLimit, + ) + + if (filesQuotaUsed) { + this.filesQuotaUsed = parseFloat(filesQuotaUsed) + } + if (filesQuotaTotal) { + this.filesQuotaTotal = parseFloat(filesQuotaTotal) + } + } public async downloadFile(file: SNFile): Promise { let downloadingToastId = '' diff --git a/app/assets/stylesheets/_sn.scss b/app/assets/stylesheets/_sn.scss index bcae64ae7a4..1314185281d 100644 --- a/app/assets/stylesheets/_sn.scss +++ b/app/assets/stylesheets/_sn.scss @@ -1127,3 +1127,24 @@ .sn-component .hover\:bg-default:hover { background-color: var(--sn-stylekit-background-color); } + +.sn-component .progress-bar { + border-radius: 0.5rem; + background-color: var(--sn-stylekit-contrast-background-color); + border: 0; + + &::-webkit-progress-bar { + background-color: var(--sn-stylekit-contrast-background-color); + border-radius: 0.5rem; + } + + &::-webkit-progress-value { + background-color: var(--sn-stylekit-info-color); + border-radius: 0.5rem; + } + + &::-moz-progress-bar { + background-color: var(--sn-stylekit-info-color); + border-radius: 0.5rem; + } +} diff --git a/package.json b/package.json index 1a3b15bcb5e..7f36b81d661 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "@standardnotes/components": "1.7.15", "@standardnotes/filepicker": "1.12.0", "@standardnotes/sncrypto-web": "1.8.3", - "@standardnotes/snjs": "2.97.7", + "@standardnotes/snjs": "2.99.0", "@standardnotes/stylekit": "5.23.0", "@zip.js/zip.js": "^2.4.7", "mobx": "^6.5.0", diff --git a/yarn.lock b/yarn.lock index 56d386ccce3..f40f231d28c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2388,18 +2388,18 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@standardnotes/auth@^3.18.10": - version "3.18.10" - resolved "https://registry.yarnpkg.com/@standardnotes/auth/-/auth-3.18.10.tgz#6be69cb1d887464daec271aeda11af4784ecb9f5" - integrity sha512-ibJvW7T/xHQooF3XVN9aGqn8DEqZxXXI0V49jquWRAztvyZ4GTwcL2RmhS2vhxvKbD6g+pBC5IOYqDn6vlUkOg== +"@standardnotes/auth@^3.18.11": + version "3.18.11" + resolved "https://registry.yarnpkg.com/@standardnotes/auth/-/auth-3.18.11.tgz#1044698e9c07d940b243d63f0deb0349481687c4" + integrity sha512-NygrMeYRTg/aqxlLroiRRoqsn1fL5Mz+gq/t0zz6+ecy3V4Pqz9fGu32l3IMYHQvI1B4vbgI1nnTp0jP5XPbjg== dependencies: - "@standardnotes/common" "^1.19.5" + "@standardnotes/common" "^1.19.6" jsonwebtoken "^8.5.1" -"@standardnotes/common@^1.19.5": - version "1.19.5" - resolved "https://registry.yarnpkg.com/@standardnotes/common/-/common-1.19.5.tgz#2ebed30ae9a1136efbbc1d86cfe43be54dd817fc" - integrity sha512-rdKOdseVAXT/WJtjAQp7fp2FmXXjoMowSu0bCvE+ggjMigbiC1z8CbFYMa/Gav2Lp+nJkBUpIMOBIwFuvPJXXA== +"@standardnotes/common@^1.19.6": + version "1.19.6" + resolved "https://registry.yarnpkg.com/@standardnotes/common/-/common-1.19.6.tgz#6c672f4f10d5ed123a2c392dfb35dbe3c698b3b9" + integrity sha512-HxPrV9JhLp//S7h+QjOjlMPy0lgrjLT4iBKzr8JG8lUeWSS1mY3p1I+w0D9+yiraS2SPq2L14Z0VKds0zs9HXw== "@standardnotes/components@1.7.15": version "1.7.15" @@ -2414,74 +2414,87 @@ "@typescript-eslint/eslint-plugin" "^5.12.1" "@typescript-eslint/parser" "^5.12.1" -"@standardnotes/domain-events@^2.27.9": - version "2.27.9" - resolved "https://registry.yarnpkg.com/@standardnotes/domain-events/-/domain-events-2.27.9.tgz#dbbf2bc0449e5555a6cc07945f04e86eb624e5b4" - integrity sha512-UGNlUplpp4N7FL03TuGj8xVUM2Yl/pjkVUTGijHFQMu6O2k/ugu7Bqv9cGPZS99Ix3gZUA/JUdHf9+5yRKKxCw== +"@standardnotes/domain-events@^2.27.10": + version "2.27.10" + resolved "https://registry.yarnpkg.com/@standardnotes/domain-events/-/domain-events-2.27.10.tgz#ce52a7c51849a8f8995678be907c68937b8cfe02" + integrity sha512-TD71BRl9KRaxZBtYPFU2dmvz8L0H1AZvLF12KJrpcXVAPbSwNaprMx0LdATerIlpIa47cR/SbBBW9GRFpk5RTA== dependencies: - "@standardnotes/auth" "^3.18.10" - "@standardnotes/features" "^1.37.8" + "@standardnotes/auth" "^3.18.11" + "@standardnotes/features" "^1.37.9" -"@standardnotes/encryption@^1.4.7": - version "1.4.7" - resolved "https://registry.yarnpkg.com/@standardnotes/encryption/-/encryption-1.4.7.tgz#11340aa5f90a01d20a778c63a83f9949fef0e7d1" - integrity sha512-ot/8YsKSe/Kk8wMbmvH4/Ks/vSr2cUsg+oZVKZVKjgmGnxG2J57vkWOKIKx4GtIUIoq4HYK8JEvhY8Rx83WulA== +"@standardnotes/encryption@^1.4.8": + version "1.4.8" + resolved "https://registry.yarnpkg.com/@standardnotes/encryption/-/encryption-1.4.8.tgz#9d9f118f80df1a241f505474c7af154190990b38" + integrity sha512-AU4eFNzU7sJj+BLpyrUrOn3z6WmkLw1XriF0m8q+a/tzco2ez5j0bM4REMAFfpreOhFN5KSJ0yUTh8pLxwyZxA== dependencies: - "@standardnotes/models" "^1.4.7" - "@standardnotes/responses" "^1.6.9" - "@standardnotes/services" "^1.9.8" + "@standardnotes/models" "^1.4.8" + "@standardnotes/responses" "^1.6.10" + "@standardnotes/services" "^1.9.9" -"@standardnotes/features@^1.37.8": - version "1.37.8" - resolved "https://registry.yarnpkg.com/@standardnotes/features/-/features-1.37.8.tgz#9214d9909da721e5db4774bc8ea7b5964b2dc322" - integrity sha512-A5ZSnxTO5fKpsEnlFhD3eIfcphn1d2V+6ATDcaJJIVr0tMPL5Km4BRUvu8VieosHn0obojfFCJpXKSRkxuqtlA== +"@standardnotes/features@^1.37.9": + version "1.37.9" + resolved "https://registry.yarnpkg.com/@standardnotes/features/-/features-1.37.9.tgz#8de7cc747e29684976d5bb5534b2a36edfa0d07c" + integrity sha512-+j4/skCnd9SIY9KmULv7fX1KPBpgs8uOC78/TBf8rT20KEI1rNIw9c9RFTMEaQW/2tn2HPFweHAetWzIUiTWJg== dependencies: - "@standardnotes/auth" "^3.18.10" - "@standardnotes/common" "^1.19.5" + "@standardnotes/auth" "^3.18.11" + "@standardnotes/common" "^1.19.6" "@standardnotes/filepicker@1.12.0": version "1.12.0" resolved "https://registry.yarnpkg.com/@standardnotes/filepicker/-/filepicker-1.12.0.tgz#6ee1224c8a7d039565a27950aa4e879a18fecebf" integrity sha512-67hsz3/xnOmvhxFVUurjuLU1jaMKEYXCwwGSls/NJxkXEX1WwWA9kvAwAnrJTRoFJAKVDyBglcLpRrFkOvEc9w== -"@standardnotes/models@^1.4.7": - version "1.4.7" - resolved "https://registry.yarnpkg.com/@standardnotes/models/-/models-1.4.7.tgz#e0e5c12f40b477db4e0dc1e20a7251461f064524" - integrity sha512-jD5EI9g3boNEJSPnZ4eeNOYjwLQEeQU839lFqe3RrDq6M7ukUgniHBxHxgEPzgPELyIbPFN+NOoLCZdqW9h2Kg== +"@standardnotes/filepicker@^1.13.1": + version "1.13.1" + resolved "https://registry.yarnpkg.com/@standardnotes/filepicker/-/filepicker-1.13.1.tgz#bad1e3434711e4894b08a40cc16ec4e631bf8476" + integrity sha512-oK5Ew9avEH9LO2YGW1fSlUHMx9wOYS0KeXt2UOnl0B+SwAiVQN14F6DfvTyZ+JlEqn8PXq0liUoRTN9Lk7Fbgg== dependencies: - "@standardnotes/features" "^1.37.8" - "@standardnotes/responses" "^1.6.9" - "@standardnotes/utils" "^1.6.1" + "@standardnotes/common" "^1.19.6" + "@standardnotes/utils" "^1.6.2" -"@standardnotes/responses@^1.6.9": - version "1.6.9" - resolved "https://registry.yarnpkg.com/@standardnotes/responses/-/responses-1.6.9.tgz#a69a8698ddada21f0edb6bbbf50f8a68a4614bfd" - integrity sha512-HUKOrqZ5WGnxMoDGh6aEnQY48Eo3W3rNpesm91vRuKBVTxbwb876RXlElEtEAz5MYepatIg5mcX2dPxIZIHSvg== +"@standardnotes/models@^1.4.8": + version "1.4.8" + resolved "https://registry.yarnpkg.com/@standardnotes/models/-/models-1.4.8.tgz#7da29c5e3d7de4265c1f1a6f112e9b89c85c26c9" + integrity sha512-30cMS320htMTBvpYcPFsFhkmr6JyvQIkc/7IvCKPxK40yGWdTGRqwfNNSDMP5SMKXjf4t7sh1NJGjJe44DrdbQ== dependencies: - "@standardnotes/auth" "^3.18.10" - "@standardnotes/common" "^1.19.5" - "@standardnotes/features" "^1.37.8" + "@standardnotes/features" "^1.37.9" + "@standardnotes/responses" "^1.6.10" + "@standardnotes/utils" "^1.6.2" -"@standardnotes/services@^1.9.8": - version "1.9.8" - resolved "https://registry.yarnpkg.com/@standardnotes/services/-/services-1.9.8.tgz#3942dfc58584388e4ec886d11f039c3f2119b7a9" - integrity sha512-uWuLNsgStNcy1dIvAsPt3VO7M01nNna0PxGs1PZupG22vm7WSbZz7bXkHmIz5ToJmsFi69M9Bt8akuzgwi3eRw== +"@standardnotes/responses@^1.6.10": + version "1.6.10" + resolved "https://registry.yarnpkg.com/@standardnotes/responses/-/responses-1.6.10.tgz#7f3436ec183005c3802b60214fe9a5b8f817e14e" + integrity sha512-orR8DIUk8IzoOdSzcpOC620LZxPog1ts+qD7Lv+45/FqHOhbzCce2eoOgheMjkaQi+TTbyR68QfmdJN853rzHQ== dependencies: - "@standardnotes/common" "^1.19.5" - "@standardnotes/models" "^1.4.7" - "@standardnotes/responses" "^1.6.9" - "@standardnotes/utils" "^1.6.1" + "@standardnotes/auth" "^3.18.11" + "@standardnotes/common" "^1.19.6" + "@standardnotes/features" "^1.37.9" -"@standardnotes/settings@^1.14.0": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@standardnotes/settings/-/settings-1.14.0.tgz#f53b7bfecd9a49a5d4369d7f989e6378da13a798" - integrity sha512-YdbGKHDW9Ee/UhE4Q1r8UQcbtz384yyjzJp88m1CmZwARrDurJCfQneo4IX2lKVjjmXMCeZuA6sUXoAwejbreQ== +"@standardnotes/services@^1.9.9": + version "1.9.9" + resolved "https://registry.yarnpkg.com/@standardnotes/services/-/services-1.9.9.tgz#5ab11644dae227435e087dea5b9a37145db96a7d" + integrity sha512-moUI8s00zLJZum2MMvqft85Yk3ZDWQFuhZeC+o0Xt8Pp9RE6sLOhuAmS3/WnKPMww3/ggoy7mdOqZ2aIn+q1eg== + dependencies: + "@standardnotes/common" "^1.19.6" + "@standardnotes/models" "^1.4.8" + "@standardnotes/responses" "^1.6.10" + "@standardnotes/utils" "^1.6.2" + +"@standardnotes/settings@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@standardnotes/settings/-/settings-1.14.1.tgz#8b6c84e2eeeab274a557bad25cb16a62d60916ec" + integrity sha512-zRRBoflI77Zqa5ejZcXFPnvwVKf/gbLNtutB/pQE5SYlDMUgWtg6Qm8r4667Ue/nBUWZixCH0sznEN8XK8rCBw== "@standardnotes/sncrypto-common@^1.7.6": version "1.7.6" resolved "https://registry.yarnpkg.com/@standardnotes/sncrypto-common/-/sncrypto-common-1.7.6.tgz#8ff57f4eb8803d5631983d2f17f3c9ec2ec22011" integrity sha512-jzS4dIIsIVCEw4e6AdoOm0L71NHbc/RcYktiFbVDrr2teQn8z7777PdzHVXUEX5vcmtaZ0VADnev39wm0K5Rvw== +"@standardnotes/sncrypto-common@^1.7.7": + version "1.7.7" + resolved "https://registry.yarnpkg.com/@standardnotes/sncrypto-common/-/sncrypto-common-1.7.7.tgz#5970bbf09dc541a9894fec1101d5c92be5822ad1" + integrity sha512-ncpzrurFtgupbQvv6+aDts9Cebx57MMI78Dl2KnJJbFm+G47UJuxfX11q2aomBJdp2XdbWhQxCKOQPl5mmwWPQ== + "@standardnotes/sncrypto-web@1.8.3": version "1.8.3" resolved "https://registry.yarnpkg.com/@standardnotes/sncrypto-web/-/sncrypto-web-1.8.3.tgz#788ddf484d4170d6ab69859067f4404085dda380" @@ -2491,22 +2504,23 @@ buffer "^6.0.3" libsodium-wrappers "^0.7.9" -"@standardnotes/snjs@2.97.7": - version "2.97.7" - resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.97.7.tgz#1354d234aa93f5c7c86f4f56c0631394e3e5a155" - integrity sha512-2H9hggd/yE78f0/KFGP914efO2iq9hfAczI6eQzjZaXZD8LAXzBqko01ScVlUNoIisYlJvrbWp368bnR+erwqQ== - dependencies: - "@standardnotes/auth" "^3.18.10" - "@standardnotes/common" "^1.19.5" - "@standardnotes/domain-events" "^2.27.9" - "@standardnotes/encryption" "^1.4.7" - "@standardnotes/features" "^1.37.8" - "@standardnotes/models" "^1.4.7" - "@standardnotes/responses" "^1.6.9" - "@standardnotes/services" "^1.9.8" - "@standardnotes/settings" "^1.14.0" - "@standardnotes/sncrypto-common" "^1.7.6" - "@standardnotes/utils" "^1.6.1" +"@standardnotes/snjs@2.99.0": + version "2.99.0" + resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.99.0.tgz#b9c51d68abb9d9c43ebe108c39229f0896e37f51" + integrity sha512-rn/F3YiHBKfzylHTY4U8YbvShX/yNegaHQpAbmvP6uXCXF8msLcppKnecPw5pweQiv+o6JNORSBFfP25C6sbrw== + dependencies: + "@standardnotes/auth" "^3.18.11" + "@standardnotes/common" "^1.19.6" + "@standardnotes/domain-events" "^2.27.10" + "@standardnotes/encryption" "^1.4.8" + "@standardnotes/features" "^1.37.9" + "@standardnotes/filepicker" "^1.13.1" + "@standardnotes/models" "^1.4.8" + "@standardnotes/responses" "^1.6.10" + "@standardnotes/services" "^1.9.9" + "@standardnotes/settings" "^1.14.1" + "@standardnotes/sncrypto-common" "^1.7.7" + "@standardnotes/utils" "^1.6.2" "@standardnotes/stylekit@5.23.0": version "5.23.0" @@ -2521,12 +2535,12 @@ nanostores "^0.5.10" prop-types "^15.8.1" -"@standardnotes/utils@^1.6.1": - version "1.6.1" - resolved "https://registry.yarnpkg.com/@standardnotes/utils/-/utils-1.6.1.tgz#db26a7fb8890c9e187054bc8951cac18e48feca0" - integrity sha512-WhcyoWGKHbrcCVTR5MJNSgbS/T3cAZPw1IhRCE+0t07ChBow8shOr3/8BN+J/lzPcRMcTfVh3+MQLxLKIHEA5A== +"@standardnotes/utils@^1.6.2": + version "1.6.2" + resolved "https://registry.yarnpkg.com/@standardnotes/utils/-/utils-1.6.2.tgz#c118b6e7b23c4618d664e7894b3c49c702f656df" + integrity sha512-huU/t93Dy940bsB1JTfK3joqcZDT8toZfAtuktvHHHloTI7o5Wb0q9BtsmfGLRf1ohTq5ya0xkHFO5QVaAlV3g== dependencies: - "@standardnotes/common" "^1.19.5" + "@standardnotes/common" "^1.19.6" dompurify "^2.3.6" lodash "^4.17.21"