Compare commits

...
Author SHA1 Message Date
StandardNotes CI 8863ee82bb chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
2022-10-09 15:47:24 +00:00
Aman Harwara 6a4b5c5cdc fix: move viewport early return above 2022-10-09 20:39:48 +05:30
Aman Harwara cd1669f56f fix: potential fix for viewport height issue (#1772) 2022-10-09 20:37:44 +05:30
StandardNotes CI 037007f0ec chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
2022-10-08 08:12:13 +00:00
Aman Harwara e7ca12babe fix: open upgrade page in new tab if user has account 2022-10-08 13:12:32 +05:30
StandardNotes CI c4c33db1a4 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
2022-10-07 20:41:32 +00:00
Aman Harwara 734b986294 feat: open purchase flow when clicking upgrade cta with no account (#1771) 2022-10-08 01:39:40 +05:30
Aman Harwara 59db63f052 feat: change quick settings menu layout (#1770) 2022-10-08 01:08:54 +05:30
Mo 20226c3269 fix(desktop): use different method to send messages across main and render without node integration in preload (#1769) 2022-10-07 14:30:07 -05:00
StandardNotes CI a1352d9f65 chore(release): publish
- @standardnotes/[email protected].0
 - @standardnotes/[email protected]
2022-10-07 13:57:12 +00:00
Mo 7d21046b51 feat(mobile): delete account option in settings (#1768) 2022-10-07 08:23:18 -05:00
Mo a365c17c46 fix(mobile): disable landscape for iPhone 2022-10-07 07:27:37 -05:00
StandardNotes CI c1981334e1 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].5
2022-10-07 10:51:03 +00:00
Aman Harwara 1e3acd50e9 fix: add fallback for viewport height on mobile (#1766) 2022-10-07 15:41:45 +05:30
27 changed files with 286 additions and 155 deletions
+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.
## [3.23.200](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-09)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.199](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-08)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.198](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
### Bug Fixes
* **desktop:** use different method to send messages across main and render without node integration in preload ([#1769](https://github.com/standardnotes/app/issues/1769)) ([20226c3](https://github.com/standardnotes/app/commit/20226c326945ad9dc524f6dcbfc1c1274befb652))
## [3.23.197](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
**Note:** Version bump only for package @standardnotes/desktop
## [3.23.196](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
**Note:** Version bump only for package @standardnotes/desktop
@@ -5,6 +5,7 @@ import { autoUpdater } from 'electron-updater'
import { action, autorun, computed, makeObservable, observable } from 'mobx'
import { MessageType } from '../../../test/TestIpcMessage'
import { AppState } from '../../AppState'
import { MessageToWebApp } from '../Shared/IpcMessages'
import { BackupsManagerInterface } from './Backups/BackupsManagerInterface'
import { StoreKeys } from './Store/StoreKeys'
import { updates as str } from './Strings'
@@ -113,12 +114,12 @@ export function setupUpdates(window: BrowserWindow, appState: AppState, backupsM
setInterval(checkUpdateSafety, oneHour)
autoUpdater.on('update-downloaded', (info: { version?: string }) => {
window.webContents.send('update-available', null)
window.webContents.send(MessageToWebApp.UpdateAvailable, null)
updateState.autoUpdateHasBeenDownloaded(info.version || null)
})
autoUpdater.on('error', logError)
autoUpdater.on('update-available', (info: { version?: string }) => {
autoUpdater.on(MessageToWebApp.UpdateAvailable, (info: { version?: string }) => {
updateState.checkedForUpdate(info.version || null)
if (updateState.enableAutoUpdate) {
const canUpdate = checkUpdateSafety()
@@ -166,6 +166,7 @@ async function createWindow(store: Store): Promise<Electron.BrowserWindow> {
spellcheck: true,
nodeIntegration: isTesting(),
contextIsolation: true,
sandbox: true,
preload: Paths.preloadJs,
},
})
@@ -1,42 +1,28 @@
import { IpcRendererEvent } from 'electron/renderer'
import { MessageToWebApp } from '../Shared/IpcMessages'
const { ipcRenderer } = require('electron')
const path = require('path')
const rendererPath = path.join('file://', __dirname, '/renderer.js')
const RemoteBridge = require('@electron/remote').getGlobal('RemoteBridge')
const { contextBridge } = require('electron')
type MainEventCallback = (event: IpcRendererEvent, value: any) => void
process.once('loaded', function () {
contextBridge.exposeInMainWorld('electronRemoteBridge', RemoteBridge.exposableValue)
listenForIpcEventsFromMainProcess()
contextBridge.exposeInMainWorld('electronMainEvents', {
handleUpdateAvailable: (callback: MainEventCallback) => ipcRenderer.on(MessageToWebApp.UpdateAvailable, callback),
handlePerformAutomatedBackup: (callback: MainEventCallback) =>
ipcRenderer.on(MessageToWebApp.PerformAutomatedBackup, callback),
handleFinishedSavingBackup: (callback: MainEventCallback) =>
ipcRenderer.on(MessageToWebApp.FinishedSavingBackup, callback),
handleWindowBlurred: (callback: MainEventCallback) => ipcRenderer.on(MessageToWebApp.WindowBlurred, callback),
handleWindowFocused: (callback: MainEventCallback) => ipcRenderer.on(MessageToWebApp.WindowFocused, callback),
handleInstallComponentComplete: (callback: MainEventCallback) =>
ipcRenderer.on(MessageToWebApp.InstallComponentComplete, callback),
})
})
function listenForIpcEventsFromMainProcess() {
const sendMessageToRenderProcess = (message: string, payload = {}) => {
window.postMessage(JSON.stringify({ message, data: payload }), rendererPath)
}
ipcRenderer.on(MessageToWebApp.UpdateAvailable, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.UpdateAvailable, data)
})
ipcRenderer.on(MessageToWebApp.PerformAutomatedBackup, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.PerformAutomatedBackup, data)
})
ipcRenderer.on(MessageToWebApp.FinishedSavingBackup, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.FinishedSavingBackup, data)
})
ipcRenderer.on(MessageToWebApp.WindowBlurred, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.WindowBlurred, data)
})
ipcRenderer.on(MessageToWebApp.WindowFocused, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.WindowFocused, data)
})
ipcRenderer.on(MessageToWebApp.InstallComponentComplete, function (_event, data) {
sendMessageToRenderProcess(MessageToWebApp.InstallComponentComplete, data)
})
}
@@ -1,6 +1,6 @@
import { DesktopClientRequiresWebMethods } from '@web/Application/Device/DesktopSnjsExports'
import { StartApplication } from '@web/Application/Device/StartApplication'
import { MessageToWebApp } from '../Shared/IpcMessages'
import { IpcRendererEvent } from 'electron/renderer'
import { CrossProcessBridge } from './CrossProcessBridge'
import { DesktopDevice } from './DesktopDevice'
@@ -23,6 +23,7 @@ declare global {
purchaseUrl: string
startApplication: StartApplication
zip: any
electronMainEvents: any
}
}
@@ -41,8 +42,6 @@ const loadAndStartApplication = async () => {
window.device = await createDesktopDevice(remoteBridge)
window.startApplication(DEFAULT_SYNC_SERVER, window.device, window.enableUnfinishedFeatures, WEBSOCKET_URL)
listenForMessagesSentFromMainToPreloadToUs(window.device)
}
window.onload = () => {
@@ -134,35 +133,26 @@ async function configureWindow(remoteBridge: CrossProcessBridge) {
}
}
function listenForMessagesSentFromMainToPreloadToUs(device: DesktopDevice) {
window.addEventListener('message', async (event) => {
// We don't have access to the full file path.
if (event.origin !== 'file://') {
return
}
let payload
try {
payload = JSON.parse(event.data)
} catch (e) {
// message doesn't belong to us
return
}
const receiver = window.webClient
const message = payload.message
const data = payload.data
window.electronMainEvents.handleUpdateAvailable(() => {
window.webClient.updateAvailable()
})
if (message === MessageToWebApp.WindowBlurred) {
receiver.windowLostFocus()
} else if (message === MessageToWebApp.WindowFocused) {
receiver.windowGainedFocus()
} else if (message === MessageToWebApp.InstallComponentComplete) {
receiver.onComponentInstallationComplete(data.component, undefined)
} else if (message === MessageToWebApp.UpdateAvailable) {
receiver.updateAvailable()
} else if (message === MessageToWebApp.PerformAutomatedBackup) {
void device.downloadBackup()
} else if (message === MessageToWebApp.FinishedSavingBackup) {
receiver.didFinishBackup(data.success)
}
})
}
window.electronMainEvents.handlePerformAutomatedBackup(() => {
void window.device.downloadBackup()
})
window.electronMainEvents.handleFinishedSavingBackup((_: IpcRendererEvent, data: any) => {
window.webClient.didFinishBackup(data.success)
})
window.electronMainEvents.handleWindowBlurred(() => {
window.webClient.windowLostFocus()
})
window.electronMainEvents.handleWindowFocused(() => {
window.webClient.windowGainedFocus()
})
window.electronMainEvents.handleInstallComponentComplete((_: IpcRendererEvent, data: any) => {
window.webClient.onComponentInstallationComplete(data.component, undefined)
})
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/desktop",
"main": "./app/dist/index.js",
"version": "3.23.196",
"version": "3.23.200",
"license": "AGPL-3.0-or-later",
"author": "Standard Notes.",
"private": true,
+26
View File
@@ -3,6 +3,32 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.41.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-09)
**Note:** Version bump only for package @standardnotes/mobile
## [3.41.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-08)
**Note:** Version bump only for package @standardnotes/mobile
## [3.41.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
**Note:** Version bump only for package @standardnotes/mobile
# [3.41.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
### Bug Fixes
* **mobile:** disable landscape for iPhone ([a365c17](https://github.com/standardnotes/app/commit/a365c17c46f38e6d8cacade47542fd4ec625bc0d))
### Features
* **mobile:** delete account option in settings ([#1768](https://github.com/standardnotes/app/issues/1768)) ([7d21046](https://github.com/standardnotes/app/commit/7d21046b5189eb14a5957bda6fa788d743d8ebb6))
## [3.40.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
**Note:** Version bump only for package @standardnotes/mobile
## [3.40.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
**Note:** Version bump only for package @standardnotes/mobile
@@ -138,6 +138,10 @@
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~iphone</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>supportsAlternateIcons</key>
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/mobile",
"version": "3.40.1",
"version": "3.41.3",
"author": "Standard Notes.",
"private": true,
"license": "AGPL-3.0-or-later",
@@ -0,0 +1,50 @@
import { ApplicationContext } from '@Root/ApplicationContext'
import { ButtonCell } from '@Root/Components/ButtonCell'
import { SectionHeader } from '@Root/Components/SectionHeader'
import { TableSection } from '@Root/Components/TableSection'
import { ButtonType } from '@standardnotes/snjs'
import React, { useContext, useState } from 'react'
import { RegularView } from './AuthSection.styled'
export const DeleteSection = () => {
const application = useContext(ApplicationContext)
const [deleting, setDeleting] = useState(false)
const deleteAccount = async () => {
const message =
"This action is irreversible. After deletion completes, you will be signed out on all devices, and this application will exit. If you have an active paid subscription, cancel the subscription first. Otherwise, if you'd like to keep the subscription, you can re-register with the same email after deletion, and your subscription will be linked back up with your account."
const confirmed = await application!.alertService.confirm(
message,
'Are you sure?',
'Delete Account',
ButtonType.Danger,
)
if (!confirmed) {
return
}
setDeleting(true)
const result = await application!.user.deleteAccount()
if (result.error) {
void application!.alertService.alert('An error occurred while deleting your account. Please try again.')
}
}
return (
<RegularView>
<SectionHeader />
<TableSection>
<ButtonCell
first
last
important
leftAligned={true}
title={deleting ? 'Deleting...' : 'Delete Account'}
onPress={deleteAccount}
></ButtonCell>
</TableSection>
</RegularView>
)
}
@@ -153,7 +153,7 @@ export const WorkspacesSection = () => {
}
await appGroup.unloadCurrentAndCreateNewDescriptor()
}, [WorkspaceAction.AddAnother, appGroup, applicationDescriptors, getWorkspaceActionConfirmation])
}, [WorkspaceAction.AddAnother, appGroup, getWorkspaceActionConfirmation])
const signOutAllWorkspaces = useCallback(async () => {
try {
@@ -8,6 +8,7 @@ import { ApplicationEvent, FeatureIdentifier, FeatureStatus } from '@standardnot
import React, { useCallback, useEffect, useState } from 'react'
import { AuthSection } from './Sections/AuthSection'
import { CompanySection } from './Sections/CompanySection'
import { DeleteSection } from './Sections/DeleteSection'
import { EncryptionSection } from './Sections/EncryptionSection'
import { NewMobileSection } from './Sections/NewMobilePreview'
import { OptionsSection } from './Sections/OptionsSection'
@@ -68,6 +69,7 @@ export const Settings = (props: Props) => {
<ProtectionsSection title="Protections" protectionsAvailable={protectionsAvailable} />
<EncryptionSection encryptionAvailable={!!encryptionAvailable} title={'Encryption Status'} />
<CompanySection title="Standard Notes" />
{application.hasAccount() && <DeleteSection />}
</Container>
)
}
+20
View File
@@ -3,6 +3,26 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.127](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-09)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.126](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-08)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.125](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.124](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.123](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
**Note:** Version bump only for package @standardnotes/releases
## [1.3.122](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
**Note:** Version bump only for package @standardnotes/releases
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/releases",
"version": "1.3.122",
"version": "1.3.127",
"license": "AGPL-3.0-or-later",
"main": "dist/releases.json",
"types": "dist/index.d.ts",
+26
View File
@@ -3,6 +3,32 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.71.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-09)
### Bug Fixes
* move viewport early return above ([6a4b5c5](https://github.com/standardnotes/app/commit/6a4b5c5cdc808c2947e4fe04c5a7e1c3ce7821d0))
* potential fix for viewport height issue ([#1772](https://github.com/standardnotes/app/issues/1772)) ([cd1669f](https://github.com/standardnotes/app/commit/cd1669f56f510fe44c39f6c6d76ca6c93ee6e5ac))
## [3.71.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-08)
### Bug Fixes
* open upgrade page in new tab if user has account ([e7ca12b](https://github.com/standardnotes/app/commit/e7ca12babefc4b8867c9dc2c535a9da0d4f62a76))
# [3.71.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
### Features
* change quick settings menu layout ([#1770](https://github.com/standardnotes/app/issues/1770)) ([59db63f](https://github.com/standardnotes/app/commit/59db63f05230168b20d6b2db2eaf1a4b99c02f50))
* open purchase flow when clicking upgrade cta with no account ([#1771](https://github.com/standardnotes/app/issues/1771)) ([734b986](https://github.com/standardnotes/app/commit/734b986294380954c7eb3ceac42d76ef17b27ca1))
## [3.70.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
### Bug Fixes
* add fallback for viewport height on mobile ([#1766](https://github.com/standardnotes/app/issues/1766)) ([1e3acd5](https://github.com/standardnotes/app/commit/1e3acd50e941051636ae2c92d143c649913b3c1a))
## [3.70.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-07)
**Note:** Version bump only for package @standardnotes/web
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/web",
"version": "3.70.4",
"version": "3.71.2",
"license": "AGPL-3.0-or-later",
"main": "dist/app.js",
"author": "Standard Notes.",
+36 -13
View File
@@ -35,25 +35,28 @@ import { WebOrDesktopDevice } from './Application/Device/WebOrDesktopDevice'
import { WebApplication } from './Application/Application'
import { createRoot, Root } from 'react-dom/client'
import { ElementIds } from './Constants/ElementIDs'
import { MediaQueryBreakpoints } from './Hooks/useMediaQuery'
let keyCount = 0
const getKey = () => {
return keyCount++
}
const setViewportHeight = () => {
const currentValue = parseInt(document.documentElement.style.getPropertyValue('--viewport-height'))
let initialCorrectViewportHeight: number | null = null
export const setViewportHeightWithFallback = (isOrientationChange = false) => {
const newValue = visualViewport && visualViewport.height > 0 ? visualViewport.height : window.innerHeight
if (currentValue && !newValue) {
if (initialCorrectViewportHeight && newValue < initialCorrectViewportHeight && !isOrientationChange) {
return
}
if (!currentValue && !newValue) {
if (!newValue) {
document.documentElement.style.setProperty('--viewport-height', '100vh')
return
}
initialCorrectViewportHeight = newValue
document.documentElement.style.setProperty('--viewport-height', `${newValue}px`)
}
@@ -77,11 +80,35 @@ const startApplication: StartApplication = async function startApplication(
SNLog.onError = console.error
let root: Root
const onDestroy = () => {
if (device.environment === Environment.Desktop) {
window.removeEventListener('resize', setViewportHeight)
const isDesktop =
device.environment === Environment.Desktop ||
(matchMedia(MediaQueryBreakpoints.md).matches && matchMedia(MediaQueryBreakpoints.pointerFine))
const orientationChangeHandler = () => {
setViewportHeightWithFallback(true)
}
const resizeHandler = () => {
setViewportHeightWithFallback(false)
}
const setupViewportHeightListeners = () => {
if (!isDesktop) {
setViewportHeightWithFallback()
window.addEventListener('orientationchange', orientationChangeHandler)
window.addEventListener('resize', resizeHandler)
}
window.removeEventListener('orientationchange', setViewportHeight)
}
const removeViewportHeightListeners = () => {
if (!isDesktop) {
window.removeEventListener('orientationchange', orientationChangeHandler)
window.removeEventListener('resize', resizeHandler)
}
}
const onDestroy = () => {
removeViewportHeightListeners()
const rootElement = document.getElementById(ElementIds.RootId) as HTMLElement
root.unmount()
rootElement.remove()
@@ -96,11 +123,7 @@ const startApplication: StartApplication = async function startApplication(
disableIosTextFieldZoom()
setViewportHeight()
window.addEventListener('orientationchange', setViewportHeight)
if (device.environment === Environment.Desktop) {
window.addEventListener('resize', setViewportHeight)
}
setupViewportHeightListeners()
setDefaultMonospaceFont(device.platform)
@@ -28,6 +28,7 @@ import { ArchiveManager, AutolockService, IOService, WebAlertService, ThemeManag
import { MobileWebReceiver } from './MobileWebReceiver'
import { AndroidBackHandler } from '@/NativeMobileWeb/AndroidBackHandler'
import { PrefDefaults } from '@/Constants/PrefDefaults'
import { setViewportHeightWithFallback } from '@/App'
type WebServices = {
viewControllerManager: ViewControllerManager
@@ -233,8 +234,9 @@ export class WebApplication extends SNApplication implements WebApplicationInter
await this.lockApplicationAfterMobileEventIfApplicable()
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
async handleMobileGainingFocusEvent(): Promise<void> {}
async handleMobileGainingFocusEvent(): Promise<void> {
setViewportHeightWithFallback()
}
async handleMobileLosingFocusEvent(): Promise<void> {
if (this.protections.getMobileScreenshotPrivacyEnabled()) {
@@ -248,6 +250,8 @@ export class WebApplication extends SNApplication implements WebApplicationInter
if (this.protections.getMobileScreenshotPrivacyEnabled()) {
this.mobileDevice().hideMobileInterfaceFromScreenshots()
}
setViewportHeightWithFallback()
}
private async lockApplicationAfterMobileEventIfApplicable(): Promise<void> {
@@ -12,18 +12,6 @@ const UpgradeNow = ({ application, featuresController }: Props) => {
const shouldShowCTA = !featuresController.hasFolders
const hasAccount = application.hasAccount()
const openPlansPage = () => {
if (!window.plansUrl) {
return
}
if (application.isNativeMobileWeb()) {
application.mobileDevice().openUrl(window.plansUrl)
} else {
window.location.assign(window.plansUrl)
}
}
return shouldShowCTA ? (
<div className="flex h-full items-center px-2">
<button
@@ -34,7 +22,7 @@ const UpgradeNow = ({ application, featuresController }: Props) => {
return
}
openPlansPage()
application.getViewControllerManager().purchaseFlowController.openPurchaseFlow()
}}
>
Upgrade now
@@ -25,7 +25,8 @@ export const loadPurchaseFlowUrl = async (application: WebApplication): Promise<
if (application.isNativeMobileWeb()) {
application.mobileDevice().openUrl(finalUrl)
} else {
window.location.assign(finalUrl)
const windowProxy = window.open('', '_blank')
;(windowProxy as WindowProxy).location = finalUrl
}
return true
@@ -6,6 +6,7 @@ import { FunctionComponent } from 'react'
import CreateAccount from './Panes/CreateAccount'
import SignIn from './Panes/SignIn'
import { SNLogoFull } from '@standardnotes/icons'
import Icon from '../Icon/Icon'
type PaneSelectorProps = {
currentPane: PurchaseFlowPane
@@ -36,6 +37,14 @@ const PurchaseFlowView: FunctionComponent<PurchaseFlowViewProps> = ({ viewContro
<div className="absolute top-0 left-0 z-purchase-flow flex h-full w-full items-center justify-center overflow-hidden bg-passive-super-light">
<div className="relative w-fit">
<div className="rounded-0 relative mb-4 w-full border border-solid border-border bg-default px-8 py-8 md:rounded md:p-12">
<button
className="absolute top-4 right-4 rounded-full p-1 hover:bg-info-backdrop"
onClick={() => {
viewControllerManager.purchaseFlowController.closePurchaseFlow()
}}
>
<Icon type="close" className="text-neutral" />
</button>
<SNLogoFull className="mb-5" />
<PurchaseFlowPaneSelector
currentPane={currentPane}
@@ -1,10 +1,6 @@
import { WebApplication } from '@/Application/Application'
import { FeatureStatus, FeatureIdentifier } from '@standardnotes/snjs'
import { FunctionComponent, MouseEventHandler, useCallback } from 'react'
import Icon from '@/Components/Icon/Icon'
import { usePremiumModal } from '@/Hooks/usePremiumModal'
import Switch from '@/Components/Switch/Switch'
import { PremiumFeatureIconClass, PremiumFeatureIconName } from '../Icon/PremiumFeatureIcon'
import { isMobileScreen } from '@/Utils'
type Props = {
@@ -15,21 +11,14 @@ type Props = {
}
const FocusModeSwitch: FunctionComponent<Props> = ({ application, onToggle, onClose, isEnabled }) => {
const premiumModal = usePremiumModal()
const isEntitled = application.features.getFeatureStatus(FeatureIdentifier.FocusMode) === FeatureStatus.Entitled
const toggle: MouseEventHandler = useCallback(
(e) => {
e.preventDefault()
if (isEntitled) {
onToggle(!isEnabled)
onClose()
} else {
premiumModal.activate('Focused Writing')
}
onToggle(!isEnabled)
onClose()
},
[isEntitled, onToggle, isEnabled, onClose, premiumModal],
[onToggle, isEnabled, onClose],
)
return (
@@ -39,17 +28,8 @@ const FocusModeSwitch: FunctionComponent<Props> = ({ application, onToggle, onCl
onClick={toggle}
disabled={application.isNativeMobileWeb() || isMobileScreen()}
>
<div className="flex items-center">
<Icon type="menu-close" className="mr-2 text-neutral group-disabled:text-passive-2" />
Focused Writing
</div>
{isEntitled ? (
<Switch className="px-0" checked={isEnabled} />
) : (
<div title="Premium feature">
<Icon type={PremiumFeatureIconName} className={PremiumFeatureIconClass} />
</div>
)}
<div className="flex items-center">Focused Writing</div>
<Switch className="px-0" checked={isEnabled} />
</button>
</>
)
@@ -4,7 +4,6 @@ import { ApplicationEvent, PrefKey } from '@standardnotes/snjs'
import MenuItem from '../Menu/MenuItem'
import { MenuItemType } from '../Menu/MenuItemType'
import { PANEL_NAME_NAVIGATION, PANEL_NAME_NOTES } from '@/Constants/Constants'
import HorizontalSeparator from '../Shared/HorizontalSeparator'
import { PrefDefaults } from '@/Constants/PrefDefaults'
type Props = {
@@ -55,8 +54,6 @@ const PanelSettingsSection = ({ application }: Props) => {
return (
<div className="hidden text-sm md:block pointer-coarse:md-only:hidden pointer-coarse:lg-only:hidden">
<HorizontalSeparator classes="my-2" />
<div className="my-1 px-3 text-sm font-semibold uppercase text-text">Panel Settings</div>
<MenuItem
type={MenuItemType.SwitchButton}
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
@@ -71,7 +68,7 @@ const PanelSettingsSection = ({ application }: Props) => {
checked={currentItemsPanelWidth > WidthForCollapsedPanel}
onChange={toggleItemsListPanel}
>
Show items list panel
Show list panel
</MenuItem>
</div>
)
@@ -70,8 +70,6 @@ const QuickSettingsMenu: FunctionComponent<MenuProps> = ({ application, quickSet
const prefsButtonRef = useRef<HTMLButtonElement>(null)
const defaultThemeButtonRef = useRef<HTMLButtonElement>(null)
const mainRef = useRef<HTMLDivElement>(null)
useEffect(() => {
toggleFocusMode(focusModeEnabled)
}, [focusModeEnabled])
@@ -176,8 +174,29 @@ const QuickSettingsMenu: FunctionComponent<MenuProps> = ({ application, quickSet
}, [application, isDarkModeOn, deactivateAnyNonLayerableTheme])
return (
<div ref={mainRef}>
<div className="my-1 px-3 text-sm font-semibold uppercase text-text">Themes</div>
<div>
{toggleableComponents.length > 0 && (
<>
<div className="my-1 px-3 text-sm font-semibold uppercase text-text">Tools</div>
{toggleableComponents.map((component) => (
<button
className="flex w-full cursor-pointer items-center justify-between border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-sm"
onClick={() => {
toggleComponent(component)
}}
key={component.uuid}
>
<div className="flex items-center">
<Icon type="window" className="mr-2 text-neutral" />
{component.displayName}
</div>
<Switch checked={component.active} className="px-0" />
</button>
))}
<HorizontalSeparator classes="my-2" />
</>
)}
<div className="my-1 px-3 text-sm font-semibold uppercase text-text">Appearance</div>
<button
className="flex w-full cursor-pointer items-center border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-sm"
onClick={toggleDefaultTheme}
@@ -196,23 +215,6 @@ const QuickSettingsMenu: FunctionComponent<MenuProps> = ({ application, quickSet
{themes.map((theme) => (
<ThemesMenuButton item={theme} application={application} key={theme.component?.uuid ?? theme.identifier} />
))}
<HorizontalSeparator classes="my-2" />
<div className="my-1 px-3 text-sm font-semibold uppercase text-text">Tools</div>
{toggleableComponents.map((component) => (
<button
className="flex w-full cursor-pointer items-center justify-between border-0 bg-transparent px-3 py-1.5 text-left text-mobile-menu-item text-text hover:bg-contrast hover:text-foreground focus:bg-info-backdrop focus:shadow-none md:text-sm"
onClick={() => {
toggleComponent(component)
}}
key={component.uuid}
>
<div className="flex items-center">
<Icon type="window" className="mr-2 text-neutral" />
{component.displayName}
</div>
<Switch checked={component.active} className="px-0" />
</button>
))}
<FocusModeSwitch
application={application}
onToggle={setFocusModeEnabled}
@@ -58,10 +58,10 @@ const ThemesMenuButton: FunctionComponent<Props> = ({ application, item }) => {
{item.component?.isLayerable() ? (
<>
<div className="flex items-center">
<Switch className="mr-2 px-0" checked={item.component?.active} />
{!canActivateTheme && <Icon type={PremiumFeatureIconName} className={PremiumFeatureIconClass} />}
{item.name}
</div>
{!canActivateTheme && <Icon type={PremiumFeatureIconName} className={PremiumFeatureIconClass} />}
<Switch className="px-0" checked={item.component?.active} />
</>
) : (
<>
@@ -7,6 +7,7 @@ export const MediaQueryBreakpoints = {
lg: '(min-width: 1024px)',
xl: '(min-width: 1280px)',
'2xl': '(min-width: 1536px)',
pointerFine: '(pointer: fine)',
} as const
export const useMediaQuery = (mediaQuery: string) => {
+2
View File
@@ -34,6 +34,8 @@
@media screen and (max-width: 768px) {
--sn-stylekit-font-size-editor: 1rem;
}
--viewport-height: 100vh;
}
html {