diff --git a/.prettierignore b/.prettierignore
index 6fd05c848..6b4f155a0 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,6 +1,14 @@
+# all
build
coverage
node_modules
dist
-native/
-public/an.js
\ No newline at end of file
+
+# mobile
+apps/mobile/native/
+
+# web
+apps/web/public/an.js
+
+# editor
+packages/editor/styles/
\ No newline at end of file
diff --git a/apps/mobile/.eslintrc.js b/apps/mobile/.eslintrc.js
index 831ede52e..c6a70e997 100644
--- a/apps/mobile/.eslintrc.js
+++ b/apps/mobile/.eslintrc.js
@@ -1,16 +1,16 @@
module.exports = {
- parser: '@typescript-eslint/parser',
+ parser: "@typescript-eslint/parser",
env: {
browser: true,
es2021: true,
- 'react-native/react-native': true
+ "react-native/react-native": true
},
extends: [
- 'eslint:recommended',
- 'plugin:react/recommended',
- 'plugin:prettier/recommended',
- 'plugin:@typescript-eslint/eslint-recommended',
- 'plugin:@typescript-eslint/recommended'
+ "eslint:recommended",
+ "plugin:react/recommended",
+ "plugin:prettier/recommended",
+ "plugin:@typescript-eslint/eslint-recommended",
+ "plugin:@typescript-eslint/recommended"
],
parserOptions: {
ecmaFeatures: {
@@ -18,22 +18,31 @@ module.exports = {
},
ecmaVersion: 12,
es6: true,
- sourceType: 'module'
+ sourceType: "module"
},
- plugins: ['react', 'react-native', 'prettier', 'unused-imports', '@typescript-eslint'],
+ plugins: [
+ "react",
+ "react-native",
+ "prettier",
+ "unused-imports",
+ "@typescript-eslint"
+ ],
rules: {
- 'react/display-name': 0,
- 'no-unused-vars': 'off',
- 'react/no-unescaped-entities': 'off',
- 'unused-imports/no-unused-vars': 'off',
- '@typescript-eslint/ban-ts-comment': 'off',
- '@typescript-eslint/no-unused-vars': 'off',
- 'prefer-const': 'off',
- 'no-empty': 'off',
- 'react/prop-types': 0,
- 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx', 'ts', 'tsx'] }],
- 'prettier/prettier': [
- 'error',
+ "react/display-name": 0,
+ "no-unused-vars": "off",
+ "react/no-unescaped-entities": "off",
+ "unused-imports/no-unused-vars": "off",
+ "@typescript-eslint/ban-ts-comment": "off",
+ "@typescript-eslint/no-unused-vars": "off",
+ "prefer-const": "off",
+ "no-empty": "off",
+ "react/prop-types": 0,
+ "react/jsx-filename-extension": [
+ 1,
+ { extensions: [".js", ".jsx", "ts", "tsx"] }
+ ],
+ "prettier/prettier": [
+ "error",
{},
{
usePrettierrc: true
diff --git a/apps/mobile/.github/workflows/android-public-release.yml b/apps/mobile/.github/workflows/android-public-release.yml
index 4cc17217c..de27c8485 100644
--- a/apps/mobile/.github/workflows/android-public-release.yml
+++ b/apps/mobile/.github/workflows/android-public-release.yml
@@ -28,13 +28,13 @@ jobs:
- uses: actions/setup-node@master
with:
- node-version: '16'
+ node-version: "16"
- name: Use specific Java version for the builds
uses: joschi/setup-jdk@v2
with:
- java-version: '11'
- architecture: 'x64'
+ java-version: "11"
+ architecture: "x64"
- name: Install node modules
run: |
diff --git a/apps/mobile/.github/workflows/android-release.yml b/apps/mobile/.github/workflows/android-release.yml
index 8946e4211..a4057d7b3 100644
--- a/apps/mobile/.github/workflows/android-release.yml
+++ b/apps/mobile/.github/workflows/android-release.yml
@@ -28,13 +28,13 @@ jobs:
- uses: actions/setup-node@master
with:
- node-version: '16'
+ node-version: "16"
- name: Use specific Java version for the builds
uses: joschi/setup-jdk@v2
with:
- java-version: '11'
- architecture: 'x64'
+ java-version: "11"
+ architecture: "x64"
- name: Install node modules
run: |
diff --git a/apps/mobile/.prettierrc.js b/apps/mobile/.prettierrc.js
deleted file mode 100644
index 4a66763d4..000000000
--- a/apps/mobile/.prettierrc.js
+++ /dev/null
@@ -1,13 +0,0 @@
-module.exports = {
- arrowParens: 'avoid',
- bracketSpacing: true,
- jsxBracketSameLine: false,
- jsxSingleQuote: false,
- quoteProps: 'as-needed',
- singleQuote: true,
- semi: true,
- printWidth: 100,
- useTabs: false,
- tabWidth: 2,
- trailingComma: 'none'
-};
diff --git a/apps/mobile/.vscode/launch.json b/apps/mobile/.vscode/launch.json
index 7a623a22a..1a48c7f0c 100644
--- a/apps/mobile/.vscode/launch.json
+++ b/apps/mobile/.vscode/launch.json
@@ -4,8 +4,6 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
-
-
{
"name": "Debug Android",
"cwd": "${workspaceFolder}",
@@ -27,4 +25,4 @@
"request": "attach"
}
]
-}
\ No newline at end of file
+}
diff --git a/apps/mobile/.watchmanconfig b/apps/mobile/.watchmanconfig
index 9e26dfeeb..0967ef424 100644
--- a/apps/mobile/.watchmanconfig
+++ b/apps/mobile/.watchmanconfig
@@ -1 +1 @@
-{}
\ No newline at end of file
+{}
diff --git a/apps/mobile/__tests__/App-test.js b/apps/mobile/__tests__/App-test.js
index a98d92c8a..8fd0553bf 100644
--- a/apps/mobile/__tests__/App-test.js
+++ b/apps/mobile/__tests__/App-test.js
@@ -2,21 +2,21 @@
* @format
*/
-import React from 'react';
-import 'react-native';
+import React from "react";
+import "react-native";
// Note: test renderer must be required after react-native.
-import renderer from 'react-test-renderer';
-import Heading from '../app/components/ui/typography/heading';
-import Paragraph from '../app/components/ui/typography/paragraph';
+import renderer from "react-test-renderer";
+import Heading from "../app/components/ui/typography/heading";
+import Paragraph from "../app/components/ui/typography/paragraph";
-it('Heading renders correctly', done => {
+it("Heading renders correctly", (done) => {
let instance = renderer.create(Heading);
- expect(instance.root.props.children).toBe('Heading');
+ expect(instance.root.props.children).toBe("Heading");
done();
});
-it('Paragraph renders correctly', done => {
+it("Paragraph renders correctly", (done) => {
let instance = renderer.create(Paragraph);
- expect(instance.root.props.children).toBe('Paragraph');
+ expect(instance.root.props.children).toBe("Paragraph");
done();
});
diff --git a/apps/mobile/app/app.js b/apps/mobile/app/app.js
index 9bed15ffc..0e90d6544 100644
--- a/apps/mobile/app/app.js
+++ b/apps/mobile/app/app.js
@@ -1,14 +1,14 @@
-import React, { useEffect } from 'react';
-import { GestureHandlerRootView } from 'react-native-gesture-handler';
-import { SafeAreaProvider } from 'react-native-safe-area-context';
-import { withErrorBoundry } from './components/exception-handler';
-import Launcher from './components/launcher';
-import { ApplicationHolder } from './navigation';
-import Notifications from './services/notifications';
-import SettingsService from './services/settings';
-import { TipManager } from './services/tip-manager';
-import { useUserStore } from './stores/use-user-store';
-import { useAppEvents } from './hooks/use-app-events';
+import React, { useEffect } from "react";
+import { GestureHandlerRootView } from "react-native-gesture-handler";
+import { SafeAreaProvider } from "react-native-safe-area-context";
+import { withErrorBoundry } from "./components/exception-handler";
+import Launcher from "./components/launcher";
+import { ApplicationHolder } from "./navigation";
+import Notifications from "./services/notifications";
+import SettingsService from "./services/settings";
+import { TipManager } from "./services/tip-manager";
+import { useUserStore } from "./stores/use-user-store";
+import { useAppEvents } from "./hooks/use-app-events";
SettingsService.init();
SettingsService.checkOrientation();
@@ -16,7 +16,7 @@ const App = () => {
useAppEvents();
useEffect(() => {
let { appLockMode } = SettingsService.get();
- if (appLockMode && appLockMode !== 'none') {
+ if (appLockMode && appLockMode !== "none") {
useUserStore.getState().setVerifyUser(true);
}
setTimeout(() => {
@@ -39,4 +39,4 @@ const App = () => {
);
};
-export default withErrorBoundry(App, 'App');
+export default withErrorBoundry(App, "App");
diff --git a/apps/mobile/app/assets/images/assets.js b/apps/mobile/app/assets/images/assets.js
index f78210ad6..0a66eec9b 100644
--- a/apps/mobile/app/assets/images/assets.js
+++ b/apps/mobile/app/assets/images/assets.js
@@ -1,12 +1,12 @@
-export const LAUNCH_ROCKET = color =>
+export const LAUNCH_ROCKET = (color) =>
``;
-export const COMMUNITY_SVG = color => `
+export const COMMUNITY_SVG = (color) => `
`;
export const SUPPORT_SVG = () =>
``;
-export const WELCOME_SVG = color =>
+export const WELCOME_SVG = (color) =>
``;
diff --git a/apps/mobile/app/common/analytics/index.js b/apps/mobile/app/common/analytics/index.js
index 7fa40c8c2..e908ad7ee 100644
--- a/apps/mobile/app/common/analytics/index.js
+++ b/apps/mobile/app/common/analytics/index.js
@@ -1,12 +1,12 @@
-import { Platform } from 'react-native';
-import { MMKV } from '../database/mmkv';
-import { useSettingStore } from '../../stores/use-setting-store';
+import { Platform } from "react-native";
+import { MMKV } from "../database/mmkv";
+import { useSettingStore } from "../../stores/use-setting-store";
const WEBSITE_ID = `3c6890ce-8410-49d5-8831-15fb2eb28a21`;
const baseUrl = `https://analytics.streetwriters.co/api/collect`;
const UA =
- Platform.OS === 'ios'
+ Platform.OS === "ios"
? `Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1`
: `
Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36`;
@@ -19,37 +19,37 @@ Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHT
*/
async function canUpdateAnalytics(route, conditions = []) {
if (!useSettingStore?.getState()?.settings?.telemetry) return false;
- let eventsList = MMKV.getString('notesnookUserEvents');
+ let eventsList = MMKV.getString("notesnookUserEvents");
if (eventsList) {
eventsList = JSON.parse(eventsList);
}
if (eventsList && eventsList[route]) {
- console.log('analytics: event already sent', route);
+ console.log("analytics: event already sent", route);
return false;
}
- if (route !== '/welcome') {
+ if (route !== "/welcome") {
for (let cond of conditions) {
if (!eventsList || !eventsList[cond]) {
- console.log('analytics: conditions not met for event', route, cond);
+ console.log("analytics: conditions not met for event", route, cond);
return false;
}
}
}
- console.log('analytics: will send event', route);
+ console.log("analytics: will send event", route);
return true;
}
async function saveAnalytics(route, value = true) {
- let eventsList = MMKV.getString('notesnookUserEvents');
+ let eventsList = MMKV.getString("notesnookUserEvents");
if (eventsList) {
eventsList = JSON.parse(eventsList);
} else {
eventsList = {};
}
eventsList[route] = value;
- MMKV.setString('notesnookUserEvents', JSON.stringify(eventsList));
+ MMKV.setString("notesnookUserEvents", JSON.stringify(eventsList));
}
/**
@@ -61,7 +61,12 @@ async function saveAnalytics(route, value = true) {
* @returns
*/
-async function pageView(route, prevRoute = '', conditions = ['/welcome'], once = true) {
+async function pageView(
+ route,
+ prevRoute = "",
+ conditions = ["/welcome"],
+ once = true
+) {
if (__DEV__) return;
if (!(await canUpdateAnalytics(route, conditions)) && once) return;
let body = {
@@ -70,22 +75,22 @@ async function pageView(route, prevRoute = '', conditions = ['/welcome'], once =
url: `notesnook-${Platform.OS}${prevRoute}${route}`,
referrer: `https://notesnook.com/notesnook-${Platform.OS}${prevRoute}`,
hostname: `notesnook-${Platform.OS}`,
- language: 'en-US',
- screen: '1920x1080'
+ language: "en-US",
+ screen: "1920x1080"
},
- type: 'pageview'
+ type: "pageview"
};
try {
let response = await fetch(baseUrl, {
- method: 'POST',
+ method: "POST",
headers: {
- 'Content-Type': 'application/json',
- 'User-Agent': UA
+ "Content-Type": "application/json",
+ "User-Agent": UA
},
body: JSON.stringify(body)
});
- console.log('analytics: event sent', route);
+ console.log("analytics: event sent", route);
await saveAnalytics(route);
return await response.text();
} catch (e) {
@@ -99,22 +104,22 @@ async function sendEvent(type, value, once = true) {
let body = {
payload: {
website: WEBSITE_ID,
- url: '/',
+ url: "/",
event_type: type,
event_value: value,
- hostname: 'notesnook-android-app',
- language: 'en-US',
- screen: '1920x1080'
+ hostname: "notesnook-android-app",
+ language: "en-US",
+ screen: "1920x1080"
},
- type: 'event'
+ type: "event"
};
try {
let response = await fetch(baseUrl, {
- method: 'POST',
+ method: "POST",
headers: {
- 'Content-Type': 'application/json',
- 'User-Agent': UA
+ "Content-Type": "application/json",
+ "User-Agent": UA
},
body: JSON.stringify(body)
});
diff --git a/apps/mobile/app/common/database/encryption.js b/apps/mobile/app/common/database/encryption.js
index 9f8e7bf92..f93c64b9b 100644
--- a/apps/mobile/app/common/database/encryption.js
+++ b/apps/mobile/app/common/database/encryption.js
@@ -1,8 +1,8 @@
-import { Platform } from 'react-native';
-import 'react-native-get-random-values';
-import * as Keychain from 'react-native-keychain';
-import { generateSecureRandom } from 'react-native-securerandom';
-import Sodium from 'react-native-sodium';
+import { Platform } from "react-native";
+import "react-native-get-random-values";
+import * as Keychain from "react-native-keychain";
+import { generateSecureRandom } from "react-native-securerandom";
+import Sodium from "react-native-sodium";
const KEYSTORE_CONFIG = Platform.select({
ios: {
@@ -14,15 +14,23 @@ const KEYSTORE_CONFIG = Platform.select({
export async function deriveCryptoKey(name, data) {
try {
let credentials = await Sodium.deriveKey(data.password, data.salt);
- await Keychain.setInternetCredentials('notesnook', name, credentials.key, KEYSTORE_CONFIG);
+ await Keychain.setInternetCredentials(
+ "notesnook",
+ name,
+ credentials.key,
+ KEYSTORE_CONFIG
+ );
return credentials.key;
} catch (e) {}
}
export async function getCryptoKey(name) {
try {
- if (await Keychain.hasInternetCredentials('notesnook')) {
- let credentials = await Keychain.getInternetCredentials('notesnook', KEYSTORE_CONFIG);
+ if (await Keychain.hasInternetCredentials("notesnook")) {
+ let credentials = await Keychain.getInternetCredentials(
+ "notesnook",
+ KEYSTORE_CONFIG
+ );
return credentials.password;
} else {
return null;
@@ -32,7 +40,7 @@ export async function getCryptoKey(name) {
export async function removeCryptoKey(name) {
try {
- let result = await Keychain.resetInternetCredentials('notesnook');
+ let result = await Keychain.resetInternetCredentials("notesnook");
return result;
} catch (e) {}
}
@@ -51,7 +59,7 @@ export async function generateCryptoKey(password, salt) {
let credentials = await Sodium.deriveKey(password, salt || null);
return credentials;
} catch (e) {
- console.log('generateCryptoKey: ', e);
+ console.log("generateCryptoKey: ", e);
}
}
@@ -61,30 +69,32 @@ export function getAlgorithm(base64Variant) {
export async function decrypt(password, data) {
if (!password.password && !password.key) return undefined;
- if (password.password && password.password === '' && !password.key) return undefined;
+ if (password.password && password.password === "" && !password.key)
+ return undefined;
let _data = { ...data };
- _data.output = 'plain';
+ _data.output = "plain";
return await Sodium.decrypt(password, _data);
}
export function parseAlgorithm(alg) {
if (!alg) return {};
- const [enc, kdf, compressed, compressionAlg, base64variant] = alg.split('-');
+ const [enc, kdf, compressed, compressionAlg, base64variant] = alg.split("-");
return {
encryptionAlgorithm: enc,
kdfAlgorithm: kdf,
compressionAlgorithm: compressionAlg,
- isCompress: compressed === '1',
+ isCompress: compressed === "1",
base64_variant: base64variant
};
}
export async function encrypt(password, data) {
if (!password.password && !password.key) return undefined;
- if (password.password && password.password === '' && !password.key) return undefined;
+ if (password.password && password.password === "" && !password.key)
+ return undefined;
let message = {
- type: 'plain',
+ type: "plain",
data: data
};
let result = await Sodium.encrypt(password, message);
diff --git a/apps/mobile/app/common/database/index.js b/apps/mobile/app/common/database/index.js
index 3a426d612..fbd6c8db7 100644
--- a/apps/mobile/app/common/database/index.js
+++ b/apps/mobile/app/common/database/index.js
@@ -1,12 +1,17 @@
-import Database from '@streetwriters/notesnook-core/api/index';
-import { initalize, logger as dbLogger } from '@streetwriters/notesnook-core/logger';
-import { Platform } from 'react-native';
-import { MMKVLoader } from 'react-native-mmkv-storage';
-import filesystem from '../filesystem';
-import EventSource from '../../utils/sse/even-source-ios';
-import AndroidEventSource from '../../utils/sse/event-source';
-import Storage, { KV } from './storage';
-const LoggerStorage = new MMKVLoader().withInstanceID('notesnook_logs').initialize();
+import Database from "@streetwriters/notesnook-core/api/index";
+import {
+ initalize,
+ logger as dbLogger
+} from "@streetwriters/notesnook-core/logger";
+import { Platform } from "react-native";
+import { MMKVLoader } from "react-native-mmkv-storage";
+import filesystem from "../filesystem";
+import EventSource from "../../utils/sse/even-source-ios";
+import AndroidEventSource from "../../utils/sse/event-source";
+import Storage, { KV } from "./storage";
+const LoggerStorage = new MMKVLoader()
+ .withInstanceID("notesnook_logs")
+ .initialize();
console.log(LoggerStorage);
initalize(new KV(LoggerStorage));
export const DatabaseLogger = dbLogger;
@@ -16,18 +21,18 @@ export const DatabaseLogger = dbLogger;
*/
export var db = new Database(
Storage,
- Platform.OS === 'ios' ? EventSource : AndroidEventSource,
+ Platform.OS === "ios" ? EventSource : AndroidEventSource,
filesystem
);
db.host(
__DEV__
? {
- API_HOST: 'https://api.notesnook.com',
- AUTH_HOST: 'https://auth.streetwriters.co',
- SSE_HOST: 'https://events.streetwriters.co',
- SUBSCRIPTIONS_HOST: 'https://subscriptions.streetwriters.co',
- ISSUES_HOST: 'https://issues.streetwriters.co'
+ API_HOST: "https://api.notesnook.com",
+ AUTH_HOST: "https://auth.streetwriters.co",
+ SSE_HOST: "https://events.streetwriters.co",
+ SUBSCRIPTIONS_HOST: "https://subscriptions.streetwriters.co",
+ ISSUES_HOST: "https://issues.streetwriters.co"
// API_HOST: 'http://192.168.10.29:5264',
// AUTH_HOST: 'http://192.168.10.29:8264',
// SSE_HOST: 'http://192.168.10.29:7264',
@@ -35,11 +40,11 @@ db.host(
// ISSUES_HOST: 'http://192.168.10.29:2624'
}
: {
- API_HOST: 'https://api.notesnook.com',
- AUTH_HOST: 'https://auth.streetwriters.co',
- SSE_HOST: 'https://events.streetwriters.co',
- SUBSCRIPTIONS_HOST: 'https://subscriptions.streetwriters.co',
- ISSUES_HOST: 'https://issues.streetwriters.co'
+ API_HOST: "https://api.notesnook.com",
+ AUTH_HOST: "https://auth.streetwriters.co",
+ SSE_HOST: "https://events.streetwriters.co",
+ SUBSCRIPTIONS_HOST: "https://subscriptions.streetwriters.co",
+ ISSUES_HOST: "https://issues.streetwriters.co"
}
);
diff --git a/apps/mobile/app/common/database/mmkv.js b/apps/mobile/app/common/database/mmkv.js
index 5b3b4a933..347cd765a 100644
--- a/apps/mobile/app/common/database/mmkv.js
+++ b/apps/mobile/app/common/database/mmkv.js
@@ -1,8 +1,10 @@
-import { Platform } from 'react-native';
-import MMKVStorage, { ProcessingModes } from 'react-native-mmkv-storage';
+import { Platform } from "react-native";
+import MMKVStorage, { ProcessingModes } from "react-native-mmkv-storage";
export const MMKV = new MMKVStorage.Loader()
.setProcessingMode(
- Platform.OS === 'ios' ? ProcessingModes.MULTI_PROCESS : ProcessingModes.SINGLE_PROCESS
+ Platform.OS === "ios"
+ ? ProcessingModes.MULTI_PROCESS
+ : ProcessingModes.SINGLE_PROCESS
)
.initialize();
diff --git a/apps/mobile/app/common/database/storage.js b/apps/mobile/app/common/database/storage.js
index a73d5b1a6..97c114910 100644
--- a/apps/mobile/app/common/database/storage.js
+++ b/apps/mobile/app/common/database/storage.js
@@ -1,5 +1,5 @@
-import { Platform } from 'react-native';
-import RNFetchBlob from 'rn-fetch-blob';
+import { Platform } from "react-native";
+import RNFetchBlob from "rn-fetch-blob";
import {
decrypt,
deriveCryptoKey,
@@ -9,8 +9,8 @@ import {
getRandomBytes,
hash,
removeCryptoKey
-} from './encryption';
-import { MMKV } from './mmkv';
+} from "./encryption";
+import { MMKV } from "./mmkv";
export class KV {
storage = null;
@@ -30,7 +30,10 @@ export class KV {
}
async write(key, data) {
- this.storage.setString(key, typeof data === 'string' ? data : JSON.stringify(data));
+ this.storage.setString(
+ key,
+ typeof data === "string" ? data : JSON.stringify(data)
+ );
return true;
}
@@ -64,12 +67,12 @@ export class KV {
async getAllKeys() {
let keys = (await this.storage.indexer.getKeys()) || [];
keys = keys.filter(
- k =>
- k !== 'stringIndex' &&
- k !== 'boolIndex' &&
- k !== 'mapIndex' &&
- k !== 'arrayIndex' &&
- k !== 'numberIndex' &&
+ (k) =>
+ k !== "stringIndex" &&
+ k !== "boolIndex" &&
+ k !== "mapIndex" &&
+ k !== "arrayIndex" &&
+ k !== "numberIndex" &&
k !== this.storage.instanceID
);
return keys;
@@ -79,14 +82,14 @@ export class KV {
const DefaultStorage = new KV(MMKV);
async function requestPermission() {
- if (Platform.OS === 'ios') return true;
+ if (Platform.OS === "ios") return true;
return true;
}
async function checkAndCreateDir(path) {
let dir =
- Platform.OS === 'ios'
+ Platform.OS === "ios"
? RNFetchBlob.fs.dirs.DocumentDir + path
- : RNFetchBlob.fs.dirs.SDCardDir + '/Notesnook/' + path;
+ : RNFetchBlob.fs.dirs.SDCardDir + "/Notesnook/" + path;
try {
let exists = await RNFetchBlob.fs.exists(dir);
@@ -102,10 +105,10 @@ async function checkAndCreateDir(path) {
}
export default {
- read: key => DefaultStorage.read(key),
+ read: (key) => DefaultStorage.read(key),
write: (key, value) => DefaultStorage.write(key, value),
- readMulti: keys => DefaultStorage.readMulti(keys),
- remove: key => DefaultStorage.remove(key),
+ readMulti: (keys) => DefaultStorage.readMulti(keys),
+ remove: (key) => DefaultStorage.remove(key),
clear: () => DefaultStorage.clear(),
getAllKeys: () => DefaultStorage.getAllKeys(),
encrypt,
diff --git a/apps/mobile/app/common/filesystem/download.js b/apps/mobile/app/common/filesystem/download.js
index 211516c0d..b441e54b6 100644
--- a/apps/mobile/app/common/filesystem/download.js
+++ b/apps/mobile/app/common/filesystem/download.js
@@ -1,48 +1,51 @@
-import React from 'react';
-import { Platform } from 'react-native';
-import * as ScopedStorage from 'react-native-scoped-storage';
-import Sodium from 'react-native-sodium';
-import RNFetchBlob from 'rn-fetch-blob';
-import { ShareComponent } from '../../components/sheets/export-notes/share';
-import { useAttachmentStore } from '../../stores/use-attachment-store';
-import { presentSheet, ToastEvent } from '../../services/event-manager';
-import { db } from '../database';
-import Storage from '../database/storage';
-import { cacheDir, fileCheck } from './utils';
-import hosts from '@streetwriters/notesnook-core/utils/constants';
-import NetInfo from '@react-native-community/netinfo';
+import React from "react";
+import { Platform } from "react-native";
+import * as ScopedStorage from "react-native-scoped-storage";
+import Sodium from "react-native-sodium";
+import RNFetchBlob from "rn-fetch-blob";
+import { ShareComponent } from "../../components/sheets/export-notes/share";
+import { useAttachmentStore } from "../../stores/use-attachment-store";
+import { presentSheet, ToastEvent } from "../../services/event-manager";
+import { db } from "../database";
+import Storage from "../database/storage";
+import { cacheDir, fileCheck } from "./utils";
+import hosts from "@streetwriters/notesnook-core/utils/constants";
+import NetInfo from "@react-native-community/netinfo";
export async function downloadFile(filename, data, cancelToken) {
if (!data) return false;
let { url, headers } = data;
- console.log('downloading file: ', filename, url);
+ console.log("downloading file: ", filename, url);
let path = `${cacheDir}/${filename}`;
try {
let exists = await RNFetchBlob.fs.exists(path);
if (exists) {
- console.log('file is downloaded');
+ console.log("file is downloaded");
return true;
}
let res = await fetch(url, {
- method: 'GET',
+ method: "GET",
headers
});
- if (!res.ok) throw new Error(`${res.status}: Unable to resolve download url`);
+ if (!res.ok)
+ throw new Error(`${res.status}: Unable to resolve download url`);
const downloadUrl = await res.text();
- if (!downloadUrl) throw new Error('Unable to resolve download url');
+ if (!downloadUrl) throw new Error("Unable to resolve download url");
let totalSize = 0;
let request = RNFetchBlob.config({
path: path,
IOSBackgroundTask: true
})
- .fetch('GET', downloadUrl, null)
+ .fetch("GET", downloadUrl, null)
.progress((recieved, total) => {
- useAttachmentStore.getState().setProgress(0, total, filename, recieved, 'download');
+ useAttachmentStore
+ .getState()
+ .setProgress(0, total, filename, recieved, "download");
totalSize = total;
- console.log('downloading: ', recieved, total);
+ console.log("downloading: ", recieved, total);
});
cancelToken.cancel = request.cancel;
@@ -53,21 +56,21 @@ export async function downloadFile(filename, data, cancelToken) {
return status >= 200 && status < 300;
} catch (e) {
ToastEvent.show({
- heading: 'Error downloading file',
+ heading: "Error downloading file",
message: e.message,
- type: 'error',
- context: 'global'
+ type: "error",
+ context: "global"
});
ToastEvent.show({
- heading: 'Error downloading file',
+ heading: "Error downloading file",
message: e.message,
- type: 'error',
- context: 'local'
+ type: "error",
+ context: "local"
});
useAttachmentStore.getState().remove(filename);
RNFetchBlob.fs.unlink(path).catch(console.log);
- console.log('download file error: ', e, url, headers);
+ console.log("download file error: ", e, url, headers);
return false;
}
}
@@ -75,24 +78,30 @@ export async function downloadFile(filename, data, cancelToken) {
export async function downloadAttachment(hash, global = true) {
let attachment = db.attachments.attachment(hash);
if (!attachment) {
- console.log('attachment not found');
+ console.log("attachment not found");
return;
}
let folder = {};
- if (Platform.OS === 'android') {
+ if (Platform.OS === "android") {
folder = await ScopedStorage.openDocumentTree();
if (!folder) return;
} else {
- folder.uri = await Storage.checkAndCreateDir('/downloads/');
+ folder.uri = await Storage.checkAndCreateDir("/downloads/");
}
try {
- await db.fs.downloadFile(attachment.metadata.hash, attachment.metadata.hash);
- if (!(await RNFetchBlob.fs.exists(`${cacheDir}/${attachment.metadata.hash}`))) return;
+ await db.fs.downloadFile(
+ attachment.metadata.hash,
+ attachment.metadata.hash
+ );
+ if (
+ !(await RNFetchBlob.fs.exists(`${cacheDir}/${attachment.metadata.hash}`))
+ )
+ return;
let key = await db.attachments.decryptKey(attachment.key);
- console.log('attachment key', key);
+ console.log("attachment key", key);
let info = {
iv: attachment.iv,
salt: attachment.salt,
@@ -108,37 +117,48 @@ export async function downloadAttachment(hash, global = true) {
let fileUri = await Sodium.decryptFile(key, info, false);
ToastEvent.show({
- heading: 'Download successful',
- message: attachment.metadata.filename + ' downloaded',
- type: 'success'
+ heading: "Download successful",
+ message: attachment.metadata.filename + " downloaded",
+ type: "success"
});
if (attachment.dateUploaded) {
- console.log('Deleting attachment after download', attachment.dateUploaded);
+ console.log(
+ "Deleting attachment after download",
+ attachment.dateUploaded
+ );
RNFetchBlob.fs
.unlink(RNFetchBlob.fs.dirs.CacheDir + `/${attachment.metadata.hash}`)
.catch(console.log);
}
- if (Platform.OS === 'ios') {
+ if (Platform.OS === "ios") {
fileUri = folder.uri + `/${attachment.metadata.filename}`;
}
- console.log('saved file uri: ', fileUri);
+ console.log("saved file uri: ", fileUri);
presentSheet({
title: `File downloaded`,
paragraph: `${attachment.metadata.filename} saved to ${
- Platform.OS === 'android' ? 'selected path' : 'File Manager/Notesnook/downloads'
+ Platform.OS === "android"
+ ? "selected path"
+ : "File Manager/Notesnook/downloads"
}`,
- icon: 'download',
+ icon: "download",
context: global ? null : attachment.metadata.hash,
- component:
+ component: (
+
+ )
});
return fileUri;
} catch (e) {
- console.log('download attachment error: ', e);
+ console.log("download attachment error: ", e);
if (attachment.dateUploaded) {
- console.log('Deleting attachment on error', attachment.dateUploaded);
+ console.log("Deleting attachment on error", attachment.dateUploaded);
RNFetchBlob.fs
.unlink(RNFetchBlob.fs.dirs.CacheDir + `/${attachment.metadata.hash}`)
.catch(console.log);
@@ -152,26 +172,27 @@ export async function getUploadedFileSize(hash) {
const token = await db.user.tokenManager.getAccessToken();
const attachmentInfo = await fetch(url, {
- method: 'HEAD',
+ method: "HEAD",
headers: { Authorization: `Bearer ${token}` }
});
- const contentLength = parseInt(attachmentInfo.headers?.get('content-length'));
- console.log('contentLength:', contentLength, attachmentInfo.headers);
+ const contentLength = parseInt(attachmentInfo.headers?.get("content-length"));
+ console.log("contentLength:", contentLength, attachmentInfo.headers);
return isNaN(contentLength) ? 0 : contentLength;
}
export async function checkAttachment(hash) {
const internetState = await NetInfo.fetch();
- const isInternetReachable = internetState.isConnected && internetState.isInternetReachable;
+ const isInternetReachable =
+ internetState.isConnected && internetState.isInternetReachable;
if (!isInternetReachable) return { success: true };
const attachment = db.attachments.attachment(hash);
- if (!attachment) return { failed: 'Attachment not found.' };
+ if (!attachment) return { failed: "Attachment not found." };
try {
const size = await getUploadedFileSize(hash);
- if (size <= 0) return { failed: 'File length is 0.' };
+ if (size <= 0) return { failed: "File length is 0." };
} catch (e) {
return { failed: e?.message };
}
diff --git a/apps/mobile/app/common/filesystem/index.js b/apps/mobile/app/common/filesystem/index.js
index c7e1753d5..2c9720277 100644
--- a/apps/mobile/app/common/filesystem/index.js
+++ b/apps/mobile/app/common/filesystem/index.js
@@ -1,7 +1,18 @@
-import { downloadAttachment, downloadFile, getUploadedFileSize, checkAttachment } from './download';
-import { clearFileStorage, deleteFile, exists, readEncrypted, writeEncrypted } from './io';
-import { uploadFile } from './upload';
-import { cancelable } from './utils';
+import {
+ downloadAttachment,
+ downloadFile,
+ getUploadedFileSize,
+ checkAttachment
+} from "./download";
+import {
+ clearFileStorage,
+ deleteFile,
+ exists,
+ readEncrypted,
+ writeEncrypted
+} from "./io";
+import { uploadFile } from "./upload";
+import { cancelable } from "./utils";
export default {
readEncrypted,
diff --git a/apps/mobile/app/common/filesystem/io.js b/apps/mobile/app/common/filesystem/io.js
index beb5c5669..de3103fea 100644
--- a/apps/mobile/app/common/filesystem/io.js
+++ b/apps/mobile/app/common/filesystem/io.js
@@ -1,7 +1,7 @@
-import { Platform } from 'react-native';
-import Sodium from 'react-native-sodium';
-import RNFetchBlob from 'rn-fetch-blob';
-import { cacheDir, getRandomId } from './utils';
+import { Platform } from "react-native";
+import Sodium from "react-native-sodium";
+import RNFetchBlob from "rn-fetch-blob";
+import { cacheDir, getRandomId } from "./utils";
export async function readEncrypted(filename, key, cipherData) {
let path = `${cacheDir}/${filename}`;
@@ -19,28 +19,28 @@ export async function readEncrypted(filename, key, cipherData) {
},
true
);
- console.log('output length: ', output?.length);
+ console.log("output length: ", output?.length);
return output;
} catch (e) {
RNFetchBlob.fs.unlink(path).catch(console.log);
console.log(e);
- console.log('error');
+ console.log("error");
return false;
}
}
export async function writeEncrypted(filename, { data, type, key }) {
- console.log('file input: ', { type, key });
- let filepath = cacheDir + `/${getRandomId('imagecache_')}`;
+ console.log("file input: ", { type, key });
+ let filepath = cacheDir + `/${getRandomId("imagecache_")}`;
console.log(filepath);
- await RNFetchBlob.fs.writeFile(filepath, data, 'base64');
+ await RNFetchBlob.fs.writeFile(filepath, data, "base64");
let output = await Sodium.encryptFile(key, {
- uri: Platform.OS === 'ios' ? filepath : `file://` + filepath,
- type: 'url'
+ uri: Platform.OS === "ios" ? filepath : `file://` + filepath,
+ type: "url"
});
RNFetchBlob.fs.unlink(filepath).catch(console.log);
- console.log('encrypted file output: ', output);
+ console.log("encrypted file output: ", output);
return {
...output,
alg: `xcha-stream`
@@ -57,7 +57,7 @@ export async function deleteFile(filename, data) {
let { url, headers } = data;
try {
- let response = await RNFetchBlob.fetch('DELETE', url, headers);
+ let response = await RNFetchBlob.fetch("DELETE", url, headers);
let status = response.info().status;
let ok = status >= 200 && status < 300;
if (ok) {
@@ -65,7 +65,7 @@ export async function deleteFile(filename, data) {
}
return ok;
} catch (e) {
- console.log('delete file: ', e, url, headers);
+ console.log("delete file: ", e, url, headers);
return false;
}
}
diff --git a/apps/mobile/app/common/filesystem/upload.js b/apps/mobile/app/common/filesystem/upload.js
index 5daa27527..4905fb0e0 100644
--- a/apps/mobile/app/common/filesystem/upload.js
+++ b/apps/mobile/app/common/filesystem/upload.js
@@ -1,36 +1,38 @@
-import RNFetchBlob from 'rn-fetch-blob';
-import { useAttachmentStore } from '../../stores/use-attachment-store';
-import { db } from '../database';
-import { cacheDir } from './utils';
+import RNFetchBlob from "rn-fetch-blob";
+import { useAttachmentStore } from "../../stores/use-attachment-store";
+import { db } from "../database";
+import { cacheDir } from "./utils";
export async function uploadFile(filename, data, cancelToken) {
if (!data) return false;
let { url, headers } = data;
- console.log('uploading file: ', filename, headers);
+ console.log("uploading file: ", filename, headers);
try {
let res = await fetch(url, {
- method: 'PUT',
+ method: "PUT",
headers
});
if (!res.ok) throw new Error(`${res.status}: Unable to resolve upload url`);
const uploadUrl = await res.text();
- if (!uploadUrl) throw new Error('Unable to resolve upload url');
+ if (!uploadUrl) throw new Error("Unable to resolve upload url");
let request = RNFetchBlob.config({
IOSBackgroundTask: true
})
.fetch(
- 'PUT',
+ "PUT",
uploadUrl,
{
- 'content-type': ''
+ "content-type": ""
},
RNFetchBlob.wrap(`${cacheDir}/${filename}`)
)
.uploadProgress((sent, total) => {
- useAttachmentStore.getState().setProgress(sent, total, filename, 0, 'upload');
- console.log('uploading: ', sent, total);
+ useAttachmentStore
+ .getState()
+ .setProgress(sent, total, filename, 0, "upload");
+ console.log("uploading: ", sent, total);
});
cancelToken.cancel = request.cancel;
let response = await request;
@@ -42,7 +44,7 @@ export async function uploadFile(filename, data, cancelToken) {
if (result) {
let attachment = db.attachments.attachment(filename);
if (!attachment) return result;
- if (!attachment.metadata.type.startsWith('image/')) {
+ if (!attachment.metadata.type.startsWith("image/")) {
RNFetchBlob.fs.unlink(`${cacheDir}/${filename}`).catch(console.log);
}
}
@@ -50,7 +52,7 @@ export async function uploadFile(filename, data, cancelToken) {
return result;
} catch (e) {
useAttachmentStore.getState().remove(filename);
- console.log('upload file: ', e, url, headers);
+ console.log("upload file: ", e, url, headers);
return false;
}
}
diff --git a/apps/mobile/app/common/filesystem/utils.js b/apps/mobile/app/common/filesystem/utils.js
index 05ca87d68..3d1cbbfa2 100644
--- a/apps/mobile/app/common/filesystem/utils.js
+++ b/apps/mobile/app/common/filesystem/utils.js
@@ -1,25 +1,28 @@
-import RNFetchBlob from 'rn-fetch-blob';
+import RNFetchBlob from "rn-fetch-blob";
export const cacheDir = RNFetchBlob.fs.dirs.CacheDir;
export function getRandomId(prefix) {
return Math.random()
.toString(36)
- .replace('0.', prefix || '');
+ .replace("0.", prefix || "");
}
export function extractValueFromXmlTag(code, xml) {
if (!xml.includes(code)) return `Unknown ${code}`;
- return xml.slice(xml.indexOf(`<${code}>`) + code.length + 2, xml.indexOf(`${code}>`));
+ return xml.slice(
+ xml.indexOf(`<${code}>`) + code.length + 2,
+ xml.indexOf(`${code}>`)
+ );
}
export async function fileCheck(response, totalSize) {
if (totalSize < 1000) {
let text = await response.text();
- if (text.startsWith(' {
- const colors = useThemeStore(state => state.colors);
- const announcements = useMessageStore(state => state.announcements);
+ const colors = useThemeStore((state) => state.colors);
+ const announcements = useMessageStore((state) => state.announcements);
let announcement = announcements.length > 0 ? announcements[0] : null;
- const selectionMode = useSelectionStore(state => state.selectionMode);
+ const selectionMode = useSelectionStore((state) => state.selectionMode);
return !announcement || selectionMode ? null : (
{
>
{
allowedOnPlatform(item.platforms))}
+ data={announcement?.body.filter((item) =>
+ allowedOnPlatform(item.platforms)
+ )}
renderItem={({ item, index }) =>
- renderItem({ item: item, index: index, color: colors[color], inline: true })
+ renderItem({
+ item: item,
+ index: index,
+ color: colors[color],
+ inline: true
+ })
}
/>
diff --git a/apps/mobile/app/components/announcements/body.js b/apps/mobile/app/components/announcements/body.js
index eaceb2c60..7b5345384 100644
--- a/apps/mobile/app/components/announcements/body.js
+++ b/apps/mobile/app/components/announcements/body.js
@@ -1,10 +1,10 @@
-import React from 'react';
-import { useThemeStore } from '../../stores/use-theme-store';
-import Paragraph from '../ui/typography/paragraph';
-import { getStyle } from './functions';
+import React from "react";
+import { useThemeStore } from "../../stores/use-theme-store";
+import Paragraph from "../ui/typography/paragraph";
+import { getStyle } from "./functions";
export const Body = ({ text, style = {} }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
{
- const colors = useThemeStore(state => state.colors);
- let buttons = actions.filter(item => allowedOnPlatform(item.platforms)) || [];
+ const colors = useThemeStore((state) => state.colors);
+ let buttons =
+ actions.filter((item) => allowedOnPlatform(item.platforms)) || [];
- const onPress = async item => {
+ const onPress = async (item) => {
if (!inline) {
eSendEvent(eCloseAnnouncementDialog);
await sleep(500);
}
- if (item.type === 'link') {
+ if (item.type === "link") {
Linking.openURL(item.data).catch(console.log);
- } else if (item.type === 'promo') {
+ } else if (item.type === "promo") {
presentSheet({
component: (
{
/>
)
});
- } else if (item.type === 'force-sync') {
+ } else if (item.type === "force-sync") {
eSendEvent(eCloseProgressDialog);
await sleep(300);
Progress.present();
- Sync.run('global', true, true, () => {
+ Sync.run("global", true, true, () => {
eSendEvent(eCloseProgressDialog);
});
}
@@ -50,7 +54,7 @@ export const Cta = ({ actions, style = {}, color, inline }) => {
style={{
paddingHorizontal: 12,
...getStyle(style),
- flexDirection: inline ? 'row' : 'column'
+ flexDirection: inline ? "row" : "column"
}}
>
@@ -58,20 +62,20 @@ export const Cta = ({ actions, style = {}, color, inline }) => {
{inline ? (
<>
{buttons.length > 0 &&
- buttons.slice(0, 1).map(item => (
+ buttons.slice(0, 1).map((item) => (
diff --git a/apps/mobile/app/components/auth/auth-modal.js b/apps/mobile/app/components/auth/auth-modal.js
index 1d239c742..4d4e16f88 100644
--- a/apps/mobile/app/components/auth/auth-modal.js
+++ b/apps/mobile/app/components/auth/auth-modal.js
@@ -1,18 +1,21 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { eCloseLoginDialog, eOpenLoginDialog } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import BaseDialog from '../dialog/base-dialog';
-import { Toast } from '../toast';
-import { Button } from '../ui/button';
-import { IconButton } from '../ui/icon-button';
-import { hideAuth, initialAuthMode } from './common';
-import { Login } from './login';
-import { Signup } from './signup';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { Platform, View } from 'react-native';
+import React, { useEffect, useRef, useState } from "react";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { eCloseLoginDialog, eOpenLoginDialog } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import BaseDialog from "../dialog/base-dialog";
+import { Toast } from "../toast";
+import { Button } from "../ui/button";
+import { IconButton } from "../ui/icon-button";
+import { hideAuth, initialAuthMode } from "./common";
+import { Login } from "./login";
+import { Signup } from "./signup";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { Platform, View } from "react-native";
export const AuthMode = {
login: 0,
@@ -22,7 +25,7 @@ export const AuthMode = {
};
const AuthModal = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [visible, setVisible] = useState(false);
const [currentAuthMode, setCurrentAuthMode] = useState(AuthMode.login);
const actionSheetRef = useRef();
@@ -66,29 +69,31 @@ const AuthModal = () => {
>
{currentAuthMode !== AuthMode.login ? (
setCurrentAuthMode(mode)}
+ changeMode={(mode) => setCurrentAuthMode(mode)}
trial={AuthMode.trialSignup === currentAuthMode}
welcome={initialAuthMode.current === AuthMode.welcomeSignup}
/>
) : (
setCurrentAuthMode(mode)}
+ changeMode={(mode) => setCurrentAuthMode(mode)}
/>
)}
{initialAuthMode.current === AuthMode.welcomeSignup ? null : (
diff --git a/apps/mobile/app/components/auth/background.js b/apps/mobile/app/components/auth/background.js
index ebf0fdb70..a3a559caf 100644
--- a/apps/mobile/app/components/auth/background.js
+++ b/apps/mobile/app/components/auth/background.js
@@ -1,2 +1,2 @@
-export const SVG = color =>
+export const SVG = (color) =>
``;
diff --git a/apps/mobile/app/components/auth/change-password.js b/apps/mobile/app/components/auth/change-password.js
index eec802941..2893cc24e 100644
--- a/apps/mobile/app/components/auth/change-password.js
+++ b/apps/mobile/app/components/auth/change-password.js
@@ -1,18 +1,22 @@
-import React, { useRef, useState } from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useUserStore } from '../../stores/use-user-store';
-import { eSendEvent, presentSheet, ToastEvent } from '../../services/event-manager';
-import { db } from '../../common/database';
-import { eCloseProgressDialog } from '../../utils/events';
-import { Button } from '../ui/button';
-import DialogHeader from '../dialog/dialog-header';
-import Input from '../ui/input';
-import { Notice } from '../ui/notice';
-import Seperator from '../ui/seperator';
+import React, { useRef, useState } from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useUserStore } from "../../stores/use-user-store";
+import {
+ eSendEvent,
+ presentSheet,
+ ToastEvent
+} from "../../services/event-manager";
+import { db } from "../../common/database";
+import { eCloseProgressDialog } from "../../utils/events";
+import { Button } from "../ui/button";
+import DialogHeader from "../dialog/dialog-header";
+import Input from "../ui/input";
+import { Notice } from "../ui/notice";
+import Seperator from "../ui/seperator";
export const ChangePassword = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const passwordInputRef = useRef();
const password = useRef();
const oldPasswordInputRef = useRef();
@@ -20,24 +24,24 @@ export const ChangePassword = () => {
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
- const user = useUserStore(state => state.user);
+ const user = useUserStore((state) => state.user);
const changePassword = async () => {
if (!user?.isEmailConfirmed) {
ToastEvent.show({
- heading: 'Email not confirmed',
- message: 'Please confirm your email to change account password',
- type: 'error',
- context: 'local'
+ heading: "Email not confirmed",
+ message: "Please confirm your email to change account password",
+ type: "error",
+ context: "local"
});
return;
}
if (error || !oldPassword.current || !password.current) {
ToastEvent.show({
- heading: 'All fields required',
- message: 'Fill all the fields and try again.',
- type: 'error',
- context: 'local'
+ heading: "All fields required",
+ message: "Fill all the fields and try again.",
+ type: "error",
+ context: "local"
});
return;
}
@@ -47,18 +51,18 @@ export const ChangePassword = () => {
await db.user.changePassword(oldPassword.current, password.current);
ToastEvent.show({
heading: `Account password updated`,
- type: 'success',
- context: 'global'
+ type: "success",
+ context: "global"
});
setLoading(false);
eSendEvent(eCloseProgressDialog);
} catch (e) {
setLoading(false);
ToastEvent.show({
- heading: 'Failed to change password',
+ heading: "Failed to change password",
message: e.message,
- type: 'error',
- context: 'local'
+ type: "error",
+ context: "local"
});
}
setLoading(false);
@@ -67,16 +71,19 @@ export const ChangePassword = () => {
return (
-
+
{
+ onChangeText={(value) => {
oldPassword.current = value;
}}
returnKeyLabel="Next"
@@ -90,10 +97,10 @@ export const ChangePassword = () => {
{
+ onChangeText={(value) => {
password.current = value;
}}
- onErrorCheck={e => setError(e)}
+ onErrorCheck={(e) => setError(e)}
returnKeyLabel="Next"
returnKeyType="next"
secureTextEntry
@@ -112,12 +119,12 @@ export const ChangePassword = () => {
);
diff --git a/apps/mobile/app/components/auth/common.js b/apps/mobile/app/components/auth/common.js
index b5e91d4b9..0f2500d35 100644
--- a/apps/mobile/app/components/auth/common.js
+++ b/apps/mobile/app/components/auth/common.js
@@ -1,9 +1,9 @@
-import { createRef } from 'react';
-import { eSendEvent } from '../../services/event-manager';
-import Navigation from '../../services/navigation';
-import SettingsService from '../../services/settings';
-import { eCloseLoginDialog } from '../../utils/events';
-import { tabBarRef } from '../../utils/global-refs';
+import { createRef } from "react";
+import { eSendEvent } from "../../services/event-manager";
+import Navigation from "../../services/navigation";
+import SettingsService from "../../services/settings";
+import { eCloseLoginDialog } from "../../utils/events";
+import { tabBarRef } from "../../utils/global-refs";
export const initialAuthMode = createRef(0);
export function hideAuth() {
diff --git a/apps/mobile/app/components/auth/forgot-password.js b/apps/mobile/app/components/auth/forgot-password.js
index e8ea00b0c..b78e5b0b9 100644
--- a/apps/mobile/app/components/auth/forgot-password.js
+++ b/apps/mobile/app/components/auth/forgot-password.js
@@ -1,21 +1,21 @@
-import React, { useRef, useState } from 'react';
-import { View } from 'react-native';
-import ActionSheet from 'react-native-actions-sheet';
-import { DDS } from '../../services/device-detection';
-import { ToastEvent } from '../../services/event-manager';
-import SettingsService from '../../services/settings';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { db } from '../../common/database';
-import DialogHeader from '../dialog/dialog-header';
-import { Button } from '../ui/button';
-import { IconButton } from '../ui/icon-button';
-import Input from '../ui/input';
-import Seperator from '../ui/seperator';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
+import React, { useRef, useState } from "react";
+import { View } from "react-native";
+import ActionSheet from "react-native-actions-sheet";
+import { DDS } from "../../services/device-detection";
+import { ToastEvent } from "../../services/event-manager";
+import SettingsService from "../../services/settings";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { db } from "../../common/database";
+import DialogHeader from "../dialog/dialog-header";
+import { Button } from "../ui/button";
+import { IconButton } from "../ui/icon-button";
+import Input from "../ui/input";
+import Seperator from "../ui/seperator";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
export const ForgotPassword = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const email = useRef();
const emailInputRef = useRef();
const [error, setError] = useState(false);
@@ -25,17 +25,20 @@ export const ForgotPassword = () => {
const sendRecoveryEmail = async () => {
if (!email.current || error) {
ToastEvent.show({
- heading: 'Account email is required.',
- type: 'error',
- context: 'local'
+ heading: "Account email is required.",
+ type: "error",
+ context: "local"
});
return;
}
setLoading(true);
try {
let lastRecoveryEmailTime = SettingsService.get().lastRecoveryEmailTime;
- if (lastRecoveryEmailTime && Date.now() - JSON.parse(lastRecoveryEmailTime) < 60000 * 3) {
- throw new Error('Please wait before requesting another email');
+ if (
+ lastRecoveryEmailTime &&
+ Date.now() - JSON.parse(lastRecoveryEmailTime) < 60000 * 3
+ ) {
+ throw new Error("Please wait before requesting another email");
}
await db.user.recoverAccount(email.current.toLowerCase());
SettingsService.set({
@@ -44,8 +47,8 @@ export const ForgotPassword = () => {
ToastEvent.show({
heading: `Check your email to reset password`,
message: `Recovery email has been sent to ${email.current.toLowerCase()}`,
- type: 'success',
- context: 'local',
+ type: "success",
+ context: "local",
duration: 7000
});
setLoading(false);
@@ -53,10 +56,10 @@ export const ForgotPassword = () => {
} catch (e) {
setLoading(false);
ToastEvent.show({
- heading: 'Recovery email not sent',
+ heading: "Recovery email not sent",
message: e.message,
- type: 'error',
- context: 'local'
+ type: "error",
+ context: "local"
});
}
};
@@ -64,7 +67,7 @@ export const ForgotPassword = () => {
return (
<>
(email.current = data)}
+ onBeforeShow={(data) => (email.current = data)}
onClose={() => {
setSent(false);
setLoading(false);
@@ -82,8 +85,8 @@ export const ForgotPassword = () => {
@@ -99,7 +102,7 @@ export const ForgotPassword = () => {
Recovery email sent!
Please follow the link in the email to recover your account.
@@ -111,7 +114,7 @@ export const ForgotPassword = () => {
borderRadius: DDS.isTab ? 5 : 0,
backgroundColor: colors.bg,
zIndex: 10,
- width: '100%',
+ width: "100%",
padding: 12
}}
>
@@ -123,11 +126,11 @@ export const ForgotPassword = () => {
{
+ onChangeText={(value) => {
email.current = value;
}}
defaultValue={email.current}
- onErrorCheck={e => setError(e)}
+ onErrorCheck={(e) => setError(e)}
returnKeyLabel="Next"
returnKeyType="next"
autoComplete="email"
@@ -142,12 +145,12 @@ export const ForgotPassword = () => {
)}
diff --git a/apps/mobile/app/components/auth/index.js b/apps/mobile/app/components/auth/index.js
index 8c14dc07d..3f256d3b2 100644
--- a/apps/mobile/app/components/auth/index.js
+++ b/apps/mobile/app/components/auth/index.js
@@ -1,13 +1,13 @@
-import React, { useState } from 'react';
-import { View } from 'react-native';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { tabBarRef } from '../../utils/global-refs';
-import { useNavigationFocus } from '../../hooks/use-navigation-focus';
-import { Toast } from '../toast';
-import { initialAuthMode } from './common';
-import { Login } from './login';
-import { Signup } from './signup';
+import React, { useState } from "react";
+import { View } from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { tabBarRef } from "../../utils/global-refs";
+import { useNavigationFocus } from "../../hooks/use-navigation-focus";
+import { Toast } from "../toast";
+import { initialAuthMode } from "./common";
+import { Login } from "./login";
+import { Signup } from "./signup";
export const AuthMode = {
login: 0,
@@ -17,8 +17,10 @@ export const AuthMode = {
};
const Auth = ({ navigation, route }) => {
- const colors = useThemeStore(state => state.colors);
- const [currentAuthMode, setCurrentAuthMode] = useState(route?.params?.mode || AuthMode.login);
+ const colors = useThemeStore((state) => state.colors);
+ const [currentAuthMode, setCurrentAuthMode] = useState(
+ route?.params?.mode || AuthMode.login
+ );
const insets = useSafeAreaInsets();
initialAuthMode.current = route?.params.mode || AuthMode.login;
useNavigationFocus(navigation, {
@@ -32,12 +34,15 @@ const Auth = ({ navigation, route }) => {
{currentAuthMode !== AuthMode.login ? (
setCurrentAuthMode(mode)}
+ changeMode={(mode) => setCurrentAuthMode(mode)}
trial={AuthMode.trialSignup === currentAuthMode}
welcome={initialAuthMode.current === AuthMode.welcomeSignup}
/>
) : (
- setCurrentAuthMode(mode)} />
+ setCurrentAuthMode(mode)}
+ />
)}
{/* {initialAuthMode.current === AuthMode.welcomeSignup ? null : (
diff --git a/apps/mobile/app/components/auth/login.js b/apps/mobile/app/components/auth/login.js
index bccd568a7..567bb6ab7 100644
--- a/apps/mobile/app/components/auth/login.js
+++ b/apps/mobile/app/components/auth/login.js
@@ -1,36 +1,40 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { Platform, View } from 'react-native';
-import { SheetManager } from 'react-native-actions-sheet';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { DDS } from '../../services/device-detection';
-import { eSendEvent, ToastEvent } from '../../services/event-manager';
-import { clearMessage } from '../../services/message';
-import PremiumService from '../../services/premium';
-import SettingsService from '../../services/settings';
-import { useUserStore } from '../../stores/use-user-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { db } from '../../common/database';
-import { eCloseLoginDialog } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import BaseDialog from '../dialog/base-dialog';
-import SheetProvider from '../sheet-provider';
-import { Progress } from '../sheets/progress';
-import { Button } from '../ui/button';
-import { IconButton } from '../ui/icon-button';
-import Input from '../ui/input';
-import { SvgView } from '../ui/svg';
-import { BouncingView } from '../ui/transitions/bouncing-view';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import { SVG } from './background';
-import { ForgotPassword } from './forgot-password';
-import TwoFactorVerification from './two-factor';
-import Animated, { FadeInDown, FadeOutDown, FadeOutUp } from 'react-native-reanimated';
-import Navigation from '../../services/navigation';
-import { hideAuth } from './common';
+import React, { useEffect, useRef, useState } from "react";
+import { Platform, View } from "react-native";
+import { SheetManager } from "react-native-actions-sheet";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { DDS } from "../../services/device-detection";
+import { eSendEvent, ToastEvent } from "../../services/event-manager";
+import { clearMessage } from "../../services/message";
+import PremiumService from "../../services/premium";
+import SettingsService from "../../services/settings";
+import { useUserStore } from "../../stores/use-user-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { db } from "../../common/database";
+import { eCloseLoginDialog } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import BaseDialog from "../dialog/base-dialog";
+import SheetProvider from "../sheet-provider";
+import { Progress } from "../sheets/progress";
+import { Button } from "../ui/button";
+import { IconButton } from "../ui/icon-button";
+import Input from "../ui/input";
+import { SvgView } from "../ui/svg";
+import { BouncingView } from "../ui/transitions/bouncing-view";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import { SVG } from "./background";
+import { ForgotPassword } from "./forgot-password";
+import TwoFactorVerification from "./two-factor";
+import Animated, {
+ FadeInDown,
+ FadeOutDown,
+ FadeOutUp
+} from "react-native-reanimated";
+import Navigation from "../../services/navigation";
+import { hideAuth } from "./common";
export const Login = ({ changeMode, welcome }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const email = useRef();
const emailInputRef = useRef();
const passwordInputRef = useRef();
@@ -40,15 +44,15 @@ export const Login = ({ changeMode, welcome }) => {
const [loading, setLoading] = useState(false);
const insets = useSafeAreaInsets();
- const setUser = useUserStore(state => state.setUser);
+ const setUser = useUserStore((state) => state.setUser);
const validateInfo = () => {
if (!password.current || !email.current) {
ToastEvent.show({
- heading: 'All fields required',
- message: 'Fill all the fields and try again',
- type: 'error',
- context: 'local'
+ heading: "All fields required",
+ message: "Fill all the fields and try again",
+ type: "error",
+ context: "local"
});
return false;
@@ -71,37 +75,41 @@ export const Login = ({ changeMode, welcome }) => {
let user;
try {
if (mfa) {
- await db.user.mfaLogin(email.current.toLowerCase(), password.current, mfa);
+ await db.user.mfaLogin(
+ email.current.toLowerCase(),
+ password.current,
+ mfa
+ );
} else {
await db.user.login(email.current.toLowerCase(), password.current);
}
callback && callback(true);
user = await db.user.getUser();
- if (!user) throw new Error('Email or password incorrect!');
+ if (!user) throw new Error("Email or password incorrect!");
PremiumService.setPremiumStatus();
setUser(user);
clearMessage();
ToastEvent.show({
- heading: 'Login successful',
+ heading: "Login successful",
message: `Logged in as ${user.email}`,
- type: 'success',
- context: 'global'
+ type: "success",
+ context: "global"
});
hideAuth();
SettingsService.set({
sessionExpired: false,
userEmailConfirmed: user?.isEmailConfirmed
});
- eSendEvent('userLoggedIn', true);
+ eSendEvent("userLoggedIn", true);
await sleep(500);
Progress.present();
} catch (e) {
callback && callback(false);
- if (e.message === 'Multifactor authentication required.') {
+ if (e.message === "Multifactor authentication required.") {
setLoading(false);
await sleep(300);
- TwoFactorVerification.present(async mfa => {
+ TwoFactorVerification.present(async (mfa) => {
if (mfa) {
console.log(mfa);
await login(mfa);
@@ -112,10 +120,10 @@ export const Login = ({ changeMode, welcome }) => {
} else {
setLoading(false);
ToastEvent.show({
- heading: user ? 'Failed to sync' : 'Login failed',
+ heading: user ? "Failed to sync" : "Login failed",
message: e.message,
- type: 'error',
- context: 'local'
+ type: "error",
+ context: "local"
});
}
}
@@ -125,7 +133,9 @@ export const Login = ({ changeMode, welcome }) => {
<>
- {loading ? : null}
+ {loading ? (
+
+ ) : null}
{
borderRadius: DDS.isTab ? 5 : 0,
backgroundColor: colors.bg,
zIndex: 10,
- width: '100%',
- minHeight: '100%'
+ width: "100%",
+ minHeight: "100%"
}}
>
-
+
{
>
{
{
@@ -180,20 +193,26 @@ export const Login = ({ changeMode, welcome }) => {
{
+ onChangeText={(value) => {
email.current = value;
}}
testID="input.email"
- onErrorCheck={e => setError(e)}
+ onErrorCheck={(e) => setError(e)}
returnKeyLabel="Next"
returnKeyType="next"
autoComplete="email"
@@ -209,7 +228,7 @@ export const Login = ({ changeMode, welcome }) => {
{
+ onChangeText={(value) => {
password.current = value;
}}
testID="input.password"
@@ -226,15 +245,15 @@ export const Login = ({ changeMode, welcome }) => {
{
- SheetManager.show('forgotpassword_sheet', email.current);
+ SheetManager.show("forgotpassword_sheet", email.current);
}}
textStyle={{
- textDecorationLine: 'underline'
+ textDecorationLine: "underline"
}}
fontSize={SIZE.xs}
type="gray"
@@ -244,7 +263,7 @@ export const Login = ({ changeMode, welcome }) => {
style={{
// position: 'absolute',
marginTop: 25,
- alignSelf: 'center'
+ alignSelf: "center"
}}
>
{
onPress={() => login()}
// width="100%"
type="accent"
- title={loading ? null : 'Login to your account'}
+ title={loading ? null : "Login to your account"}
/>
diff --git a/apps/mobile/app/components/auth/session-expired.js b/apps/mobile/app/components/auth/session-expired.js
index 39b559ac2..22f8ff383 100644
--- a/apps/mobile/app/components/auth/session-expired.js
+++ b/apps/mobile/app/components/auth/session-expired.js
@@ -1,47 +1,47 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { Modal, View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useUserStore } from '../../stores/use-user-store';
-import BiometricService from '../../services/biometrics';
+import React, { useEffect, useRef, useState } from "react";
+import { Modal, View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useUserStore } from "../../stores/use-user-store";
+import BiometricService from "../../services/biometrics";
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent,
presentSheet,
ToastEvent
-} from '../../services/event-manager';
-import { clearMessage } from '../../services/message';
-import PremiumService from '../../services/premium';
-import Sync from '../../services/sync';
-import { db } from '../../common/database';
-import { MMKV } from '../../common/database/mmkv';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import { IconButton } from '../ui/icon-button';
-import { Button } from '../ui/button';
-import { Dialog } from '../dialog';
-import { presentDialog } from '../dialog/functions';
-import Input from '../ui/input';
-import { Toast } from '../toast';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import SettingsService from '../../services/settings';
-import TwoFactorVerification from './two-factor';
-import SheetProvider from '../sheet-provider';
-import { Progress } from '../sheets/progress';
+} from "../../services/event-manager";
+import { clearMessage } from "../../services/message";
+import PremiumService from "../../services/premium";
+import Sync from "../../services/sync";
+import { db } from "../../common/database";
+import { MMKV } from "../../common/database/mmkv";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import { IconButton } from "../ui/icon-button";
+import { Button } from "../ui/button";
+import { Dialog } from "../dialog";
+import { presentDialog } from "../dialog/functions";
+import Input from "../ui/input";
+import { Toast } from "../toast";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import SettingsService from "../../services/settings";
+import TwoFactorVerification from "./two-factor";
+import SheetProvider from "../sheet-provider";
+import { Progress } from "../sheets/progress";
function getEmail(email) {
if (!email) return null;
return email.replace(/(.{2})(.*)(?=@)/, function (gp1, gp2, gp3) {
for (let i = 0; i < gp3.length; i++) {
- gp2 += '*';
+ gp2 += "*";
}
return gp2;
});
}
export const SessionExpired = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const email = useRef();
const emailInputRef = useRef();
const passwordInputRef = useRef();
@@ -49,7 +49,7 @@ export const SessionExpired = () => {
const [visible, setVisible] = useState(false);
const [focused, setFocused] = useState(false);
- const setUser = useUserStore(state => state.setUser);
+ const setUser = useUserStore((state) => state.setUser);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
@@ -65,27 +65,28 @@ export const SessionExpired = () => {
} catch (e) {
ToastEvent.show({
heading: e.message,
- type: 'error',
- context: 'local'
+ type: "error",
+ context: "local"
});
}
};
useEffect(() => {
- eSubscribeEvent('session_expired', open);
+ eSubscribeEvent("session_expired", open);
return () => {
- eUnSubscribeEvent('session_expired', open);
+ eUnSubscribeEvent("session_expired", open);
setFocused(false);
};
}, [visible]);
const open = async () => {
try {
- console.log('REQUESTING NEW TOKEN');
+ console.log("REQUESTING NEW TOKEN");
let res = await db.user.tokenManager.getToken();
- if (!res) throw new Error('no token found');
- if (db.user.tokenManager._isTokenExpired(res)) throw new Error('token expired');
- Sync.run('global', false, true, async complete => {
+ if (!res) throw new Error("no token found");
+ if (db.user.tokenManager._isTokenExpired(res))
+ throw new Error("token expired");
+ Sync.run("global", false, true, async (complete) => {
if (!complete) {
let user = await db.user.getUser();
if (!user) return;
@@ -113,35 +114,39 @@ export const SessionExpired = () => {
let user;
try {
if (mfa) {
- await db.user.mfaLogin(email.current.toLowerCase(), password.current, mfa);
+ await db.user.mfaLogin(
+ email.current.toLowerCase(),
+ password.current,
+ mfa
+ );
} else {
await db.user.login(email.current.toLowerCase(), password.current);
}
callback && callback(true);
setVisible(false);
user = await db.user.getUser();
- if (!user) throw new Error('Email or password incorrect!');
+ if (!user) throw new Error("Email or password incorrect!");
PremiumService.setPremiumStatus();
setUser(user);
clearMessage();
ToastEvent.show({
- heading: 'Login successful',
+ heading: "Login successful",
message: `Logged in as ${user.email}`,
- type: 'success',
- context: 'global'
+ type: "success",
+ context: "global"
});
await SettingsService.set({
sessionExpired: false,
userEmailConfirmed: user?.isEmailConfirmed
});
- eSendEvent('userLoggedIn', true);
+ eSendEvent("userLoggedIn", true);
await sleep(500);
Progress.present();
setLoading(false);
} catch (e) {
callback && callback(false);
- if (e.message === 'Multifactor authentication required.') {
- TwoFactorVerification.present(async mfa => {
+ if (e.message === "Multifactor authentication required.") {
+ TwoFactorVerification.present(async (mfa) => {
if (mfa) {
console.log(mfa);
await login(mfa);
@@ -153,10 +158,10 @@ export const SessionExpired = () => {
console.log(e.stack);
setLoading(false);
ToastEvent.show({
- heading: user ? 'Failed to sync' : 'Login failed',
+ heading: user ? "Failed to sync" : "Login failed",
message: e.message,
- type: 'error',
- context: 'local'
+ type: "error",
+ context: "local"
});
}
}
@@ -174,17 +179,17 @@ export const SessionExpired = () => {
{
- Your session on this device has expired. Please enter password for{' '}
+ Your session on this device has expired. Please enter password for{" "}
{getEmail(email.current)} to continue.
{
+ onChangeText={(value) => {
password.current = value;
}}
returnKeyLabel="Next"
@@ -230,32 +235,32 @@ export const SessionExpired = () => {
login()}
type="accent"
- title={loading ? null : 'Login'}
+ title={loading ? null : "Login"}
/>
{
presentDialog({
- context: 'session_expiry',
- title: 'Logout',
+ context: "session_expiry",
+ title: "Logout",
paragraph:
- 'Are you sure you want to logout from this device? Any unsynced changes will be lost.',
- positiveText: 'Logout',
- positiveType: 'errorShade',
+ "Are you sure you want to logout from this device? Any unsynced changes will be lost.",
+ positiveText: "Logout",
+ positiveType: "errorShade",
positivePress: logout
});
}}
type="errorShade"
- title={loading ? null : 'Logout from this device'}
+ title={loading ? null : "Logout from this device"}
/>
diff --git a/apps/mobile/app/components/auth/signup.js b/apps/mobile/app/components/auth/signup.js
index 6ddc09fc0..a7faa6a7d 100644
--- a/apps/mobile/app/components/auth/signup.js
+++ b/apps/mobile/app/components/auth/signup.js
@@ -1,32 +1,36 @@
-import React, { useRef, useState } from 'react';
-import { Dimensions, View } from 'react-native';
-import Animated, { FadeInDown, FadeOutDown, FadeOutUp } from 'react-native-reanimated';
-import { DDS } from '../../services/device-detection';
-import { eSendEvent, ToastEvent } from '../../services/event-manager';
-import { clearMessage, setEmailVerifyMessage } from '../../services/message';
-import Navigation from '../../services/navigation';
-import PremiumService from '../../services/premium';
-import SettingsService from '../../services/settings';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useUserStore } from '../../stores/use-user-store';
-import umami from '../../common/analytics';
-import { db } from '../../common/database';
-import { eCloseLoginDialog } from '../../utils/events';
-import { openLinkInBrowser } from '../../utils/functions';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import BaseDialog from '../dialog/base-dialog';
-import { Button } from '../ui/button';
-import Input from '../ui/input';
-import { SvgView } from '../ui/svg';
-import { BouncingView } from '../ui/transitions/bouncing-view';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import { SVG } from './background';
-import { hideAuth } from './common';
+import React, { useRef, useState } from "react";
+import { Dimensions, View } from "react-native";
+import Animated, {
+ FadeInDown,
+ FadeOutDown,
+ FadeOutUp
+} from "react-native-reanimated";
+import { DDS } from "../../services/device-detection";
+import { eSendEvent, ToastEvent } from "../../services/event-manager";
+import { clearMessage, setEmailVerifyMessage } from "../../services/message";
+import Navigation from "../../services/navigation";
+import PremiumService from "../../services/premium";
+import SettingsService from "../../services/settings";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useUserStore } from "../../stores/use-user-store";
+import umami from "../../common/analytics";
+import { db } from "../../common/database";
+import { eCloseLoginDialog } from "../../utils/events";
+import { openLinkInBrowser } from "../../utils/functions";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import BaseDialog from "../dialog/base-dialog";
+import { Button } from "../ui/button";
+import Input from "../ui/input";
+import { SvgView } from "../ui/svg";
+import { BouncingView } from "../ui/transitions/bouncing-view";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import { SVG } from "./background";
+import { hideAuth } from "./common";
export const Signup = ({ changeMode, welcome, trial }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const email = useRef();
const emailInputRef = useRef();
const passwordInputRef = useRef();
@@ -35,16 +39,16 @@ export const Signup = ({ changeMode, welcome, trial }) => {
const confirmPassword = useRef();
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
- const setUser = useUserStore(state => state.setUser);
- const setLastSynced = useUserStore(state => state.setLastSynced);
+ const setUser = useUserStore((state) => state.setUser);
+ const setLastSynced = useUserStore((state) => state.setLastSynced);
const validateInfo = () => {
if (!password.current || !email.current || !confirmPassword.current) {
ToastEvent.show({
- heading: 'All fields required',
- message: 'Fill all the fields and try again',
- type: 'error',
- context: 'local'
+ heading: "All fields required",
+ message: "Fill all the fields and try again",
+ type: "error",
+ context: "local"
});
return false;
@@ -64,7 +68,7 @@ export const Signup = ({ changeMode, welcome, trial }) => {
clearMessage();
setEmailVerifyMessage();
hideAuth();
- umami.pageView('/account-created', '/welcome/signup');
+ umami.pageView("/account-created", "/welcome/signup");
await sleep(300);
if (trial) {
PremiumService.sheet(null, null, true);
@@ -74,17 +78,19 @@ export const Signup = ({ changeMode, welcome, trial }) => {
} catch (e) {
setLoading(false);
ToastEvent.show({
- heading: 'Signup failed',
+ heading: "Signup failed",
message: e.message,
- type: 'error',
- context: 'local'
+ type: "error",
+ context: "local"
});
}
};
return (
<>
- {loading ? : null}
+ {loading ? (
+
+ ) : null}
{
borderRadius: DDS.isTab ? 5 : 0,
backgroundColor: colors.bg,
zIndex: 10,
- width: '100%',
- minHeight: '100%'
+ width: "100%",
+ minHeight: "100%"
}}
>
-
+
{
{
changeMode(0);
@@ -139,20 +148,20 @@ export const Signup = ({ changeMode, welcome, trial }) => {
{
+ onChangeText={(value) => {
email.current = value;
}}
testID="input.email"
- onErrorCheck={e => setError(e)}
+ onErrorCheck={(e) => setError(e)}
returnKeyLabel="Next"
returnKeyType="next"
autoComplete="email"
@@ -168,11 +177,11 @@ export const Signup = ({ changeMode, welcome, trial }) => {
{
+ onChangeText={(value) => {
password.current = value;
}}
testID="input.password"
- onErrorCheck={e => setError(e)}
+ onErrorCheck={(e) => setError(e)}
returnKeyLabel="Next"
returnKeyType="next"
secureTextEntry
@@ -188,11 +197,11 @@ export const Signup = ({ changeMode, welcome, trial }) => {
{
+ onChangeText={(value) => {
confirmPassword.current = value;
}}
testID="input.confirmPassword"
- onErrorCheck={e => setError(e)}
+ onErrorCheck={(e) => setError(e)}
returnKeyLabel="Signup"
returnKeyType="done"
secureTextEntry
@@ -208,7 +217,7 @@ export const Signup = ({ changeMode, welcome, trial }) => {
{
loading={loading}
onPress={signup}
type="accent"
- title={loading ? null : 'Agree and continue'}
+ title={loading ? null : "Agree and continue"}
/>
- By signing up, you agree to our{' '}
+ By signing up, you agree to our{" "}
{
- openLinkInBrowser('https://notesnook.com/tos', colors);
+ openLinkInBrowser("https://notesnook.com/tos", colors);
}}
style={{
- textDecorationLine: 'underline'
+ textDecorationLine: "underline"
}}
color={colors.accent}
>
- terms of service{' '}
+ terms of service{" "}
- and{' '}
+ and{" "}
{
- openLinkInBrowser('https://notesnook.com/privacy', colors);
+ openLinkInBrowser("https://notesnook.com/privacy", colors);
}}
style={{
- textDecorationLine: 'underline'
+ textDecorationLine: "underline"
}}
color={colors.accent}
>
diff --git a/apps/mobile/app/components/auth/two-factor.js b/apps/mobile/app/components/auth/two-factor.js
index 1bbd40a97..a9884ebbb 100644
--- a/apps/mobile/app/components/auth/two-factor.js
+++ b/apps/mobile/app/components/auth/two-factor.js
@@ -1,22 +1,22 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { View } from 'react-native';
-import { eSendEvent, presentSheet } from '../../services/event-manager';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { eCloseProgressDialog } from '../../utils/events';
-import useTimer from '../../hooks/use-timer';
-import { SIZE } from '../../utils/size';
-import { Button } from '../ui/button';
-import { IconButton } from '../ui/icon-button';
-import Input from '../ui/input';
-import { PressableButton } from '../ui/pressable';
-import Seperator from '../ui/seperator';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import { db } from '../../common/database/index';
-import { ToastEvent } from '../../services/event-manager';
+import React, { useEffect, useRef, useState } from "react";
+import { View } from "react-native";
+import { eSendEvent, presentSheet } from "../../services/event-manager";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { eCloseProgressDialog } from "../../utils/events";
+import useTimer from "../../hooks/use-timer";
+import { SIZE } from "../../utils/size";
+import { Button } from "../ui/button";
+import { IconButton } from "../ui/icon-button";
+import Input from "../ui/input";
+import { PressableButton } from "../ui/pressable";
+import Seperator from "../ui/seperator";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import { db } from "../../common/database/index";
+import { ToastEvent } from "../../services/event-manager";
const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const code = useRef();
const [currentMethod, setCurrentMethod] = useState({
method: mfaInfo?.primaryMethod,
@@ -28,10 +28,10 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
const [sending, setSending] = useState(false);
const codeHelpText = {
- app: 'Enter the 6 digit code from your authenticator app to continue logging in',
- sms: 'Enter the 6 digit code sent to your phone number to continue logging in',
- email: 'Enter the 6 digit code sent to your email to continue logging in',
- recoveryCode: 'Enter the 8 digit recovery code to continue logging in'
+ app: "Enter the 6 digit code from your authenticator app to continue logging in",
+ sms: "Enter the 6 digit code sent to your phone number to continue logging in",
+ email: "Enter the 6 digit code sent to your email to continue logging in",
+ recoveryCode: "Enter the 8 digit recovery code to continue logging in"
};
const secondaryMethodsText = {
@@ -42,7 +42,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
};
const onNext = async () => {
- const length = currentMethod.method === 'recoveryCode' ? 8 : 6;
+ const length = currentMethod.method === "recoveryCode" ? 8 : 6;
if (!code.current || code.current.length !== length) return;
console.log(currentMethod.method, code.current);
@@ -53,10 +53,10 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
method: currentMethod.method,
code: code.current
},
- result => {
- console.log('result recieved');
+ (result) => {
+ console.log("result recieved");
if (result) {
- eSendEvent(eCloseProgressDialog, 'two_factor_verify');
+ eSendEvent(eCloseProgressDialog, "two_factor_verify");
}
setLoading(false);
}
@@ -73,38 +73,38 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
const methods = [
{
- id: 'sms',
- title: 'Send code via SMS',
- icon: 'message-plus-outline'
+ id: "sms",
+ title: "Send code via SMS",
+ icon: "message-plus-outline"
},
{
- id: 'email',
- title: 'Send code via email',
- icon: 'email-outline'
+ id: "email",
+ title: "Send code via email",
+ icon: "email-outline"
},
{
- id: 'app',
- title: 'Enter code from authenticator app',
- icon: 'cellphone-key'
+ id: "app",
+ title: "Enter code from authenticator app",
+ icon: "cellphone-key"
},
{
- id: 'recoveryCode',
- title: 'I have a recovery code',
- icon: 'key'
+ id: "recoveryCode",
+ title: "I have a recovery code",
+ icon: "key"
}
];
const getMethods = () => {
return methods.filter(
- m =>
+ (m) =>
m.id === mfaInfo?.primaryMethod ||
m.id === mfaInfo?.secondaryMethod ||
- m.id === 'recoveryCode'
+ m.id === "recoveryCode"
);
};
useEffect(() => {
- if (currentMethod.method === 'sms' || currentMethod.method === 'email') {
+ if (currentMethod.method === "sms" || currentMethod.method === "email") {
onSendCode();
}
}, [currentMethod.method]);
@@ -114,13 +114,13 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
// TODO
setSending(true);
try {
- console.log('sending code', currentMethod.method, mfaInfo.token);
+ console.log("sending code", currentMethod.method, mfaInfo.token);
await db.mfa.sendCode(currentMethod.method, mfaInfo.token);
start(60);
setSending(false);
} catch (e) {
setSending(false);
- ToastEvent.error(e, 'Error sending 2FA Code', 'local');
+ ToastEvent.error(e, "Error sending 2FA Code", "local");
}
};
@@ -128,7 +128,7 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
@@ -143,29 +143,34 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
/>
{currentMethod.method
- ? 'Two factor authentication'
- : 'Select methods for two-factor authentication'}
+ ? "Two factor authentication"
+ : "Select methods for two-factor authentication"}
- {codeHelpText[currentMethod.method] || `Select how you would like to recieve the code`}
+ {codeHelpText[currentMethod.method] ||
+ `Select how you would like to recieve the code`}
- {currentMethod.method === 'sms' || currentMethod.method === 'email' ? (
+ {currentMethod.method === "sms" || currentMethod.method === "email" ? (
@@ -176,11 +181,13 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
{currentMethod.method ? (
<>
{
+ onChangeText={(value) => {
code.current = value;
onNext();
}}
@@ -188,22 +195,24 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
inputStyle={{
fontSize: SIZE.lg,
height: 60,
- textAlign: 'center',
+ textAlign: "center",
letterSpacing: 10,
width: null
}}
- keyboardType={currentMethod.method === 'recoveryCode' ? 'default' : 'numeric'}
+ keyboardType={
+ currentMethod.method === "recoveryCode" ? "default" : "numeric"
+ }
containerStyle={{
height: 60,
borderWidth: 0,
//@ts-ignore
width: null,
- minWidth: '50%'
+ minWidth: "50%"
}}
/>
{
>
) : (
<>
- {getMethods().map(item => (
+ {getMethods().map((item) => (
{
@@ -236,11 +245,11 @@ const TwoFactorVerification = ({ onMfaLogin, mfaInfo }) => {
paddingHorizontal: 12,
paddingVertical: 12,
marginTop: 0,
- flexDirection: 'row',
+ flexDirection: "row",
borderRadius: 0,
- alignItems: 'center',
- width: '100%',
- justifyContent: 'flex-start'
+ alignItems: "center",
+ width: "100%",
+ justifyContent: "flex-start"
}}
>
{
};
TwoFactorVerification.present = (onMfaLogin, data, context) => {
- console.log('presenting sheet');
+ console.log("presenting sheet");
presentSheet({
component: ,
- context: context || 'two_factor_verify',
+ context: context || "two_factor_verify",
onClose: () => {
- console.log('on close called');
+ console.log("on close called");
onMfaLogin();
},
disableClosing: true
diff --git a/apps/mobile/app/components/container/container-header.js b/apps/mobile/app/components/container/container-header.js
index 8134f2f31..a40fbae99 100644
--- a/apps/mobile/app/components/container/container-header.js
+++ b/apps/mobile/app/components/container/container-header.js
@@ -1,18 +1,18 @@
-import React from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useSelectionStore } from '../../stores/use-selection-store';
+import React from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useSelectionStore } from "../../stores/use-selection-store";
export const ContainerHeader = ({ children }) => {
- const colors = useThemeStore(state => state.colors);
- const selectionMode = useSelectionStore(state => state.selectionMode);
+ const colors = useThemeStore((state) => state.colors);
+ const selectionMode = useSelectionStore((state) => state.selectionMode);
return !selectionMode ? (
{children}
diff --git a/apps/mobile/app/components/container/floating-button.js b/apps/mobile/app/components/container/floating-button.js
index efebe95c1..7f7cd3377 100644
--- a/apps/mobile/app/components/container/floating-button.js
+++ b/apps/mobile/app/components/container/floating-button.js
@@ -1,25 +1,30 @@
-import React, { useEffect } from 'react';
-import { Keyboard, Platform, View } from 'react-native';
+import React, { useEffect } from "react";
+import { Keyboard, Platform, View } from "react-native";
import Animated, {
Easing,
useAnimatedStyle,
useSharedValue,
withTiming
-} from 'react-native-reanimated';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { notesnook } from '../../../e2e/test.ids';
-import { editorState } from '../../screens/editor/tiptap/utils';
-import { useSelectionStore } from '../../stores/use-selection-store';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { getElevation, showTooltip, TOOLTIP_POSITIONS } from '../../utils';
-import { normalize, SIZE } from '../../utils/size';
-import { PressableButton } from '../ui/pressable';
+} from "react-native-reanimated";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { notesnook } from "../../../e2e/test.ids";
+import { editorState } from "../../screens/editor/tiptap/utils";
+import { useSelectionStore } from "../../stores/use-selection-store";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { getElevation, showTooltip, TOOLTIP_POSITIONS } from "../../utils";
+import { normalize, SIZE } from "../../utils/size";
+import { PressableButton } from "../ui/pressable";
-export const FloatingButton = ({ title, onPress, color = 'accent', shouldShow = false }) => {
+export const FloatingButton = ({
+ title,
+ onPress,
+ color = "accent",
+ shouldShow = false
+}) => {
const insets = useSafeAreaInsets();
- const deviceMode = useSettingStore(state => state.deviceMode);
- const selectionMode = useSelectionStore(state => state.selectionMode);
+ const deviceMode = useSettingStore((state) => state.deviceMode);
+ const selectionMode = useSelectionStore((state) => state.selectionMode);
const translate = useSharedValue(0);
const animatedStyle = useAnimatedStyle(() => {
@@ -48,19 +53,19 @@ export const FloatingButton = ({ title, onPress, color = 'accent', shouldShow =
const onKeyboardHide = async () => {
editorState().keyboardState = false;
- if (deviceMode !== 'mobile') return;
+ if (deviceMode !== "mobile") return;
animate(0);
};
const onKeyboardShow = async () => {
editorState().keyboardState = true;
- if (deviceMode !== 'mobile') return;
+ if (deviceMode !== "mobile") return;
animate(150);
};
useEffect(() => {
- let sub1 = Keyboard.addListener('keyboardDidShow', onKeyboardShow);
- let sub2 = Keyboard.addListener('keyboardDidHide', onKeyboardHide);
+ let sub1 = Keyboard.addListener("keyboardDidShow", onKeyboardShow);
+ let sub2 = Keyboard.addListener("keyboardDidHide", onKeyboardHide);
return () => {
sub1?.remove();
sub2?.remove();
@@ -72,13 +77,13 @@ export const FloatingButton = ({ title, onPress, color = 'accent', shouldShow =
iPad: 20
};
- return deviceMode !== 'mobile' && !shouldShow ? null : (
+ return deviceMode !== "mobile" && !shouldShow ? null : (
{
+ onLongPress={(event) => {
showTooltip(event, title, TOOLTIP_POSITIONS.LEFT);
}}
onPress={onPress}
>
diff --git a/apps/mobile/app/components/container/index.js b/apps/mobile/app/components/container/index.js
index 58904d153..4d6f1a595 100644
--- a/apps/mobile/app/components/container/index.js
+++ b/apps/mobile/app/components/container/index.js
@@ -1,16 +1,18 @@
-import React from 'react';
-import { KeyboardAvoidingView, Platform, SafeAreaView } from 'react-native';
-import { useSettingStore } from '../../stores/use-setting-store';
-import useIsFloatingKeyboard from '../../hooks/use-is-floating-keyboard';
-import { Header } from '../header';
-import SelectionHeader from '../selection-header';
+import React from "react";
+import { KeyboardAvoidingView, Platform, SafeAreaView } from "react-native";
+import { useSettingStore } from "../../stores/use-setting-store";
+import useIsFloatingKeyboard from "../../hooks/use-is-floating-keyboard";
+import { Header } from "../header";
+import SelectionHeader from "../selection-header";
export const Container = ({ children }) => {
const floating = useIsFloatingKeyboard();
- const introCompleted = useSettingStore(state => state.settings.introCompleted);
+ const introCompleted = useSettingStore(
+ (state) => state.settings.introCompleted
+ );
return (
{
{!introCompleted ? null : (
diff --git a/apps/mobile/app/components/delay-layout/default-placeholder.tsx b/apps/mobile/app/components/delay-layout/default-placeholder.tsx
index d780c8dfe..075853388 100644
--- a/apps/mobile/app/components/delay-layout/default-placeholder.tsx
+++ b/apps/mobile/app/components/delay-layout/default-placeholder.tsx
@@ -1,29 +1,31 @@
-import React from 'react';
-import { View } from 'react-native';
-import { useMessageStore } from '../../stores/use-message-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { COLORS_NOTE } from '../../utils/color-scheme';
-import { hexToRGBA } from '../../utils/color-scheme/utils';
+import React from "react";
+import { View } from "react-native";
+import { useMessageStore } from "../../stores/use-message-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { COLORS_NOTE } from "../../utils/color-scheme";
+import { hexToRGBA } from "../../utils/color-scheme/utils";
export const DefaultPlaceholder = ({ color }: { color: string }) => {
- const colors = useThemeStore(state => state.colors);
- const message = useMessageStore(state => state.message);
- const annoucements = useMessageStore(state => state.announcements);
+ const colors = useThemeStore((state) => state.colors);
+ const message = useMessageStore((state) => state.message);
+ const annoucements = useMessageStore((state) => state.announcements);
const hasAnnoucements = annoucements.length > 0;
//@ts-ignore
- const shadeColor = color ? hexToRGBA(COLORS_NOTE[color?.toLowerCase()], 0.15) : colors.shade;
+ const shadeColor = color
+ ? hexToRGBA(COLORS_NOTE[color?.toLowerCase()], 0.15)
+ : colors.shade;
return (
{hasAnnoucements ? (
{
{message ? (
@@ -106,15 +108,15 @@ export const DefaultPlaceholder = ({ color }: { color: string }) => {
{
{
/>
{
diff --git a/apps/mobile/app/components/delay-layout/index.tsx b/apps/mobile/app/components/delay-layout/index.tsx
index 573d7f90d..9c326f175 100644
--- a/apps/mobile/app/components/delay-layout/index.tsx
+++ b/apps/mobile/app/components/delay-layout/index.tsx
@@ -1,15 +1,15 @@
-import React from 'react';
-import { ViewProps } from 'react-native';
-import Animated, { FadeOutUp } from 'react-native-reanimated';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useDelayLayout } from '../../hooks/use-delay-layout';
-import { DefaultPlaceholder } from './default-placeholder';
-import { SettingsPlaceholder } from './settings-placeholder';
+import React from "react";
+import { ViewProps } from "react-native";
+import Animated, { FadeOutUp } from "react-native-reanimated";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useDelayLayout } from "../../hooks/use-delay-layout";
+import { DefaultPlaceholder } from "./default-placeholder";
+import { SettingsPlaceholder } from "./settings-placeholder";
interface IDelayLayoutProps extends ViewProps {
delay?: number;
wait?: boolean;
- type?: 'default' | 'settings';
+ type?: "default" | "settings";
color?: string;
animated?: boolean;
}
@@ -19,10 +19,15 @@ const placeholder = {
settings: SettingsPlaceholder
};
-export default function DelayLayout({ animated = true, ...props }: IDelayLayoutProps) {
- const colors = useThemeStore(state => state.colors);
- const loading = useDelayLayout(!props.delay || props.delay < 300 ? 300 : props.delay);
- const Placeholder = placeholder[props.type || 'default'];
+export default function DelayLayout({
+ animated = true,
+ ...props
+}: IDelayLayoutProps) {
+ const colors = useThemeStore((state) => state.colors);
+ const loading = useDelayLayout(
+ !props.delay || props.delay < 300 ? 300 : props.delay
+ );
+ const Placeholder = placeholder[props.type || "default"];
return loading || props.wait ? (
{
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
@@ -19,12 +19,12 @@ export const SettingsPlaceholder = () => {
/>
@@ -60,14 +60,14 @@ export const SettingsPlaceholder = () => {
{
backgroundColor: colors.nav,
borderRadius: 100,
marginLeft: 15,
- alignItems: 'flex-end',
- justifyContent: 'center',
+ alignItems: "flex-end",
+ justifyContent: "center",
paddingHorizontal: 4
}}
>
diff --git a/apps/mobile/app/components/dialog-provider/index.js b/apps/mobile/app/components/dialog-provider/index.js
index 2bb645eaf..031788ac6 100644
--- a/apps/mobile/app/components/dialog-provider/index.js
+++ b/apps/mobile/app/components/dialog-provider/index.js
@@ -1,33 +1,33 @@
-import React from 'react';
-import { useNoteStore } from '../../stores/use-notes-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { AnnouncementDialog } from '../announcements';
-import { AttachmentDialog } from '../attachments';
-import Auth from '../auth';
-import AuthModal from '../auth/auth-modal';
-import { SessionExpired } from '../auth/session-expired';
-import { Dialog } from '../dialog';
-import { AddTopicDialog } from '../dialogs/add-topic';
-import ResultDialog from '../dialogs/result';
-import { VaultDialog } from '../dialogs/vault';
-import ImagePreview from '../image-preview';
-import MergeConflicts from '../merge-conflicts';
-import PremiumDialog from '../premium';
-import { Expiring } from '../premium/expiring';
-import SheetProvider from '../sheet-provider';
-import { AddNotebookSheet } from '../sheets/add-notebook';
-import AddToNotebookSheet from '../sheets/add-to';
-import ExportNotesSheet from '../sheets/export-notes';
-import ManageTagsSheet from '../sheets/manage-tags';
-import PublishNoteSheet from '../sheets/publish-note';
-import RateAppSheet from '../sheets/rate-app';
-import RecoveryKeySheet from '../sheets/recovery-key';
-import RestoreDataSheet from '../sheets/restore-data';
+import React from "react";
+import { useNoteStore } from "../../stores/use-notes-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { AnnouncementDialog } from "../announcements";
+import { AttachmentDialog } from "../attachments";
+import Auth from "../auth";
+import AuthModal from "../auth/auth-modal";
+import { SessionExpired } from "../auth/session-expired";
+import { Dialog } from "../dialog";
+import { AddTopicDialog } from "../dialogs/add-topic";
+import ResultDialog from "../dialogs/result";
+import { VaultDialog } from "../dialogs/vault";
+import ImagePreview from "../image-preview";
+import MergeConflicts from "../merge-conflicts";
+import PremiumDialog from "../premium";
+import { Expiring } from "../premium/expiring";
+import SheetProvider from "../sheet-provider";
+import { AddNotebookSheet } from "../sheets/add-notebook";
+import AddToNotebookSheet from "../sheets/add-to";
+import ExportNotesSheet from "../sheets/export-notes";
+import ManageTagsSheet from "../sheets/manage-tags";
+import PublishNoteSheet from "../sheets/publish-note";
+import RateAppSheet from "../sheets/rate-app";
+import RecoveryKeySheet from "../sheets/recovery-key";
+import RestoreDataSheet from "../sheets/restore-data";
const DialogProvider = React.memo(
() => {
- const colors = useThemeStore(state => state.colors);
- const loading = useNoteStore(state => state.loading);
+ const colors = useThemeStore((state) => state.colors);
+ const loading = useNoteStore((state) => state.loading);
return (
<>
diff --git a/apps/mobile/app/components/dialog-provider/recievers.js b/apps/mobile/app/components/dialog-provider/recievers.js
index f1f439563..54da9358d 100644
--- a/apps/mobile/app/components/dialog-provider/recievers.js
+++ b/apps/mobile/app/components/dialog-provider/recievers.js
@@ -1,4 +1,4 @@
-import { eSendEvent } from '../../services/event-manager';
+import { eSendEvent } from "../../services/event-manager";
import {
eCloseActionSheet,
eCloseAddNotebookDialog,
@@ -8,7 +8,7 @@ import {
eOpenAddNotebookDialog,
eOpenAddTopicDialog,
eOpenMoveNoteDialog
-} from '../../utils/events';
+} from "../../utils/events";
export const ActionSheetEvent = (item, buttons) => {
eSendEvent(eOpenActionSheet, {
@@ -27,15 +27,15 @@ export const moveNoteHideEvent = () => {
eSendEvent(eCloseMoveNoteDialog);
};
-export const AddNotebookEvent = notebook => {
+export const AddNotebookEvent = (notebook) => {
eSendEvent(eOpenAddNotebookDialog, notebook);
};
-export const HideAddNotebookEvent = notebook => {
+export const HideAddNotebookEvent = (notebook) => {
eSendEvent(eCloseAddNotebookDialog, notebook);
};
-export const AddTopicEvent = topic => {
+export const AddTopicEvent = (topic) => {
eSendEvent(eOpenAddTopicDialog, topic);
};
-export const HideAddTopicEvent = notebook => {
+export const HideAddTopicEvent = (notebook) => {
eSendEvent(eCloseAddTopicDialog, notebook);
};
diff --git a/apps/mobile/app/components/dialog/base-dialog.js b/apps/mobile/app/components/dialog/base-dialog.js
index ac6ae3a4f..bbe57b770 100644
--- a/apps/mobile/app/components/dialog/base-dialog.js
+++ b/apps/mobile/app/components/dialog/base-dialog.js
@@ -1,4 +1,4 @@
-import React, { useEffect } from 'react';
+import React, { useEffect } from "react";
import {
KeyboardAvoidingView,
Modal,
@@ -7,17 +7,17 @@ import {
StyleSheet,
TouchableOpacity,
View
-} from 'react-native';
-import { useSettingStore } from '../../stores/use-setting-store';
-import useIsFloatingKeyboard from '../../hooks/use-is-floating-keyboard';
-import { BouncingView } from '../ui/transitions/bouncing-view';
+} from "react-native";
+import { useSettingStore } from "../../stores/use-setting-store";
+import useIsFloatingKeyboard from "../../hooks/use-is-floating-keyboard";
+import { BouncingView } from "../ui/transitions/bouncing-view";
const BaseDialog = ({
visible,
onRequestClose,
children,
onShow,
- animation = 'fade',
+ animation = "fade",
premium,
statusBarTranslucent = true,
transparent,
@@ -46,11 +46,11 @@ const BaseDialog = ({
animated
statusBarTranslucent={statusBarTranslucent}
supportedOrientations={[
- 'portrait',
- 'portrait-upside-down',
- 'landscape',
- 'landscape-left',
- 'landscape-right'
+ "portrait",
+ "portrait-upside-down",
+ "landscape",
+ "landscape-left",
+ "landscape-right"
]}
onShow={() => {
if (onShow) {
@@ -67,10 +67,17 @@ const BaseDialog = ({
>
-
+
@@ -97,15 +108,15 @@ const BaseDialog = ({
const styles = StyleSheet.create({
backdrop: {
- width: '100%',
- height: '100%',
- justifyContent: 'center',
- alignItems: 'center'
+ width: "100%",
+ height: "100%",
+ justifyContent: "center",
+ alignItems: "center"
},
overlayButton: {
- width: '100%',
- height: '100%',
- position: 'absolute'
+ width: "100%",
+ height: "100%",
+ position: "absolute"
}
});
diff --git a/apps/mobile/app/components/dialog/dialog-buttons.js b/apps/mobile/app/components/dialog/dialog-buttons.js
index 14489cc6e..12019087e 100644
--- a/apps/mobile/app/components/dialog/dialog-buttons.js
+++ b/apps/mobile/app/components/dialog/dialog-buttons.js
@@ -1,22 +1,22 @@
-import React from 'react';
-import { ActivityIndicator, StyleSheet, View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { SIZE } from '../../utils/size';
-import { Button } from '../ui/button';
-import Paragraph from '../ui/typography/paragraph';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { notesnook } from '../../../e2e/test.ids';
+import React from "react";
+import { ActivityIndicator, StyleSheet, View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { SIZE } from "../../utils/size";
+import { Button } from "../ui/button";
+import Paragraph from "../ui/typography/paragraph";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { notesnook } from "../../../e2e/test.ids";
const DialogButtons = ({
onPressPositive,
onPressNegative,
positiveTitle,
- negativeTitle = 'Cancel',
+ negativeTitle = "Cancel",
loading,
doneText,
positiveType
}) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
-
- {' ' + doneText}
+
+ {" " + doneText}
) : (
@@ -49,8 +53,8 @@ const DialogButtons = ({
) : null}
@@ -83,9 +87,9 @@ export default DialogButtons;
const styles = StyleSheet.create({
container: {
- justifyContent: 'space-between',
- alignItems: 'center',
- flexDirection: 'row',
+ justifyContent: "space-between",
+ alignItems: "center",
+ flexDirection: "row",
marginTop: 10
}
});
diff --git a/apps/mobile/app/components/dialog/dialog-container.js b/apps/mobile/app/components/dialog/dialog-container.js
index d1c5a5e6c..e3e3ccd8b 100644
--- a/apps/mobile/app/components/dialog/dialog-container.js
+++ b/apps/mobile/app/components/dialog/dialog-container.js
@@ -1,18 +1,18 @@
-import React from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { DDS } from '../../services/device-detection';
-import { getElevation } from '../../utils';
+import React from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { DDS } from "../../services/device-detection";
+import { getElevation } from "../../utils";
const DialogContainer = ({ width, height, ...restProps }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
void;
loading?: boolean;
title?: string;
- type?: PressableButtonProps['type'];
+ type?: PressableButtonProps["type"];
};
paragraphColor?: string;
padding?: number;
@@ -34,33 +34,39 @@ const DialogHeader = ({
centered,
titlePart
}: DialogHeaderProps) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
<>
-
- {title} {titlePart ? {titlePart} : null}
+
+ {title}{" "}
+ {titlePart ? (
+ {titlePart}
+ ) : null}
{button ? (
@@ -73,7 +79,7 @@ const DialogHeader = ({
loading={button.loading}
fontSize={13}
title={button.title}
- type={button.type || 'grayBg'}
+ type={button.type || "grayBg"}
height={25}
/>
) : null}
@@ -82,9 +88,9 @@ const DialogHeader = ({
{paragraph ? (
diff --git a/apps/mobile/app/components/dialog/functions.ts b/apps/mobile/app/components/dialog/functions.ts
index 3724cfdc2..815403862 100644
--- a/apps/mobile/app/components/dialog/functions.ts
+++ b/apps/mobile/app/components/dialog/functions.ts
@@ -1,5 +1,5 @@
-import { eSendEvent } from '../../services/event-manager';
-import { eCloseSimpleDialog, eOpenSimpleDialog } from '../../utils/events';
+import { eSendEvent } from "../../services/event-manager";
+import { eCloseSimpleDialog, eOpenSimpleDialog } from "../../utils/events";
type DialogInfo = {
title?: string;
@@ -9,20 +9,20 @@ type DialogInfo = {
positivePress?: (value: any) => void;
onClose?: () => void;
positiveType?:
- | 'transparent'
- | 'gray'
- | 'grayBg'
- | 'accent'
- | 'inverted'
- | 'shade'
- | 'error'
- | 'errorShade';
+ | "transparent"
+ | "gray"
+ | "grayBg"
+ | "accent"
+ | "inverted"
+ | "shade"
+ | "error"
+ | "errorShade";
icon?: string;
paragraphColor: string;
input: boolean;
inputPlaceholder: string;
defaultValue: string;
- context: 'global' | 'local';
+ context: "global" | "local";
};
export function presentDialog(data: Partial): void {
diff --git a/apps/mobile/app/components/dialog/index.js b/apps/mobile/app/components/dialog/index.js
index d28479906..f8f3ca0c3 100644
--- a/apps/mobile/app/components/dialog/index.js
+++ b/apps/mobile/app/components/dialog/index.js
@@ -1,36 +1,39 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { DDS } from '../../services/device-detection';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import { getElevation } from '../../utils';
-import { eCloseSimpleDialog, eOpenSimpleDialog } from '../../utils/events';
-import { sleep } from '../../utils/time';
-import Input from '../ui/input';
-import Seperator from '../ui/seperator';
-import { Toast } from '../toast';
-import BaseDialog from './base-dialog';
-import DialogButtons from './dialog-buttons';
-import DialogHeader from './dialog-header';
+import React, { useEffect, useRef, useState } from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { DDS } from "../../services/device-detection";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import { getElevation } from "../../utils";
+import { eCloseSimpleDialog, eOpenSimpleDialog } from "../../utils/events";
+import { sleep } from "../../utils/time";
+import Input from "../ui/input";
+import Seperator from "../ui/seperator";
+import { Toast } from "../toast";
+import BaseDialog from "./base-dialog";
+import DialogButtons from "./dialog-buttons";
+import DialogHeader from "./dialog-header";
-export const Dialog = ({ context = 'global' }) => {
- const colors = useThemeStore(state => state.colors);
+export const Dialog = ({ context = "global" }) => {
+ const colors = useThemeStore((state) => state.colors);
const [visible, setVisible] = useState(false);
const [inputValue, setInputValue] = useState(null);
const inputRef = useRef();
const [dialogInfo, setDialogInfo] = useState({
- title: '',
- paragraph: '',
- positiveText: 'Done',
- negativeText: 'Cancel',
+ title: "",
+ paragraph: "",
+ positiveText: "Done",
+ negativeText: "Cancel",
positivePress: () => {},
onClose: () => {},
- positiveType: 'transparent',
+ positiveType: "transparent",
icon: null,
paragraphColor: colors.pri,
input: false,
- inputPlaceholder: 'Enter some text',
- defaultValue: '',
+ inputPlaceholder: "Enter some text",
+ defaultValue: "",
disableBackdropClosing: false
});
@@ -47,7 +50,9 @@ export const Dialog = ({ context = 'global' }) => {
const onPressPositive = async () => {
if (dialogInfo.positivePress) {
inputRef.current?.blur();
- let result = await dialogInfo.positivePress(inputValue || dialogInfo.defaultValue);
+ let result = await dialogInfo.positivePress(
+ inputValue || dialogInfo.defaultValue
+ );
if (result === false) {
return;
}
@@ -56,8 +61,8 @@ export const Dialog = ({ context = 'global' }) => {
hide();
};
- const show = data => {
- if (!data.context) data.context = 'global';
+ const show = (data) => {
+ if (!data.context) data.context = "global";
if (data.context !== context) return;
setDialogInfo(data);
setVisible(true);
@@ -78,7 +83,7 @@ export const Dialog = ({ context = 'global' }) => {
const style = {
...getElevation(5),
- width: DDS.isTab ? 400 : '85%',
+ width: DDS.isTab ? 400 : "85%",
maxHeight: 450,
borderRadius: 5,
backgroundColor: colors.bg,
@@ -121,7 +126,7 @@ export const Dialog = ({ context = 'global' }) => {
{
+ onChangeText={(value) => {
setInputValue(value);
}}
testID="input-value"
diff --git a/apps/mobile/app/components/dialogs/add-topic/index.js b/apps/mobile/app/components/dialogs/add-topic/index.js
index d344af62a..76d2df73d 100644
--- a/apps/mobile/app/components/dialogs/add-topic/index.js
+++ b/apps/mobile/app/components/dialogs/add-topic/index.js
@@ -1,19 +1,30 @@
-import React, { createRef } from 'react';
-import { Keyboard, LayoutAnimation, UIManager, View } from 'react-native';
-import { Transition, Transitioning, TransitioningView } from 'react-native-reanimated';
-import { useMenuStore } from '../../../stores/use-menu-store';
-import { eSubscribeEvent, eUnSubscribeEvent, ToastEvent } from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import { db } from '../../../common/database';
-import { eCloseAddTopicDialog, eOpenAddTopicDialog } from '../../../utils/events';
-import { sleep } from '../../../utils/time';
-import BaseDialog from '../../dialog/base-dialog';
-import DialogButtons from '../../dialog/dialog-buttons';
-import DialogContainer from '../../dialog/dialog-container';
-import DialogHeader from '../../dialog/dialog-header';
-import Input from '../../ui/input';
-import Seperator from '../../ui/seperator';
-import { Toast } from '../../toast';
+import React, { createRef } from "react";
+import { Keyboard, LayoutAnimation, UIManager, View } from "react-native";
+import {
+ Transition,
+ Transitioning,
+ TransitioningView
+} from "react-native-reanimated";
+import { useMenuStore } from "../../../stores/use-menu-store";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent,
+ ToastEvent
+} from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import { db } from "../../../common/database";
+import {
+ eCloseAddTopicDialog,
+ eOpenAddTopicDialog
+} from "../../../utils/events";
+import { sleep } from "../../../utils/time";
+import BaseDialog from "../../dialog/base-dialog";
+import DialogButtons from "../../dialog/dialog-buttons";
+import DialogContainer from "../../dialog/dialog-container";
+import DialogHeader from "../../dialog/dialog-header";
+import Input from "../../ui/input";
+import Seperator from "../../ui/seperator";
+import { Toast } from "../../toast";
export class AddTopicDialog extends React.Component {
constructor(props) {
@@ -34,11 +45,11 @@ export class AddTopicDialog extends React.Component {
addNewTopic = async () => {
try {
this.setState({ loading: true });
- if (!this.title || this.title?.trim() === '') {
+ if (!this.title || this.title?.trim() === "") {
ToastEvent.show({
- heading: 'Topic title is required',
- type: 'error',
- context: 'local'
+ heading: "Topic title is required",
+ type: "error",
+ context: "local"
});
this.setState({ loading: false });
return;
@@ -54,7 +65,7 @@ export class AddTopicDialog extends React.Component {
}
this.setState({ loading: false });
this.close();
- Navigation.queueRoutesForUpdate('Notebooks', 'Notebook', 'TopicNotes');
+ Navigation.queueRoutesForUpdate("Notebooks", "Notebook", "TopicNotes");
useMenuStore.getState().setMenuPins();
} catch (e) {}
};
@@ -116,9 +127,11 @@ export class AddTopicDialog extends React.Component {
@@ -132,7 +145,7 @@ export class AddTopicDialog extends React.Component {
{
+ onChangeText={(value) => {
this.title = value;
}}
blurOnSubmit={false}
@@ -144,7 +157,7 @@ export class AddTopicDialog extends React.Component {
this.close()}
onPressPositive={() => this.addNewTopic()}
loading={this.state.loading}
diff --git a/apps/mobile/app/components/dialogs/jump-to-section/index.js b/apps/mobile/app/components/dialogs/jump-to-section/index.js
index 4def3def1..1463a8591 100644
--- a/apps/mobile/app/components/dialogs/jump-to-section/index.js
+++ b/apps/mobile/app/components/dialogs/jump-to-section/index.js
@@ -1,26 +1,35 @@
-import React, { useEffect, useState } from 'react';
-import { ScrollView, View } from 'react-native';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { useMessageStore } from '../../../stores/use-message-store';
-import { DDS } from '../../../services/device-detection';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../../services/event-manager';
-import { getElevation } from '../../../utils';
-import { eCloseJumpToDialog, eOpenJumpToDialog, eScrollEvent } from '../../../utils/events';
-import { SIZE } from '../../../utils/size';
-import BaseDialog from '../../dialog/base-dialog';
-import { PressableButton } from '../../ui/pressable';
-import Paragraph from '../../ui/typography/paragraph';
+import React, { useEffect, useState } from "react";
+import { ScrollView, View } from "react-native";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { useMessageStore } from "../../../stores/use-message-store";
+import { DDS } from "../../../services/device-detection";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../../services/event-manager";
+import { getElevation } from "../../../utils";
+import {
+ eCloseJumpToDialog,
+ eOpenJumpToDialog,
+ eScrollEvent
+} from "../../../utils/events";
+import { SIZE } from "../../../utils/size";
+import BaseDialog from "../../dialog/base-dialog";
+import { PressableButton } from "../../ui/pressable";
+import Paragraph from "../../ui/typography/paragraph";
const offsets = [];
let timeout = null;
const JumpToSectionDialog = ({ scrollRef, data, type, screen }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const notes = data;
const [visible, setVisible] = useState(false);
const [currentIndex, setCurrentIndex] = useState(null);
const onPress = (item, index) => {
- let ind = notes.findIndex(i => i.title === item.title && i.type === 'header');
+ let ind = notes.findIndex(
+ (i) => i.title === item.title && i.type === "header"
+ );
console.log(scrollRef.current);
scrollRef.current?.scrollToIndex({
index: ind,
@@ -41,7 +50,7 @@ const JumpToSectionDialog = ({ scrollRef, data, type, screen }) => {
};
}, []);
- const onScroll = data => {
+ const onScroll = (data) => {
let y = data.y;
if (timeout) {
clearTimeout(timeout);
@@ -53,7 +62,7 @@ const JumpToSectionDialog = ({ scrollRef, data, type, screen }) => {
}, 200);
};
- const open = _type => {
+ const open = (_type) => {
if (_type !== type) return;
setVisible(true);
};
@@ -68,10 +77,12 @@ const JumpToSectionDialog = ({ scrollRef, data, type, screen }) => {
const loadOffsets = () => {
notes
- .filter(i => i.type === 'header')
+ .filter((i) => i.type === "header")
.map((item, index) => {
let offset = 35 * index;
- let ind = notes.findIndex(i => i.title === item.title && i.type === 'header');
+ let ind = notes.findIndex(
+ (i) => i.title === item.title && i.type === "header"
+ );
let messageState = useMessageStore.getState().message;
let msgOffset = messageState?.visible ? 60 : 10;
ind = ind + 1;
@@ -92,41 +103,41 @@ const JumpToSectionDialog = ({ scrollRef, data, type, screen }) => {
{notes
- .filter(i => i.type === 'header')
+ .filter((i) => i.type === "header")
.map((item, index) => {
return item.title ? (
onPress(item, index)}
- type={currentIndex === index ? 'accent' : 'transparent'}
+ type={currentIndex === index ? "accent" : "transparent"}
customStyle={{
- minWidth: '20%',
+ minWidth: "20%",
width: null,
paddingHorizontal: 12,
margin: 5,
@@ -137,9 +148,11 @@ const JumpToSectionDialog = ({ scrollRef, data, type, screen }) => {
>
{item.title}
diff --git a/apps/mobile/app/components/dialogs/result/index.js b/apps/mobile/app/components/dialogs/result/index.js
index 96071b787..aa8d0cb68 100644
--- a/apps/mobile/app/components/dialogs/result/index.js
+++ b/apps/mobile/app/components/dialogs/result/index.js
@@ -1,25 +1,29 @@
-import React, { useEffect, useState } from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { DDS } from '../../../services/device-detection';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../../services/event-manager';
-import { getElevation } from '../../../utils';
-import { eCloseResultDialog, eOpenResultDialog } from '../../../utils/events';
-import { SIZE } from '../../../utils/size';
-import { Button } from '../../ui/button';
-import BaseDialog from '../../dialog/base-dialog';
-import Seperator from '../../ui/seperator';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
-import { ProFeatures } from './pro-features';
+import React, { useEffect, useState } from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { DDS } from "../../../services/device-detection";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../../services/event-manager";
+import { getElevation } from "../../../utils";
+import { eCloseResultDialog, eOpenResultDialog } from "../../../utils/events";
+import { SIZE } from "../../../utils/size";
+import { Button } from "../../ui/button";
+import BaseDialog from "../../dialog/base-dialog";
+import Seperator from "../../ui/seperator";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
+import { ProFeatures } from "./pro-features";
const ResultDialog = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [visible, setVisible] = useState(false);
const [dialogData, setDialogData] = useState({
- title: 'Thank you for signing up!',
- paragraph: 'Try out all features of Notesnook free for 7 days. No limitations. No commitments.',
- button: 'Start taking notes'
+ title: "Thank you for signing up!",
+ paragraph:
+ "Try out all features of Notesnook free for 7 days. No limitations. No commitments.",
+ button: "Start taking notes"
});
useEffect(() => {
eSubscribeEvent(eOpenResultDialog, open);
@@ -30,7 +34,7 @@ const ResultDialog = () => {
};
}, []);
- const open = data => {
+ const open = (data) => {
if (data) {
setDialogData(data);
}
@@ -46,23 +50,23 @@ const ResultDialog = () => {
{
color={colors.icon}
size={SIZE.md}
style={{
- alignSelf: 'center',
- textAlign: 'center',
- maxWidth: '80%',
+ alignSelf: "center",
+ textAlign: "center",
+ maxWidth: "80%",
lineHeight: SIZE.sm + 5
}}
>
@@ -88,8 +92,8 @@ const ResultDialog = () => {
@@ -99,7 +103,7 @@ const ResultDialog = () => {
{
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
<>
{[
{
- content: 'Unlock unlimited notebooks, tags, colors. Organize like a pro'
+ content:
+ "Unlock unlimited notebooks, tags, colors. Organize like a pro"
},
{
- content: 'Attach files upto 500MB, upload 4K images with unlimited storage'
+ content:
+ "Attach files upto 500MB, upload 4K images with unlimited storage"
},
{
- content: 'Instantly sync to unlimited devices'
+ content: "Instantly sync to unlimited devices"
},
{
- content: 'A private vault to keep everything imporant always locked'
+ content: "A private vault to keep everything imporant always locked"
},
{
- content: 'Rich note editing experience with markdown, tables, checklists and more'
+ content:
+ "Rich note editing experience with markdown, tables, checklists and more"
},
{
- content: 'Export your notes in Pdf, markdown and html formats'
+ content: "Export your notes in Pdf, markdown and html formats"
}
]
.slice(0, count)
- .map(item => (
+ .map((item) => (
- {item.content}
+
+ {item.content}
+
))}
{
}}
size={SIZE.xs + 1}
style={{
- textDecorationLine: 'underline',
+ textDecorationLine: "underline",
color: colors.icon
}}
>
diff --git a/apps/mobile/app/components/dialogs/vault/index.js b/apps/mobile/app/components/dialogs/vault/index.js
index f064358a8..f70703190 100644
--- a/apps/mobile/app/components/dialogs/vault/index.js
+++ b/apps/mobile/app/components/dialogs/vault/index.js
@@ -1,39 +1,39 @@
-import Clipboard from '@react-native-clipboard/clipboard';
-import React, { Component, createRef } from 'react';
-import { InteractionManager, View } from 'react-native';
-import Share from 'react-native-share';
-import { notesnook } from '../../../../e2e/test.ids';
-import { editorController } from '../../../screens/editor/tiptap/utils';
-import BiometricService from '../../../services/biometrics';
-import { DDS } from '../../../services/device-detection';
+import Clipboard from "@react-native-clipboard/clipboard";
+import React, { Component, createRef } from "react";
+import { InteractionManager, View } from "react-native";
+import Share from "react-native-share";
+import { notesnook } from "../../../../e2e/test.ids";
+import { editorController } from "../../../screens/editor/tiptap/utils";
+import BiometricService from "../../../services/biometrics";
+import { DDS } from "../../../services/device-detection";
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent,
ToastEvent
-} from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import SearchService from '../../../services/search';
-import { getElevation, toTXT } from '../../../utils';
-import { db } from '../../../common/database';
+} from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import SearchService from "../../../services/search";
+import { getElevation, toTXT } from "../../../utils";
+import { db } from "../../../common/database";
import {
eClearEditor,
eCloseActionSheet,
eCloseVaultDialog,
eOnLoadNote,
eOpenVaultDialog
-} from '../../../utils/events';
-import { deleteItems } from '../../../utils/functions';
-import { tabBarRef } from '../../../utils/global-refs';
-import { sleep } from '../../../utils/time';
-import BaseDialog from '../../dialog/base-dialog';
-import DialogButtons from '../../dialog/dialog-buttons';
-import DialogHeader from '../../dialog/dialog-header';
-import { Toast } from '../../toast';
-import { Button } from '../../ui/button';
-import Input from '../../ui/input';
-import Seperator from '../../ui/seperator';
-import Paragraph from '../../ui/typography/paragraph';
+} from "../../../utils/events";
+import { deleteItems } from "../../../utils/functions";
+import { tabBarRef } from "../../../utils/global-refs";
+import { sleep } from "../../../utils/time";
+import BaseDialog from "../../dialog/base-dialog";
+import DialogButtons from "../../dialog/dialog-buttons";
+import DialogHeader from "../../dialog/dialog-header";
+import { Toast } from "../../toast";
+import { Button } from "../../ui/button";
+import Input from "../../ui/input";
+import Seperator from "../../ui/seperator";
+import Paragraph from "../../ui/typography/paragraph";
let Keychain;
const passInputRef = createRef();
@@ -62,7 +62,7 @@ export class VaultDialog extends Component {
changePassword: false,
copyNote: false,
revokeFingerprintAccess: false,
- title: 'Unlock Note',
+ title: "Unlock Note",
description: null,
clearVault: false,
deleteVault: false,
@@ -72,45 +72,45 @@ export class VaultDialog extends Component {
this.confirmPassword = null;
this.newPassword = null;
(this.title = !this.state.novault
- ? 'Create Vault'
+ ? "Create Vault"
: this.state.fingerprintAccess
- ? 'Vault Fingerprint Unlock'
+ ? "Vault Fingerprint Unlock"
: this.state.revokeFingerprintAccess
- ? 'Revoke Vault Fingerprint Unlock'
+ ? "Revoke Vault Fingerprint Unlock"
: this.state.changePassword
- ? 'Change Vault Password'
+ ? "Change Vault Password"
: this.state.note.locked
? this.state.deleteNote
- ? 'Delete note'
+ ? "Delete note"
: this.state.share
- ? 'Share note'
+ ? "Share note"
: this.state.copyNote
- ? 'Copy note'
+ ? "Copy note"
: this.state.goToEditor
- ? 'Unlock note'
- : 'Unlock note'
- : 'Lock note'),
+ ? "Unlock note"
+ : "Unlock note"
+ : "Lock note"),
(this.description = !this.state.novault
- ? 'Set a password to create vault'
+ ? "Set a password to create vault"
: this.state.fingerprintAccess
- ? 'Enter vault password to enable fingerprint unlocking.'
+ ? "Enter vault password to enable fingerprint unlocking."
: this.state.revokeFingerprintAccess
- ? 'Disable vault fingerprint unlock '
+ ? "Disable vault fingerprint unlock "
: this.state.changePassword
- ? 'Setup a new password for the vault.'
+ ? "Setup a new password for the vault."
: this.state.permanant
- ? 'Enter password to remove note from vault.'
+ ? "Enter password to remove note from vault."
: this.state.note.locked
? this.state.deleteNote
- ? 'Unlock note to delete it. If biometrics are not working, you can enter device pin to unlock vault.'
+ ? "Unlock note to delete it. If biometrics are not working, you can enter device pin to unlock vault."
: this.state.share
- ? 'Unlock note to share it. If biometrics are not working, you can enter device pin to unlock vault.'
+ ? "Unlock note to share it. If biometrics are not working, you can enter device pin to unlock vault."
: this.state.copyNote
- ? 'Unlock note to copy it. If biometrics are not working, you can enter device pin to unlock vault.'
+ ? "Unlock note to copy it. If biometrics are not working, you can enter device pin to unlock vault."
: this.state.goToEditor
- ? 'Unlock note to open it in editor. If biometrics are not working, you can enter device pin to unlock vault.'
- : 'Enter vault password to unlock note. If biometrics are not working, you can enter device pin to unlock vault.'
- : 'Enter vault password to lock note. If biometrics are not working, you can enter device pin to lock note.');
+ ? "Unlock note to open it in editor. If biometrics are not working, you can enter device pin to unlock vault."
+ : "Enter vault password to unlock note. If biometrics are not working, you can enter device pin to unlock vault."
+ : "Enter vault password to lock note. If biometrics are not working, you can enter device pin to lock note.");
}
componentDidMount() {
@@ -127,13 +127,13 @@ export class VaultDialog extends Component {
*
* @param {import('../../../services/event-manager').vaultType} data
*/
- open = async data => {
+ open = async (data) => {
if (!Keychain) {
- Keychain = require('react-native-keychain');
+ Keychain = require("react-native-keychain");
}
let biometry = await BiometricService.isBiometryAvailable();
let available = false;
- let fingerprint = await BiometricService.hasInternetCredentials('nn_vault');
+ let fingerprint = await BiometricService.hasInternetCredentials("nn_vault");
if (biometry) {
available = true;
@@ -181,19 +181,19 @@ export class VaultDialog extends Component {
if (this.state.loading) {
ToastEvent.show({
heading: this.state.title,
- message: 'Please wait and do not close the app.',
- type: 'success',
- context: 'local'
+ message: "Please wait and do not close the app.",
+ type: "success",
+ context: "local"
});
return;
}
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'TopicNotes',
- 'TaggedNotes',
- 'ColoredNotes'
+ "Notes",
+ "Favorites",
+ "TopicNotes",
+ "TaggedNotes",
+ "ColoredNotes"
);
this.password = null;
@@ -223,19 +223,19 @@ export class VaultDialog extends Component {
if (!this.password) {
ToastEvent.show({
- heading: 'Password not entered',
- message: 'Enter a password for the vault and try again.',
- type: 'error',
- context: 'local'
+ heading: "Password not entered",
+ message: "Enter a password for the vault and try again.",
+ type: "error",
+ context: "local"
});
return;
}
if (this.password && this.password.length < 3) {
ToastEvent.show({
- heading: 'Password too short',
- message: 'Password must be longer than 3 characters.',
- type: 'error',
- context: 'local'
+ heading: "Password too short",
+ message: "Password must be longer than 3 characters.",
+ type: "error",
+ context: "local"
});
return;
@@ -244,9 +244,9 @@ export class VaultDialog extends Component {
if (!this.state.novault) {
if (this.password !== this.confirmPassword) {
ToastEvent.show({
- heading: 'Passwords do not match',
- type: 'error',
- context: 'local'
+ heading: "Passwords do not match",
+ type: "error",
+ context: "local"
});
this.setState({
passwordsDontMatch: true
@@ -262,7 +262,7 @@ export class VaultDialog extends Component {
db.vault
.changePassword(this.password, this.newPassword)
- .then(result => {
+ .then((result) => {
this.setState({
loading: false
});
@@ -270,32 +270,32 @@ export class VaultDialog extends Component {
this._enrollFingerprint(this.newPassword);
}
ToastEvent.show({
- heading: 'Vault password updated successfully',
- type: 'success',
- context: 'global'
+ heading: "Vault password updated successfully",
+ type: "success",
+ context: "global"
});
this.close();
})
- .catch(e => {
+ .catch((e) => {
this.setState({
loading: false
});
if (e.message === db.vault.ERRORS.wrongPassword) {
ToastEvent.show({
- heading: 'Incorrect password',
- message: 'Please enter the correct password and try again',
- type: 'error',
- context: 'local'
+ heading: "Incorrect password",
+ message: "Please enter the correct password and try again",
+ type: "error",
+ context: "local"
});
}
});
} else if (this.state.locked) {
if (!this.password || this.password.trim() === 0) {
ToastEvent.show({
- heading: 'Incorrect password',
- message: 'Please enter the correct password and try again',
- type: 'error',
- context: 'local'
+ heading: "Incorrect password",
+ message: "Please enter the correct password and try again",
+ type: "error",
+ context: "local"
});
this.setState({
wrongPassword: true
@@ -313,7 +313,7 @@ export class VaultDialog extends Component {
});
await this._lockNote();
})
- .catch(e => {
+ .catch((e) => {
this._takeErrorAction(e);
});
}
@@ -335,17 +335,17 @@ export class VaultDialog extends Component {
if (!(await db.user.getUser())) verified = true;
if (verified) {
await db.vault.delete(this.state.deleteAll);
- eSendEvent('vaultUpdated');
+ eSendEvent("vaultUpdated");
this.setState({
loading: false
});
this.close();
} else {
ToastEvent.show({
- heading: 'Account password incorrect',
- message: 'Please enter correct password for your account.',
- type: 'error',
- context: 'local'
+ heading: "Account password incorrect",
+ message: "Please enter correct password for your account.",
+ type: "error",
+ context: "local"
});
}
} catch (e) {}
@@ -364,13 +364,13 @@ export class VaultDialog extends Component {
loading: false
});
this.close();
- eSendEvent('vaultUpdated');
+ eSendEvent("vaultUpdated");
} catch (e) {
ToastEvent.show({
- heading: 'Vault password incorrect',
- message: 'Please enter correct password to clear vault.',
- type: 'error',
- context: 'local'
+ heading: "Vault password incorrect",
+ message: "Please enter correct password to clear vault.",
+ type: "error",
+ context: "local"
});
}
this.setState({
@@ -381,11 +381,11 @@ export class VaultDialog extends Component {
async _lockNote() {
if (!this.password || this.password.trim() === 0) {
ToastEvent.show({
- heading: 'Incorrect password',
- type: 'error',
- context: 'local'
+ heading: "Incorrect password",
+ type: "error",
+ context: "local"
});
- console.log('returning from here');
+ console.log("returning from here");
return;
} else {
await db.vault.add(this.state.note.id);
@@ -394,9 +394,9 @@ export class VaultDialog extends Component {
}
this.close();
ToastEvent.show({
- message: 'Note locked successfully',
- type: 'error',
- context: 'local'
+ message: "Note locked successfully",
+ type: "error",
+ context: "local"
});
this.setState({
loading: false
@@ -407,10 +407,10 @@ export class VaultDialog extends Component {
async _unlockNote() {
if (!this.password || this.password.trim() === 0) {
ToastEvent.show({
- heading: 'Incorrect password',
- message: 'Please enter the correct password and try again',
- type: 'error',
- context: 'local'
+ heading: "Incorrect password",
+ message: "Please enter the correct password and try again",
+ type: "error",
+ context: "local"
});
return;
}
@@ -464,20 +464,21 @@ export class VaultDialog extends Component {
this.setState({
loading: false
});
- eSendEvent('vaultUpdated');
+ eSendEvent("vaultUpdated");
ToastEvent.show({
- heading: 'Biometric unlocking enabled!',
- message: 'Now you can unlock notes in vault with biometrics.',
- type: 'success',
- context: 'global'
+ heading: "Biometric unlocking enabled!",
+ message: "Now you can unlock notes in vault with biometrics.",
+ type: "success",
+ context: "global"
});
this.close();
} catch (e) {
ToastEvent.show({
- heading: 'Incorrect password',
- message: 'Please enter the correct vault password to enable biometrics.',
- type: 'error',
- context: 'local'
+ heading: "Incorrect password",
+ message:
+ "Please enter the correct vault password to enable biometrics.",
+ type: "error",
+ context: "local"
});
this.setState({
loading: false
@@ -506,17 +507,17 @@ export class VaultDialog extends Component {
loading: false
});
ToastEvent.show({
- heading: 'Note added to vault',
- type: 'success',
- context: 'global'
+ heading: "Note added to vault",
+ type: "success",
+ context: "global"
});
this.close();
} else {
- eSendEvent('vaultUpdated');
+ eSendEvent("vaultUpdated");
ToastEvent.show({
- heading: 'Vault created successfully',
- type: 'success',
- context: 'global'
+ heading: "Vault created successfully",
+ type: "success",
+ context: "global"
});
this.close();
}
@@ -525,15 +526,15 @@ export class VaultDialog extends Component {
_permanantUnlock() {
db.vault
.remove(this.state.note.id, this.password)
- .then(r => {
+ .then((r) => {
ToastEvent.show({
- heading: 'Note permanantly unlocked.',
- type: 'success',
- context: 'global'
+ heading: "Note permanantly unlocked.",
+ type: "success",
+ context: "global"
});
this.close();
})
- .catch(e => {
+ .catch((e) => {
this._takeErrorAction(e);
});
}
@@ -551,10 +552,10 @@ export class VaultDialog extends Component {
async _copyNote(note) {
Clipboard.setString(await toTXT(note));
ToastEvent.show({
- heading: 'Note copied',
- type: 'success',
- message: 'Note has been copied to clipboard!',
- context: 'global'
+ heading: "Note copied",
+ type: "success",
+ message: "Note has been copied to clipboard!",
+ context: "global"
});
this.close();
}
@@ -563,7 +564,7 @@ export class VaultDialog extends Component {
this.close();
try {
await Share.open({
- heading: 'Share note',
+ heading: "Share note",
failOnCancel: false,
message: await toTXT(note)
});
@@ -571,16 +572,19 @@ export class VaultDialog extends Component {
}
_takeErrorAction(e) {
- if (e.message === db.vault.ERRORS.wrongPassword || e.message === 'FAILURE') {
+ if (
+ e.message === db.vault.ERRORS.wrongPassword ||
+ e.message === "FAILURE"
+ ) {
this.setState({
wrongPassword: true,
visible: true
});
setTimeout(() => {
ToastEvent.show({
- heading: 'Incorrect password',
- type: 'error',
- context: 'local'
+ heading: "Incorrect password",
+ type: "error",
+ context: "local"
});
}, 500);
@@ -591,18 +595,18 @@ export class VaultDialog extends Component {
_revokeFingerprintAccess = async () => {
try {
await BiometricService.resetCredentials();
- eSendEvent('vaultUpdated');
+ eSendEvent("vaultUpdated");
ToastEvent.show({
- heading: 'Biometric unlocking disabled!',
- type: 'success',
- context: 'global'
+ heading: "Biometric unlocking disabled!",
+ type: "success",
+ context: "global"
});
} catch (e) {
ToastEvent.show({
- heading: 'Failed to disable Biometric unlocking.',
+ heading: "Failed to disable Biometric unlocking.",
message: e.message,
- type: 'success',
- context: 'global'
+ type: "success",
+ context: "global"
});
}
};
@@ -663,7 +667,7 @@ export class VaultDialog extends Component {
- {(novault || changePassword || this.state.clearVault || this.state.deleteVault) &&
+ {(novault ||
+ changePassword ||
+ this.state.clearVault ||
+ this.state.deleteVault) &&
!this.state.revokeFingerprintAccess ? (
<>
{
+ onChangeText={(value) => {
this.password = value;
}}
marginBottom={
@@ -702,13 +709,15 @@ export class VaultDialog extends Component {
: 10
}
onSubmit={() => {
- changePassword ? changePassInputRef.current?.focus() : this.onPress;
+ changePassword
+ ? changePassInputRef.current?.focus()
+ : this.onPress;
}}
autoComplete="password"
- returnKeyLabel={changePassword ? 'Next' : this.state.title}
- returnKeyType={changePassword ? 'next' : 'done'}
+ returnKeyLabel={changePassword ? "Next" : this.state.title}
+ returnKeyType={changePassword ? "next" : "done"}
secureTextEntry
- placeholder={changePassword ? 'Current password' : 'Password'}
+ placeholder={changePassword ? "Current password" : "Password"}
/>
{!this.state.biometricUnlock ||
@@ -716,10 +725,12 @@ export class VaultDialog extends Component {
!novault ||
changePassword ? null : (
this._onPressFingerprintAuth('Unlock note', '')}
+ onPress={() =>
+ this._onPressFingerprintAuth("Unlock note", "")
+ }
icon="fingerprint"
width="100%"
- title={'Biometric unlock'}
+ title={"Biometric unlock"}
type="transparent"
/>
)}
@@ -734,13 +745,15 @@ export class VaultDialog extends Component {
})
}
icon={
- this.state.deleteAll ? 'check-circle-outline' : 'checkbox-blank-circle-outline'
+ this.state.deleteAll
+ ? "check-circle-outline"
+ : "checkbox-blank-circle-outline"
}
style={{
marginTop: 10
}}
width="100%"
- title={'Delete all notes'}
+ title={"Delete all notes"}
type="errorShade"
/>
)}
@@ -753,7 +766,7 @@ export class VaultDialog extends Component {
editable={!loading}
testID={notesnook.ids.dialogs.vault.changePwd}
autoCapitalize="none"
- onChangeText={value => {
+ onChangeText={(value) => {
this.newPassword = value;
}}
autoComplete="password"
@@ -761,7 +774,7 @@ export class VaultDialog extends Component {
returnKeyLabel="Change"
returnKeyType="done"
secureTextEntry
- placeholder={'New password'}
+ placeholder={"New password"}
/>
>
) : null}
@@ -772,7 +785,7 @@ export class VaultDialog extends Component {
fwdRef={passInputRef}
autoCapitalize="none"
testID={notesnook.ids.dialogs.vault.pwd}
- onChangeText={value => {
+ onChangeText={(value) => {
this.password = value;
}}
autoComplete="password"
@@ -793,12 +806,12 @@ export class VaultDialog extends Component {
validationType="confirmPassword"
customValidator={() => this.password}
errorMessage="Passwords do not match."
- onErrorCheck={e => null}
+ onErrorCheck={(e) => null}
marginBottom={0}
autoComplete="password"
returnKeyLabel="Create"
returnKeyType="done"
- onChangeText={value => {
+ onChangeText={(value) => {
this.confirmPassword = value;
if (value !== this.password) {
this.setState({
@@ -816,8 +829,12 @@ export class VaultDialog extends Component {
) : null}
- {this.state.biometricUnlock && !this.state.isBiometryEnrolled && novault ? (
- Unlock with password once to enable biometric access.
+ {this.state.biometricUnlock &&
+ !this.state.isBiometryEnrolled &&
+ novault ? (
+
+ Unlock with password once to enable biometric access.
+
) : null}
{this.state.isBiometryAvailable &&
@@ -838,7 +855,7 @@ export class VaultDialog extends Component {
icon="fingerprint"
width="100%"
title="Biometric unlocking"
- type={this.state.biometricUnlock ? 'transparent' : 'gray'}
+ type={this.state.biometricUnlock ? "transparent" : "gray"}
/>
) : null}
@@ -847,29 +864,31 @@ export class VaultDialog extends Component {
onPressNegative={this.close}
onPressPositive={this.onPress}
loading={loading}
- positiveType={deleteVault || clearVault ? 'errorShade' : 'transparent'}
+ positiveType={
+ deleteVault || clearVault ? "errorShade" : "transparent"
+ }
positiveTitle={
deleteVault
- ? 'Delete'
+ ? "Delete"
: clearVault
- ? 'Clear'
+ ? "Clear"
: fingerprintAccess
- ? 'Enable'
+ ? "Enable"
: this.state.revokeFingerprintAccess
- ? 'Revoke'
+ ? "Revoke"
: changePassword
- ? 'Change'
+ ? "Change"
: note.locked
? deleteNote
- ? 'Delete'
+ ? "Delete"
: share
- ? 'Share '
+ ? "Share "
: goToEditor
- ? 'Open'
- : 'Unlock'
+ ? "Open"
+ : "Unlock"
: !note.id
- ? 'Create'
- : 'Lock'
+ ? "Create"
+ : "Lock"
}
/>
diff --git a/apps/mobile/app/components/exception-handler/index.tsx b/apps/mobile/app/components/exception-handler/index.tsx
index 472566b58..461659339 100644
--- a/apps/mobile/app/components/exception-handler/index.tsx
+++ b/apps/mobile/app/components/exception-handler/index.tsx
@@ -1,8 +1,8 @@
-import React from 'react';
-import RNBootSplash from 'react-native-bootsplash';
-import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
-import { Dialog } from '../dialog';
-import { Issue } from '../sheets/github/issue';
+import React from "react";
+import RNBootSplash from "react-native-bootsplash";
+import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";
+import { Dialog } from "../dialog";
+import { Issue } from "../sheets/github/issue";
const error = (
stack: string,
@@ -12,7 +12,10 @@ const error = (
_______________________________
Stacktrace: In ${component}::${stack}`;
-class ExceptionHandler extends React.Component<{ children: React.ReactNode; component: string }> {
+class ExceptionHandler extends React.Component<{
+ children: React.ReactNode;
+ component: string;
+}> {
state: {
error: {
title: string;
@@ -45,8 +48,11 @@ class ExceptionHandler extends React.Component<{ children: React.ReactNode; comp
}}
>
diff --git a/apps/mobile/app/components/header/index.js b/apps/mobile/app/components/header/index.js
index 26b3f62b3..2f0288cc8 100644
--- a/apps/mobile/app/components/header/index.js
+++ b/apps/mobile/app/components/header/index.js
@@ -1,25 +1,30 @@
-import React, { useEffect, useState } from 'react';
-import { Platform, StyleSheet, View } from 'react-native';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { SearchBar } from '../../screens/search/search-bar';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { useSelectionStore } from '../../stores/use-selection-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { eScrollEvent } from '../../utils/events';
-import { LeftMenus } from './left-menus';
-import { RightMenus } from './right-menus';
-import { Title } from './title';
+import React, { useEffect, useState } from "react";
+import { Platform, StyleSheet, View } from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { SearchBar } from "../../screens/search/search-bar";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import useNavigationStore from "../../stores/use-navigation-store";
+import { useSelectionStore } from "../../stores/use-selection-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { eScrollEvent } from "../../utils/events";
+import { LeftMenus } from "./left-menus";
+import { RightMenus } from "./right-menus";
+import { Title } from "./title";
export const Header = React.memo(
() => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const insets = useSafeAreaInsets();
const [hide, setHide] = useState(true);
- const selectionMode = useSelectionStore(state => state.selectionMode);
- const currentScreen = useNavigationStore(state => state.currentScreen?.name);
+ const selectionMode = useSelectionStore((state) => state.selectionMode);
+ const currentScreen = useNavigationStore(
+ (state) => state.currentScreen?.name
+ );
- const onScroll = data => {
+ const onScroll = (data) => {
if (data.y > 150) {
if (!hide) return;
setHide(false);
@@ -42,16 +47,16 @@ export const Header = React.memo(
style={[
styles.container,
{
- marginTop: Platform.OS === 'android' ? insets.top : null,
+ marginTop: Platform.OS === "android" ? insets.top : null,
backgroundColor: colors.bg,
- overflow: 'hidden',
+ overflow: "hidden",
borderBottomWidth: 1,
- borderBottomColor: hide ? 'transparent' : colors.nav,
- justifyContent: 'space-between'
+ borderBottomColor: hide ? "transparent" : colors.nav,
+ justifyContent: "space-between"
}
]}
>
- {currentScreen === 'Search' ? (
+ {currentScreen === "Search" ? (
) : (
<>
@@ -71,24 +76,24 @@ export const Header = React.memo(
const styles = StyleSheet.create({
container: {
- flexDirection: 'row',
+ flexDirection: "row",
zIndex: 11,
height: 50,
maxHeight: 50,
- justifyContent: 'center',
- alignItems: 'center',
+ justifyContent: "center",
+ alignItems: "center",
paddingHorizontal: 12,
- width: '100%'
+ width: "100%"
},
leftBtnContainer: {
- flexDirection: 'row',
- justifyContent: 'flex-start',
- alignItems: 'center',
+ flexDirection: "row",
+ justifyContent: "flex-start",
+ alignItems: "center",
flexShrink: 1
},
leftBtn: {
- justifyContent: 'center',
- alignItems: 'center',
+ justifyContent: "center",
+ alignItems: "center",
height: 40,
width: 40,
borderRadius: 100,
@@ -96,12 +101,12 @@ const styles = StyleSheet.create({
marginRight: 25
},
rightBtnContainer: {
- flexDirection: 'row',
- alignItems: 'center'
+ flexDirection: "row",
+ alignItems: "center"
},
rightBtn: {
- justifyContent: 'center',
- alignItems: 'flex-end',
+ justifyContent: "center",
+ alignItems: "flex-end",
height: 40,
width: 40,
paddingRight: 0
diff --git a/apps/mobile/app/components/header/left-menus.js b/apps/mobile/app/components/header/left-menus.js
index f63a2b87e..67835b88b 100644
--- a/apps/mobile/app/components/header/left-menus.js
+++ b/apps/mobile/app/components/header/left-menus.js
@@ -1,18 +1,18 @@
-import React from 'react';
-import { notesnook } from '../../../e2e/test.ids';
-import { DDS } from '../../services/device-detection';
-import Navigation from '../../services/navigation';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { tabBarRef } from '../../utils/global-refs';
-import { IconButton } from '../ui/icon-button';
+import React from "react";
+import { notesnook } from "../../../e2e/test.ids";
+import { DDS } from "../../services/device-detection";
+import Navigation from "../../services/navigation";
+import useNavigationStore from "../../stores/use-navigation-store";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { tabBarRef } from "../../utils/global-refs";
+import { IconButton } from "../ui/icon-button";
export const LeftMenus = () => {
- const colors = useThemeStore(state => state.colors);
- const deviceMode = useSettingStore(state => state.deviceMode);
- const canGoBack = useNavigationStore(state => state.canGoBack);
- const isTablet = deviceMode === 'tablet';
+ const colors = useThemeStore((state) => state.colors);
+ const deviceMode = useSettingStore((state) => state.deviceMode);
+ const canGoBack = useNavigationStore((state) => state.canGoBack);
+ const isTablet = deviceMode === "tablet";
const onLeftButtonPress = () => {
if (!canGoBack) {
@@ -25,8 +25,8 @@ export const LeftMenus = () => {
}
Navigation.goBack();
if (
- useNavigationStore.getState().currentScreen.name === 'Signup' ||
- useNavigationStore.getState().currentScreen.name === 'Login'
+ useNavigationStore.getState().currentScreen.name === "Signup" ||
+ useNavigationStore.getState().currentScreen.name === "Login"
) {
tabBarRef.current.unlock();
}
@@ -36,8 +36,8 @@ export const LeftMenus = () => {
{
onLongPress={() => {
Navigation.popToTop();
}}
- name={canGoBack ? 'arrow-left' : 'menu'}
+ name={canGoBack ? "arrow-left" : "menu"}
color={colors.pri}
iconStyle={{
marginLeft: canGoBack ? -5 : 0
diff --git a/apps/mobile/app/components/header/right-menus.js b/apps/mobile/app/components/header/right-menus.js
index 6515c2091..a3aafdfe0 100644
--- a/apps/mobile/app/components/header/right-menus.js
+++ b/apps/mobile/app/components/header/right-menus.js
@@ -1,33 +1,33 @@
-import React, { useRef } from 'react';
-import { Platform, StyleSheet, View } from 'react-native';
-import Menu from 'react-native-reanimated-material-menu';
-import { notesnook } from '../../../e2e/test.ids';
-import Navigation from '../../services/navigation';
-import SearchService from '../../services/search';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import { Button } from '../ui/button';
-import { IconButton } from '../ui/icon-button';
+import React, { useRef } from "react";
+import { Platform, StyleSheet, View } from "react-native";
+import Menu from "react-native-reanimated-material-menu";
+import { notesnook } from "../../../e2e/test.ids";
+import Navigation from "../../services/navigation";
+import SearchService from "../../services/search";
+import useNavigationStore from "../../stores/use-navigation-store";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import { Button } from "../ui/button";
+import { IconButton } from "../ui/icon-button";
export const RightMenus = () => {
- const colors = useThemeStore(state => state.colors);
- const deviceMode = useSettingStore(state => state.deviceMode);
- const rightButtons = useNavigationStore(state => state.headerRightButtons);
- const currentScreen = useNavigationStore(state => state.currentScreen.name);
- const buttonAction = useNavigationStore(state => state.buttonAction);
+ const colors = useThemeStore((state) => state.colors);
+ const deviceMode = useSettingStore((state) => state.deviceMode);
+ const rightButtons = useNavigationStore((state) => state.headerRightButtons);
+ const currentScreen = useNavigationStore((state) => state.currentScreen.name);
+ const buttonAction = useNavigationStore((state) => state.buttonAction);
const menuRef = useRef();
return (
- {!currentScreen.startsWith('Settings') ? (
+ {!currentScreen.startsWith("Settings") ? (
{
SearchService.prepareSearch();
Navigation.navigate({
- name: 'Search'
+ name: "Search"
});
}}
testID="icon-search"
@@ -37,11 +37,11 @@ export const RightMenus = () => {
/>
) : null}
- {deviceMode !== 'mobile' ? (
+ {deviceMode !== "mobile" ? (
{
{
title={item.title}
onPress={async () => {
menuRef.current?.hide();
- if (Platform.OS === 'ios') await sleep(300);
+ if (Platform.OS === "ios") await sleep(300);
item.onPress();
}}
/>
@@ -112,12 +112,12 @@ export const RightMenus = () => {
const styles = StyleSheet.create({
rightBtnContainer: {
- flexDirection: 'row',
- alignItems: 'center'
+ flexDirection: "row",
+ alignItems: "center"
},
rightBtn: {
- justifyContent: 'center',
- alignItems: 'center',
+ justifyContent: "center",
+ alignItems: "center",
height: 40,
width: 40,
marginLeft: 10,
diff --git a/apps/mobile/app/components/header/title.js b/apps/mobile/app/components/header/title.js
index c3394a918..c47521495 100644
--- a/apps/mobile/app/components/header/title.js
+++ b/apps/mobile/app/components/header/title.js
@@ -1,40 +1,43 @@
-import React, { useEffect, useState } from 'react';
-import { Platform, View } from 'react-native';
-import Notebook from '../../screens/notebook';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { db } from '../../common/database';
-import { eScrollEvent } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
+import React, { useEffect, useState } from "react";
+import { Platform, View } from "react-native";
+import Notebook from "../../screens/notebook";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import useNavigationStore from "../../stores/use-navigation-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { db } from "../../common/database";
+import { eScrollEvent } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
const titleState = {};
export const Title = () => {
- const colors = useThemeStore(state => state.colors);
- const currentScreen = useNavigationStore(state => state.currentScreen);
- const isNotebook = currentScreen.name === 'Notebook';
- const isTopic = currentScreen?.name === 'TopicNotes';
+ const colors = useThemeStore((state) => state.colors);
+ const currentScreen = useNavigationStore((state) => state.currentScreen);
+ const isNotebook = currentScreen.name === "Notebook";
+ const isTopic = currentScreen?.name === "TopicNotes";
const [hide, setHide] = useState(
isNotebook
- ? typeof titleState[currentScreen.id] === 'boolean'
+ ? typeof titleState[currentScreen.id] === "boolean"
? titleState[currentScreen.id]
: true
: false
);
const isHidden = titleState[currentScreen.id];
- console.log(currentScreen, 'header');
+ console.log(currentScreen, "header");
const notebook =
isTopic && currentScreen.notebookId
? db.notebooks?.notebook(currentScreen.notebookId)?.data
: null;
const title = currentScreen.title;
- const isTag = currentScreen?.name === 'TaggedNotes';
+ const isTag = currentScreen?.name === "TaggedNotes";
- const onScroll = data => {
- if (currentScreen.name !== 'Notebook') {
+ const onScroll = (data) => {
+ if (currentScreen.name !== "Notebook") {
setHide(false);
return;
}
@@ -48,9 +51,11 @@ export const Title = () => {
};
useEffect(() => {
- if (currentScreen.name === 'Notebook') {
+ if (currentScreen.name === "Notebook") {
let value =
- typeof titleState[currentScreen.id] === 'boolean' ? titleState[currentScreen.id] : true;
+ typeof titleState[currentScreen.id] === "boolean"
+ ? titleState[currentScreen.id]
+ : true;
setHide(value);
} else {
setHide(titleState[currentScreen.id]);
@@ -77,7 +82,7 @@ export const Title = () => {
style={{
opacity: 1,
flexShrink: 1,
- flexDirection: 'row'
+ flexDirection: "row"
}}
>
{!hide && !isHidden ? (
@@ -86,19 +91,22 @@ export const Title = () => {
numberOfLines={isTopic ? 2 : 1}
size={isTopic ? SIZE.md + 2 : SIZE.xl}
style={{
- flexWrap: 'wrap',
- marginTop: Platform.OS === 'ios' ? -1 : 0
+ flexWrap: "wrap",
+ marginTop: Platform.OS === "ios" ? -1 : 0
}}
color={currentScreen.color || colors.heading}
>
{isTopic ? (
{notebook?.title}
- {'\n'}
+ {"\n"}
) : null}
{isTag ? (
-
+
#
) : null}
diff --git a/apps/mobile/app/components/image-preview/index.js b/apps/mobile/app/components/image-preview/index.js
index 922c83b38..95d975ee5 100644
--- a/apps/mobile/app/components/image-preview/index.js
+++ b/apps/mobile/app/components/image-preview/index.js
@@ -1,23 +1,26 @@
-import React, { useEffect, useState } from 'react';
-import { View } from 'react-native';
-import ImageViewer from 'react-native-image-zoom-viewer';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import BaseDialog from '../dialog/base-dialog';
-import { IconButton } from '../ui/icon-button';
+import React, { useEffect, useState } from "react";
+import { View } from "react-native";
+import ImageViewer from "react-native-image-zoom-viewer";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import BaseDialog from "../dialog/base-dialog";
+import { IconButton } from "../ui/icon-button";
const ImagePreview = () => {
const [visible, setVisible] = useState(false);
- const [image, setImage] = useState('');
+ const [image, setImage] = useState("");
useEffect(() => {
- eSubscribeEvent('ImagePreview', open);
+ eSubscribeEvent("ImagePreview", open);
return () => {
- eUnSubscribeEvent('ImagePreview', open);
+ eUnSubscribeEvent("ImagePreview", open);
};
}, []);
- const open = image => {
+ const open = (image) => {
setImage(image);
setVisible(true);
};
@@ -32,9 +35,9 @@ const ImagePreview = () => {
{
renderHeader={() => (
diff --git a/apps/mobile/app/components/intro/index.js b/apps/mobile/app/components/intro/index.js
index 9c6d6b86a..85d2eedf9 100644
--- a/apps/mobile/app/components/intro/index.js
+++ b/apps/mobile/app/components/intro/index.js
@@ -1,30 +1,40 @@
-import React, { useEffect } from 'react';
-import { Dimensions, Image, TouchableOpacity, useWindowDimensions, View } from 'react-native';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { DDS } from '../../services/device-detection';
-import SettingsService from '../../services/settings';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { getElevation } from '../../utils';
-import umami from '../../common/analytics';
-import { tabBarRef } from '../../utils/global-refs';
-import { useNavigationFocus } from '../../hooks/use-navigation-focus';
-import { SIZE } from '../../utils/size';
-import { Button } from '../ui/button';
-import { SvgView } from '../ui/svg';
-import { BouncingView } from '../ui/transitions/bouncing-view';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
+import React, { useEffect } from "react";
+import {
+ Dimensions,
+ Image,
+ TouchableOpacity,
+ useWindowDimensions,
+ View
+} from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { DDS } from "../../services/device-detection";
+import SettingsService from "../../services/settings";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { getElevation } from "../../utils";
+import umami from "../../common/analytics";
+import { tabBarRef } from "../../utils/global-refs";
+import { useNavigationFocus } from "../../hooks/use-navigation-focus";
+import { SIZE } from "../../utils/size";
+import { Button } from "../ui/button";
+import { SvgView } from "../ui/svg";
+import { BouncingView } from "../ui/transitions/bouncing-view";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
let SVG_D = ``;
export const SVG_Z = ``;
const Intro = ({ navigation, route }) => {
- const colors = useThemeStore(state => state.colors);
- const introCompleted = useSettingStore(state => state.settings.introCompleted);
- const isTelemetryEnabled = useSettingStore(state => state.settings.telemetry);
+ const colors = useThemeStore((state) => state.colors);
+ const introCompleted = useSettingStore(
+ (state) => state.settings.introCompleted
+ );
+ const isTelemetryEnabled = useSettingStore(
+ (state) => state.settings.telemetry
+ );
const { height } = useWindowDimensions();
const insets = useSafeAreaInsets();
useNavigationFocus(navigation, {
@@ -35,7 +45,7 @@ const Intro = ({ navigation, route }) => {
useEffect(() => {
if (!introCompleted) {
- umami.pageView('/welcome', '', []);
+ umami.pageView("/welcome", "", []);
}
}, [introCompleted]);
@@ -43,27 +53,27 @@ const Intro = ({ navigation, route }) => {
@@ -77,7 +87,7 @@ const Intro = ({ navigation, route }) => {
style={{
marginTop: 40,
marginBottom: 20,
- maxWidth: '80%',
+ maxWidth: "80%",
opacity: 0.8
}}
>
@@ -90,21 +100,21 @@ const Intro = ({ navigation, route }) => {
{
>
@@ -125,7 +137,7 @@ const Intro = ({ navigation, route }) => {
}}
size={SIZE.md}
>
- Help improve Notesnook by sending completely anonymized{' '}
+ Help improve Notesnook by sending completely anonymized{" "}
private analytics and bug reports.
@@ -135,15 +147,15 @@ const Intro = ({ navigation, route }) => {
height={45}
width={250}
onPress={async () => {
- navigation.navigate('AppLock', {
+ navigation.navigate("AppLock", {
welcome: true
});
- umami.pageView('/home', '/welcome');
+ umami.pageView("/home", "/welcome");
}}
style={{
paddingHorizontal: 24,
- alignSelf: 'center',
+ alignSelf: "center",
borderRadius: 100,
...getElevation(5)
}}
@@ -154,15 +166,15 @@ const Intro = ({ navigation, route }) => {
diff --git a/apps/mobile/app/components/intro/welcome.js b/apps/mobile/app/components/intro/welcome.js
index 7f02ce531..17baf67c0 100644
--- a/apps/mobile/app/components/intro/welcome.js
+++ b/apps/mobile/app/components/intro/welcome.js
@@ -1,33 +1,33 @@
-import React from 'react';
-import Animated, { FadeInDown } from 'react-native-reanimated';
-import { DDS } from '../../services/device-detection';
-import { eSendEvent } from '../../services/event-manager';
-import Navigation from '../../services/navigation';
-import SettingsService from '../../services/settings';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { getElevation } from '../../utils';
-import umami from '../../common/analytics';
-import { eOpenLoginDialog } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { AuthMode } from '../auth';
-import { Button } from '../ui/button';
-import { SvgView } from '../ui/svg';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-const IMAGE = color =>
+import React from "react";
+import Animated, { FadeInDown } from "react-native-reanimated";
+import { DDS } from "../../services/device-detection";
+import { eSendEvent } from "../../services/event-manager";
+import Navigation from "../../services/navigation";
+import SettingsService from "../../services/settings";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { getElevation } from "../../utils";
+import umami from "../../common/analytics";
+import { eOpenLoginDialog } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { AuthMode } from "../auth";
+import { Button } from "../ui/button";
+import { SvgView } from "../ui/svg";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+const IMAGE = (color) =>
``;
export const WelcomeNotice = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
@@ -35,13 +35,13 @@ export const WelcomeNotice = () => {
100% encrypted notes
- Notesnook encrypts everything on your device before syncing. This means that no one can read
- your notes except you. Not even us.
+ Notesnook encrypts everything on your device before syncing. This means
+ that no one can read your notes except you. Not even us.
{
});
Navigation.replace(
{
- name: 'Notes'
+ name: "Notes"
},
{
canGoBack: false
}
);
}, 1000);
- umami.pageView('/encryptionnotice', '/welcome/privacymode');
+ umami.pageView("/encryptionnotice", "/welcome/privacymode");
}}
style={{
paddingHorizontal: 24,
- alignSelf: 'center',
+ alignSelf: "center",
borderRadius: 100,
...getElevation(5),
marginTop: 30
diff --git a/apps/mobile/app/components/launcher/index.js b/apps/mobile/app/components/launcher/index.js
index d5783c7f0..c768f3c3f 100644
--- a/apps/mobile/app/components/launcher/index.js
+++ b/apps/mobile/app/components/launcher/index.js
@@ -1,55 +1,61 @@
-import React, { useEffect, useRef } from 'react';
-import { Platform, View } from 'react-native';
-import RNBootSplash from 'react-native-bootsplash';
-import { checkVersion } from 'react-native-check-version';
-import { enabled } from 'react-native-privacy-snapshot';
-import { editorState } from '../../screens/editor/tiptap/utils';
-import BackupService from '../../services/backup';
-import BiometricService from '../../services/biometrics';
-import { DDS } from '../../services/device-detection';
-import { eSendEvent, presentSheet, ToastEvent } from '../../services/event-manager';
-import { setRateAppMessage } from '../../services/message';
-import PremiumService from '../../services/premium';
-import SettingsService from '../../services/settings';
-import { initialize } from '../../stores';
-import { useMessageStore } from '../../stores/use-message-store';
-import { useNoteStore } from '../../stores/use-notes-store';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useUserStore } from '../../stores/use-user-store';
-import { DatabaseLogger, db, loadDatabase } from '../../common/database';
-import { MMKV } from '../../common/database/mmkv';
-import { eOpenAnnouncementDialog } from '../../utils/events';
-import { tabBarRef } from '../../utils/global-refs';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import { SVG } from '../auth/background';
-import Migrate from '../sheets/migrate';
-import NewFeature from '../sheets/new-feature/index';
-import { Update } from '../sheets/update';
-import { Button } from '../ui/button';
-import { IconButton } from '../ui/icon-button';
-import Input from '../ui/input';
-import Seperator from '../ui/seperator';
-import { SvgView } from '../ui/svg';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import { Walkthrough } from '../walkthroughs';
-import { useAppState } from '../../hooks/use-app-state';
+import React, { useEffect, useRef } from "react";
+import { Platform, View } from "react-native";
+import RNBootSplash from "react-native-bootsplash";
+import { checkVersion } from "react-native-check-version";
+import { enabled } from "react-native-privacy-snapshot";
+import { editorState } from "../../screens/editor/tiptap/utils";
+import BackupService from "../../services/backup";
+import BiometricService from "../../services/biometrics";
+import { DDS } from "../../services/device-detection";
+import {
+ eSendEvent,
+ presentSheet,
+ ToastEvent
+} from "../../services/event-manager";
+import { setRateAppMessage } from "../../services/message";
+import PremiumService from "../../services/premium";
+import SettingsService from "../../services/settings";
+import { initialize } from "../../stores";
+import { useMessageStore } from "../../stores/use-message-store";
+import { useNoteStore } from "../../stores/use-notes-store";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useUserStore } from "../../stores/use-user-store";
+import { DatabaseLogger, db, loadDatabase } from "../../common/database";
+import { MMKV } from "../../common/database/mmkv";
+import { eOpenAnnouncementDialog } from "../../utils/events";
+import { tabBarRef } from "../../utils/global-refs";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import { SVG } from "../auth/background";
+import Migrate from "../sheets/migrate";
+import NewFeature from "../sheets/new-feature/index";
+import { Update } from "../sheets/update";
+import { Button } from "../ui/button";
+import { IconButton } from "../ui/icon-button";
+import Input from "../ui/input";
+import Seperator from "../ui/seperator";
+import { SvgView } from "../ui/svg";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import { Walkthrough } from "../walkthroughs";
+import { useAppState } from "../../hooks/use-app-state";
const Launcher = React.memo(
() => {
- const colors = useThemeStore(state => state.colors);
- const setLoading = useNoteStore(state => state.setLoading);
- const loading = useNoteStore(state => state.loading);
- const user = useUserStore(state => state.user);
- const verifyUser = useUserStore(state => state.verifyUser);
- const setVerifyUser = useUserStore(state => state.setVerifyUser);
- const deviceMode = useSettingStore(state => state.deviceMode);
+ const colors = useThemeStore((state) => state.colors);
+ const setLoading = useNoteStore((state) => state.setLoading);
+ const loading = useNoteStore((state) => state.loading);
+ const user = useUserStore((state) => state.user);
+ const verifyUser = useUserStore((state) => state.verifyUser);
+ const setVerifyUser = useUserStore((state) => state.setVerifyUser);
+ const deviceMode = useSettingStore((state) => state.deviceMode);
const appState = useAppState();
const passwordInputRef = useRef();
const password = useRef();
- const introCompleted = useSettingStore(state => state.settings.introCompleted);
+ const introCompleted = useSettingStore(
+ (state) => state.settings.introCompleted
+ );
const dbInitCompleted = useRef(false);
const loadNotes = async () => {
if (verifyUser) {
@@ -76,7 +82,7 @@ const Launcher = React.memo(
if (!dbInitCompleted.current) {
await RNBootSplash.hide({ fade: true });
await loadDatabase();
- DatabaseLogger.info('Initializing database');
+ DatabaseLogger.info("Initializing database");
await db.init();
dbInitCompleted.current = true;
}
@@ -115,16 +121,20 @@ const Launcher = React.memo(
const doAppLoadActions = async () => {
await sleep(500);
if (SettingsService.get().sessionExpired) {
- eSendEvent('session_expired');
+ eSendEvent("session_expired");
return;
}
const user = await db.user.getUser();
await useMessageStore.getState().setAnnouncement();
if (PremiumService.get() && user) {
- if (SettingsService.get().reminder === 'off') {
- SettingsService.set({ reminder: 'daily' });
+ if (SettingsService.get().reminder === "off") {
+ SettingsService.set({ reminder: "daily" });
}
- if (await BackupService.checkBackupRequired(SettingsService.get().reminder)) {
+ if (
+ await BackupService.checkBackupRequired(
+ SettingsService.get().reminder
+ )
+ ) {
sleep(2000).then(() => BackupService.run());
}
}
@@ -135,7 +145,7 @@ const Launcher = React.memo(
if (await PremiumService.getRemainingTrialDaysStatus()) return;
if (introCompleted) {
- useMessageStore.subscribe(state => {
+ useMessageStore.subscribe((state) => {
let dialogs = state.dialogs;
if (dialogs.length > 0) {
eSendEvent(eOpenAnnouncementDialog, dialogs[0]);
@@ -150,7 +160,7 @@ const Launcher = React.memo(
const version = await checkVersion();
if (!version.needsUpdate) return false;
presentSheet({
- component: ref =>
+ component: (ref) =>
});
return true;
} catch (e) {
@@ -159,7 +169,7 @@ const Launcher = React.memo(
};
const restoreEditorState = async () => {
- let appState = MMKV.getString('appState');
+ let appState = MMKV.getString("appState");
if (appState) {
appState = JSON.parse(appState);
if (
@@ -174,14 +184,18 @@ const Launcher = React.memo(
if (!DDS.isTab) {
tabBarRef.current?.goToPage(1);
}
- eSendEvent('loadingNote', appState.note);
+ eSendEvent("loadingNote", appState.note);
}
}
};
const checkForRateAppRequest = async () => {
let rateApp = SettingsService.get().rateApp;
- if (rateApp && rateApp < Date.now() && !useMessageStore.getState().message?.visible) {
+ if (
+ rateApp &&
+ rateApp < Date.now() &&
+ !useMessageStore.getState().message?.visible
+ ) {
setRateAppMessage();
return false;
}
@@ -208,12 +222,15 @@ const Launcher = React.memo(
const onUnlockBiometrics = async () => {
if (!(await BiometricService.isBiometryAvailable())) {
ToastEvent.show({
- heading: 'Biometrics unavailable',
- message: 'Try unlocking the app with your account password'
+ heading: "Biometrics unavailable",
+ message: "Try unlocking the app with your account password"
});
return;
}
- let verified = await BiometricService.validateUser('Unlock to access your notes', '');
+ let verified = await BiometricService.validateUser(
+ "Unlock to access your notes",
+ ""
+ );
if (verified) {
setVerifyUser(false);
enabled(false);
@@ -226,7 +243,7 @@ const Launcher = React.memo(
}, [verifyUser]);
useEffect(() => {
- if (verifyUser && appState === 'active') {
+ if (verifyUser && appState === "active") {
onUnlockBiometrics();
}
}, [appState]);
@@ -247,30 +264,35 @@ const Launcher = React.memo(
-
+
Unlock to access your notes
@@ -297,10 +319,10 @@ const Launcher = React.memo(
Please verify it's you
@@ -308,7 +330,7 @@ const Launcher = React.memo(
(password.current = v)}
+ onChangeText={(v) => (password.current = v)}
onSubmit={onSubmit}
/>
>
@@ -356,8 +378,8 @@ const Launcher = React.memo(
borderRadius: 100
}}
onPress={onUnlockBiometrics}
- icon={'fingerprint'}
- type={user ? 'grayAccent' : 'accent'}
+ icon={"fingerprint"}
+ type={user ? "grayAccent" : "accent"}
fontSize={SIZE.md}
/>
diff --git a/apps/mobile/app/components/list-items/footer/index.js b/apps/mobile/app/components/list-items/footer/index.js
index 2c66c98a2..9d747cff9 100644
--- a/apps/mobile/app/components/list-items/footer/index.js
+++ b/apps/mobile/app/components/list-items/footer/index.js
@@ -1,5 +1,5 @@
-import React from 'react';
-import { View } from 'react-native';
+import React from "react";
+import { View } from "react-native";
export const Footer = () => {
return ;
diff --git a/apps/mobile/app/components/list-items/headers/header.js b/apps/mobile/app/components/list-items/headers/header.js
index f1f8d6934..16c81951d 100644
--- a/apps/mobile/app/components/list-items/headers/header.js
+++ b/apps/mobile/app/components/list-items/headers/header.js
@@ -1,20 +1,27 @@
-import React from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { useMessageStore } from '../../../stores/use-message-store';
-import { COLORS_NOTE } from '../../../utils/color-scheme';
-import { Announcement } from '../../announcements/announcement';
-import { Card } from '../../list/card';
-import Paragraph from '../../ui/typography/paragraph';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { SIZE } from '../../../utils/size';
-import { useSelectionStore } from '../../../stores/use-selection-store';
-import Animated, { FadeInUp, FadeOutUp } from 'react-native-reanimated';
+import React from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { useMessageStore } from "../../../stores/use-message-store";
+import { COLORS_NOTE } from "../../../utils/color-scheme";
+import { Announcement } from "../../announcements/announcement";
+import { Card } from "../../list/card";
+import Paragraph from "../../ui/typography/paragraph";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { SIZE } from "../../../utils/size";
+import { useSelectionStore } from "../../../stores/use-selection-store";
+import Animated, { FadeInUp, FadeOutUp } from "react-native-reanimated";
export const Header = React.memo(
- ({ type, messageCard = true, color, shouldShow = false, noAnnouncement, warning }) => {
- const colors = useThemeStore(state => state.colors);
- const announcements = useMessageStore(state => state.announcements);
- const selectionMode = useSelectionStore(state => state.selectionMode);
+ ({
+ type,
+ messageCard = true,
+ color,
+ shouldShow = false,
+ noAnnouncement,
+ warning
+ }) => {
+ const colors = useThemeStore((state) => state.colors);
+ const announcements = useMessageStore((state) => state.announcements);
+ const selectionMode = useSelectionStore((state) => state.selectionMode);
return selectionMode ? null : (
<>
@@ -23,11 +30,11 @@ export const Header = React.memo(
style={{
padding: 12,
backgroundColor: colors.errorBg,
- width: '95%',
- alignSelf: 'center',
+ width: "95%",
+ alignSelf: "center",
borderRadius: 5,
- flexDirection: 'row',
- alignItems: 'center'
+ flexDirection: "row",
+ alignItems: "center"
}}
>
@@ -37,18 +44,20 @@ export const Header = React.memo(
) : announcements.length !== 0 && !noAnnouncement ? (
- ) : type === 'search' ? null : !shouldShow ? (
+ ) : type === "search" ? null : !shouldShow ? (
{messageCard ? (
-
+
) : null}
) : null}
@@ -57,4 +66,4 @@ export const Header = React.memo(
}
);
-Header.displayName = 'Header';
+Header.displayName = "Header";
diff --git a/apps/mobile/app/components/list-items/headers/notebook-header.js b/apps/mobile/app/components/list-items/headers/notebook-header.js
index efb22752d..36edb153a 100644
--- a/apps/mobile/app/components/list-items/headers/notebook-header.js
+++ b/apps/mobile/app/components/list-items/headers/notebook-header.js
@@ -1,19 +1,21 @@
-import React, { useRef, useState } from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { useMenuStore } from '../../../stores/use-menu-store';
-import { ToastEvent } from '../../../services/event-manager';
-import { getTotalNotes } from '../../../utils';
-import { db } from '../../../common/database';
-import { SIZE } from '../../../utils/size';
-import { IconButton } from '../../ui/icon-button';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
+import React, { useRef, useState } from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { useMenuStore } from "../../../stores/use-menu-store";
+import { ToastEvent } from "../../../services/event-manager";
+import { getTotalNotes } from "../../../utils";
+import { db } from "../../../common/database";
+import { SIZE } from "../../../utils/size";
+import { IconButton } from "../../ui/icon-button";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
export const NotebookHeader = ({ notebook, onEditNotebook }) => {
- const colors = useThemeStore(state => state.colors);
- const [isPinnedToMenu, setIsPinnedToMenu] = useState(db.settings.isPinned(notebook.id));
- const setMenuPins = useMenuStore(state => state.setMenuPins);
+ const colors = useThemeStore((state) => state.colors);
+ const [isPinnedToMenu, setIsPinnedToMenu] = useState(
+ db.settings.isPinned(notebook.id)
+ );
+ const setMenuPins = useMenuStore((state) => state.setMenuPins);
const totalNotes = getTotalNotes(notebook);
const shortcutRef = useRef();
@@ -24,8 +26,8 @@ export const NotebookHeader = ({ notebook, onEditNotebook }) => {
} else {
await db.settings.pin(notebook.type, { id: notebook.id });
ToastEvent.show({
- heading: 'Shortcut created',
- type: 'success'
+ heading: "Shortcut created",
+ type: "success"
});
}
setIsPinnedToMenu(db.settings.isPinned(notebook.id));
@@ -38,10 +40,10 @@ export const NotebookHeader = ({ notebook, onEditNotebook }) => {
style={{
marginBottom: 5,
padding: 0,
- width: '100%',
+ width: "100%",
paddingVertical: 15,
paddingHorizontal: 12,
- alignSelf: 'center',
+ alignSelf: "center",
borderRadius: 10,
paddingTop: 25
}}
@@ -51,29 +53,29 @@ export const NotebookHeader = ({ notebook, onEditNotebook }) => {
{notebook.title}
@@ -101,18 +103,21 @@ export const NotebookHeader = ({ notebook, onEditNotebook }) => {
- {notebook.topics.length === 1 ? '1 topic' : `${notebook.topics.length} topics`},{' '}
+ {notebook.topics.length === 1
+ ? "1 topic"
+ : `${notebook.topics.length} topics`}
+ ,{" "}
{notebook && totalNotes > 1
- ? totalNotes + ' notes'
+ ? totalNotes + " notes"
: totalNotes === 1
- ? totalNotes + ' note'
- : '0 notes'}
+ ? totalNotes + " note"
+ : "0 notes"}
);
diff --git a/apps/mobile/app/components/list-items/headers/section-header.js b/apps/mobile/app/components/list-items/headers/section-header.js
index 4fdde8133..2cd1049ae 100644
--- a/apps/mobile/app/components/list-items/headers/section-header.js
+++ b/apps/mobile/app/components/list-items/headers/section-header.js
@@ -1,40 +1,48 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { TouchableOpacity, useWindowDimensions, View } from 'react-native';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { useSettingStore } from '../../../stores/use-setting-store';
+import React, { useEffect, useRef, useState } from "react";
+import { TouchableOpacity, useWindowDimensions, View } from "react-native";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { useSettingStore } from "../../../stores/use-setting-store";
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent,
presentSheet
-} from '../../../services/event-manager';
-import SettingsService from '../../../services/settings';
-import { GROUP } from '../../../utils/constants';
-import { COLORS_NOTE } from '../../../utils/color-scheme';
-import { db } from '../../../common/database';
-import { eOpenJumpToDialog } from '../../../utils/events';
-import { SIZE } from '../../../utils/size';
-import { IconButton } from '../../ui/icon-button';
-import { Button } from '../../ui/button';
-import Sort from '../../sheets/sort';
-import Heading from '../../ui/typography/heading';
+} from "../../../services/event-manager";
+import SettingsService from "../../../services/settings";
+import { GROUP } from "../../../utils/constants";
+import { COLORS_NOTE } from "../../../utils/color-scheme";
+import { db } from "../../../common/database";
+import { eOpenJumpToDialog } from "../../../utils/events";
+import { SIZE } from "../../../utils/size";
+import { IconButton } from "../../ui/icon-button";
+import { Button } from "../../ui/button";
+import Sort from "../../sheets/sort";
+import Heading from "../../ui/typography/heading";
export const SectionHeader = React.memo(
({ item, index, type, color, screen }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const { fontScale } = useWindowDimensions();
- const [groupOptions, setGroupOptions] = useState(db.settings?.getGroupOptions(type));
- let groupBy = Object.keys(GROUP).find(key => GROUP[key] === groupOptions.groupBy);
+ const [groupOptions, setGroupOptions] = useState(
+ db.settings?.getGroupOptions(type)
+ );
+ let groupBy = Object.keys(GROUP).find(
+ (key) => GROUP[key] === groupOptions.groupBy
+ );
const jumpToRef = useRef();
const sortRef = useRef();
const compactModeRef = useRef();
- const notebooksListMode = useSettingStore(state => state.settings.notebooksListMode);
- const notesListMode = useSettingStore(state => state.settings.notesListMode);
- const listMode = type === 'notebooks' ? notebooksListMode : notesListMode;
+ const notebooksListMode = useSettingStore(
+ (state) => state.settings.notebooksListMode
+ );
+ const notesListMode = useSettingStore(
+ (state) => state.settings.notesListMode
+ );
+ const listMode = type === "notebooks" ? notebooksListMode : notesListMode;
groupBy = !groupBy
- ? 'Default'
+ ? "Default"
: groupBy.slice(0, 1).toUpperCase() + groupBy.slice(1, groupBy.length);
const onUpdate = () => {
@@ -42,23 +50,23 @@ export const SectionHeader = React.memo(
};
useEffect(() => {
- eSubscribeEvent('groupOptionsUpdate', onUpdate);
+ eSubscribeEvent("groupOptionsUpdate", onUpdate);
return () => {
- eUnSubscribeEvent('groupOptionsUpdate', onUpdate);
+ eUnSubscribeEvent("groupOptionsUpdate", onUpdate);
};
}, []);
return (
- {!item.title || item.title === '' ? 'Pinned' : item.title}
+ {!item.title || item.title === "" ? "Pinned" : item.title}
{index === 0 ? (
@@ -105,19 +113,26 @@ export const SectionHeader = React.memo(
tooltipText="Change sorting of items in list"
fwdRef={sortRef}
title={groupBy}
- icon={groupOptions.sortDirection === 'asc' ? 'sort-ascending' : 'sort-descending'}
+ icon={
+ groupOptions.sortDirection === "asc"
+ ? "sort-ascending"
+ : "sort-descending"
+ }
height={25}
style={{
borderRadius: 100,
paddingHorizontal: 0,
- backgroundColor: 'transparent',
- marginRight: type === 'notes' || type === 'home' || type === 'notebooks' ? 10 : 0
+ backgroundColor: "transparent",
+ marginRight:
+ type === "notes" || type === "home" || type === "notebooks"
+ ? 10
+ : 0
}}
type="gray"
iconPosition="right"
/>
- {type === 'notes' || type === 'notebooks' || type === 'home' ? (
+ {type === "notes" || type === "notebooks" || type === "home" ? (
{
let settings = {};
- settings[type !== 'notebooks' ? 'notesListMode' : 'notebooksListMode'] =
- listMode === 'normal' ? 'compact' : 'normal';
+ settings[
+ type !== "notebooks"
+ ? "notesListMode"
+ : "notebooksListMode"
+ ] = listMode === "normal" ? "compact" : "normal";
SettingsService.set(settings);
}}
diff --git a/apps/mobile/app/components/list-items/note/index.js b/apps/mobile/app/components/list-items/note/index.js
index e03701bae..42ee67892 100644
--- a/apps/mobile/app/components/list-items/note/index.js
+++ b/apps/mobile/app/components/list-items/note/index.js
@@ -1,24 +1,24 @@
-import { decode, EntityLevel } from 'entities';
-import React from 'react';
-import { View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { notesnook } from '../../../../e2e/test.ids';
-import { TaggedNotes } from '../../../screens/notes/tagged';
-import { TopicNotes } from '../../../screens/notes/topic-notes';
-import useNavigationStore from '../../../stores/use-navigation-store';
-import { useSettingStore } from '../../../stores/use-setting-store';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { COLORS_NOTE } from '../../../utils/color-scheme';
-import { db } from '../../../common/database';
-import { SIZE } from '../../../utils/size';
-import { Properties } from '../../properties';
-import { Button } from '../../ui/button';
-import { IconButton } from '../../ui/icon-button';
-import { TimeSince } from '../../ui/time-since';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
+import { decode, EntityLevel } from "entities";
+import React from "react";
+import { View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { notesnook } from "../../../../e2e/test.ids";
+import { TaggedNotes } from "../../../screens/notes/tagged";
+import { TopicNotes } from "../../../screens/notes/topic-notes";
+import useNavigationStore from "../../../stores/use-navigation-store";
+import { useSettingStore } from "../../../stores/use-setting-store";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { COLORS_NOTE } from "../../../utils/color-scheme";
+import { db } from "../../../common/database";
+import { SIZE } from "../../../utils/size";
+import { Properties } from "../../properties";
+import { Button } from "../../ui/button";
+import { IconButton } from "../../ui/icon-button";
+import { TimeSince } from "../../ui/time-since";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
-const navigateToTopic = topic => {
+const navigateToTopic = (topic) => {
TopicNotes.navigate(topic, true);
};
@@ -28,16 +28,19 @@ function navigateToTag(item) {
TaggedNotes.navigate(tag, true);
}
-const showActionSheet = item => {
+const showActionSheet = (item) => {
Properties.present(item);
};
function getNotebook(item) {
- const isTrash = item.type === 'trash';
+ const isTrash = item.type === "trash";
if (isTrash || !item.notebooks || item.notebooks.length < 1) return [];
const currentScreen = useNavigationStore.getState().currentScreen;
- const filteredNotebooks = item.notebooks?.filter(n => n.id !== currentScreen.notebookId);
- let item_notebook = filteredNotebooks?.length > 0 ? filteredNotebooks.slice(0, 1)[0] : null;
+ const filteredNotebooks = item.notebooks?.filter(
+ (n) => n.id !== currentScreen.notebookId
+ );
+ let item_notebook =
+ filteredNotebooks?.length > 0 ? filteredNotebooks.slice(0, 1)[0] : null;
let notebook = item_notebook && db.notebooks.notebook(item_notebook.id);
if (!notebook) return [];
let topic = notebook.topics.topic(item_notebook.topics[0])?._topic;
@@ -52,11 +55,19 @@ function getNotebook(item) {
];
}
-const NoteItem = ({ item, isTrash, tags, dateBy = 'dateCreated', noOpen = false }) => {
- const colors = useThemeStore(state => state.colors);
- const notesListMode = useSettingStore(state => state.settings.notesListMode);
- const compactMode = notesListMode === 'compact';
- const attachmentCount = db.attachments?.ofNote(item.id, 'all')?.length || 0;
+const NoteItem = ({
+ item,
+ isTrash,
+ tags,
+ dateBy = "dateCreated",
+ noOpen = false
+}) => {
+ const colors = useThemeStore((state) => state.colors);
+ const notesListMode = useSettingStore(
+ (state) => state.settings.notesListMode
+ );
+ const compactMode = notesListMode === "compact";
+ const attachmentCount = db.attachments?.ofNote(item.id, "all")?.length || 0;
const notebooks = React.useMemo(() => getNotebook(item), [item]);
return (
@@ -70,14 +81,14 @@ const NoteItem = ({ item, isTrash, tags, dateBy = 'dateCreated', noOpen = false
{!compactMode ? (
- {notebooks.map(_item => (
+ {notebooks.map((_item) => (
@@ -116,7 +127,7 @@ const NoteItem = ({ item, isTrash, tags, dateBy = 'dateCreated', noOpen = false
{item.headline && !compactMode ? (
@@ -128,10 +139,10 @@ const NoteItem = ({ item, isTrash, tags, dateBy = 'dateCreated', noOpen = false
{attachmentCount > 0 ? (
@@ -181,7 +194,9 @@ const NoteItem = ({ item, isTrash, tags, dateBy = 'dateCreated', noOpen = false
style={{
marginRight: 6
}}
- color={COLORS_NOTE[item.color?.toLowerCase()] || colors.accent}
+ color={
+ COLORS_NOTE[item.color?.toLowerCase()] || colors.accent
+ }
/>
) : null}
@@ -210,15 +225,15 @@ const NoteItem = ({ item, isTrash, tags, dateBy = 'dateCreated', noOpen = false
) : null}
{!isTrash && !compactMode && tags
- ? tags.map(item =>
+ ? tags.map((item) =>
item.id ? (
- Deleted on{' '}
+ Deleted on{" "}
{item && item.dateDeleted
? new Date(item.dateDeleted).toISOString().slice(0, 10)
: null}
@@ -270,11 +285,11 @@ const NoteItem = ({ item, isTrash, tags, dateBy = 'dateCreated', noOpen = false
size={SIZE.xl}
onPress={() => !noOpen && showActionSheet(item, isTrash)}
customStyle={{
- justifyContent: 'center',
+ justifyContent: "center",
height: 35,
width: 35,
borderRadius: 100,
- alignItems: 'center'
+ alignItems: "center"
}}
/>
>
diff --git a/apps/mobile/app/components/list-items/note/wrapper.js b/apps/mobile/app/components/list-items/note/wrapper.js
index 39e202ddb..ab81838f0 100644
--- a/apps/mobile/app/components/list-items/note/wrapper.js
+++ b/apps/mobile/app/components/list-items/note/wrapper.js
@@ -1,24 +1,28 @@
-import React from 'react';
-import NoteItem from '.';
-import { notesnook } from '../../../../e2e/test.ids';
-import { useSelectionStore } from '../../../stores/use-selection-store';
-import { useTrashStore } from '../../../stores/use-trash-store';
-import { useEditorStore } from '../../../stores/use-editor-store';
-import { DDS } from '../../../services/device-detection';
-import { eSendEvent, openVault, ToastEvent } from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import { history } from '../../../utils';
-import { db } from '../../../common/database';
-import { eOnLoadNote, eShowMergeDialog } from '../../../utils/events';
-import { tabBarRef } from '../../../utils/global-refs';
-import { presentDialog } from '../../dialog/functions';
-import SelectionWrapper from '../selection-wrapper';
+import React from "react";
+import NoteItem from ".";
+import { notesnook } from "../../../../e2e/test.ids";
+import { useSelectionStore } from "../../../stores/use-selection-store";
+import { useTrashStore } from "../../../stores/use-trash-store";
+import { useEditorStore } from "../../../stores/use-editor-store";
+import { DDS } from "../../../services/device-detection";
+import {
+ eSendEvent,
+ openVault,
+ ToastEvent
+} from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import { history } from "../../../utils";
+import { db } from "../../../common/database";
+import { eOnLoadNote, eShowMergeDialog } from "../../../utils/events";
+import { tabBarRef } from "../../../utils/global-refs";
+import { presentDialog } from "../../dialog/functions";
+import SelectionWrapper from "../selection-wrapper";
const present = () =>
presentDialog({
- title: 'Note not synced',
- negativeText: 'Ok',
- paragraph: 'Please sync again to open this note for editing'
+ title: "Note not synced",
+ negativeText: "Ok",
+ paragraph: "Please sync again to open this note for editing"
});
export const openNote = async (item, isTrash, setSelectedItem) => {
@@ -55,8 +59,8 @@ export const openNote = async (item, isTrash, setSelectedItem) => {
novault: true,
locked: true,
goToEditor: true,
- title: 'Open note',
- description: 'Unlock note to open it in editor.'
+ title: "Open note",
+ description: "Unlock note to open it in editor."
});
return;
}
@@ -64,24 +68,24 @@ export const openNote = async (item, isTrash, setSelectedItem) => {
presentDialog({
title: `Restore ${item.itemType}`,
paragraph: `Restore or delete ${item.itemType} forever`,
- positiveText: 'Restore',
- negativeText: 'Delete',
+ positiveText: "Restore",
+ negativeText: "Delete",
positivePress: async () => {
await db.trash.restore(item.id);
Navigation.queueRoutesForUpdate(
- 'Tags',
- 'Notes',
- 'Notebooks',
- 'Favorites',
- 'Trash',
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes'
+ "Tags",
+ "Notes",
+ "Notebooks",
+ "Favorites",
+ "Trash",
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes"
);
useSelectionStore.getState().setSelectionMode(false);
ToastEvent.show({
- heading: 'Restore successful',
- type: 'success'
+ heading: "Restore successful",
+ type: "success"
});
},
onClose: async () => {
@@ -89,9 +93,9 @@ export const openNote = async (item, isTrash, setSelectedItem) => {
useTrashStore.getState().setTrash();
useSelectionStore.getState().setSelectionMode(false);
ToastEvent.show({
- heading: 'Permanantly deleted items',
- type: 'success',
- context: 'local'
+ heading: "Permanantly deleted items",
+ type: "success",
+ context: "local"
});
}
});
@@ -106,8 +110,8 @@ export const openNote = async (item, isTrash, setSelectedItem) => {
export const NoteWrapper = React.memo(
({ item, index, tags, dateBy }) => {
- const isTrash = item.type === 'trash';
- const setSelectedItem = useSelectionStore(state => state.setSelectedItem);
+ const isTrash = item.type === "trash";
+ const setSelectedItem = useSelectionStore((state) => state.setSelectedItem);
return (
{
+const showActionSheet = (item) => {
Properties.present(item);
};
-const navigateToTopic = topic => {
+const navigateToTopic = (topic) => {
if (history.selectedItemsList.length > 0) return;
TopicNotes.navigate(topic, true);
};
-export const NotebookItem = ({ item, isTopic = false, notebookID, isTrash, dateBy }) => {
- const colors = useThemeStore(state => state.colors);
- const notebooksListMode = useSettingStore(state => state.settings.notebooksListMode);
- const compactMode = notebooksListMode === 'compact';
+export const NotebookItem = ({
+ item,
+ isTopic = false,
+ notebookID,
+ isTrash,
+ dateBy
+}) => {
+ const colors = useThemeStore((state) => state.colors);
+ const notebooksListMode = useSettingStore(
+ (state) => state.settings.notebooksListMode
+ );
+ const compactMode = notebooksListMode === "compact";
const topics = item.topics?.slice(0, 3) || [];
const totalNotes = getTotalNotes(item);
@@ -41,7 +49,7 @@ export const NotebookItem = ({ item, isTopic = false, notebookID, isTrash, dateB
size={SIZE.md}
numberOfLines={1}
style={{
- flexWrap: 'wrap'
+ flexWrap: "wrap"
}}
>
{item.title}
@@ -51,7 +59,7 @@ export const NotebookItem = ({ item, isTopic = false, notebookID, isTrash, dateB
size={SIZE.sm}
numberOfLines={2}
style={{
- flexWrap: 'wrap'
+ flexWrap: "wrap"
}}
>
{item.description}
@@ -61,18 +69,18 @@ export const NotebookItem = ({ item, isTopic = false, notebookID, isTrash, dateB
{isTopic || compactMode ? null : (
- {topics.map(topic => (
+ {topics.map((topic) => (
- {isTopic ? 'Topic' : 'Notebook'}
+ {isTopic ? "Topic" : "Notebook"}
{isTrash ? (
@@ -121,17 +129,18 @@ export const NotebookItem = ({ item, isTopic = false, notebookID, isTrash, dateB
color={colors.icon}
size={SIZE.xs}
style={{
- textAlignVertical: 'center',
+ textAlignVertical: "center",
marginRight: 6
}}
>
- {'Deleted on ' + new Date(item.dateDeleted).toISOString().slice(0, 10)}
+ {"Deleted on " +
+ new Date(item.dateDeleted).toISOString().slice(0, 10)}
@@ -157,10 +166,10 @@ export const NotebookItem = ({ item, isTopic = false, notebookID, isTrash, dateB
}}
>
{item && totalNotes > 1
- ? totalNotes + ' notes'
+ ? totalNotes + " notes"
: totalNotes === 1
- ? totalNotes + ' note'
- : '0 notes'}
+ ? totalNotes + " note"
+ : "0 notes"}
{item.pinned ? (
@@ -183,11 +192,11 @@ export const NotebookItem = ({ item, isTopic = false, notebookID, isTrash, dateB
size={SIZE.xl}
onPress={() => showActionSheet(item)}
customStyle={{
- justifyContent: 'center',
+ justifyContent: "center",
height: 35,
width: 35,
borderRadius: 100,
- alignItems: 'center'
+ alignItems: "center"
}}
/>
>
diff --git a/apps/mobile/app/components/list-items/notebook/wrapper.js b/apps/mobile/app/components/list-items/notebook/wrapper.js
index bc6784b4b..0666fff15 100644
--- a/apps/mobile/app/components/list-items/notebook/wrapper.js
+++ b/apps/mobile/app/components/list-items/notebook/wrapper.js
@@ -1,18 +1,18 @@
-import React from 'react';
-import { NotebookItem } from '.';
-import Notebook from '../../../screens/notebook';
-import { TopicNotes } from '../../../screens/notes/topic-notes';
-import { ToastEvent } from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import { useSelectionStore } from '../../../stores/use-selection-store';
-import { useTrashStore } from '../../../stores/use-trash-store';
-import { history } from '../../../utils';
-import { db } from '../../../common/database';
-import { presentDialog } from '../../dialog/functions';
-import SelectionWrapper from '../selection-wrapper';
+import React from "react";
+import { NotebookItem } from ".";
+import Notebook from "../../../screens/notebook";
+import { TopicNotes } from "../../../screens/notes/topic-notes";
+import { ToastEvent } from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import { useSelectionStore } from "../../../stores/use-selection-store";
+import { useTrashStore } from "../../../stores/use-trash-store";
+import { history } from "../../../utils";
+import { db } from "../../../common/database";
+import { presentDialog } from "../../dialog/functions";
+import SelectionWrapper from "../selection-wrapper";
-export const openNotebookTopic = item => {
- const isTrash = item.type === 'trash';
+export const openNotebookTopic = (item) => {
+ const isTrash = item.type === "trash";
if (history.selectedItemsList.length > 0 && history.selectionMode) {
useSelectionStore.getState().setSelectedItem(item);
return;
@@ -24,24 +24,24 @@ export const openNotebookTopic = item => {
presentDialog({
title: `Restore ${item.itemType}`,
paragraph: `Restore or delete ${item.itemType} forever`,
- positiveText: 'Restore',
- negativeText: 'Delete',
+ positiveText: "Restore",
+ negativeText: "Delete",
positivePress: async () => {
await db.trash.restore(item.id);
Navigation.queueRoutesForUpdate(
- 'Tags',
- 'Notes',
- 'Notebooks',
- 'Favorites',
- 'Trash',
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes'
+ "Tags",
+ "Notes",
+ "Notebooks",
+ "Favorites",
+ "Trash",
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes"
);
useSelectionStore.getState().setSelectionMode(false);
ToastEvent.show({
- heading: 'Restore successful',
- type: 'success'
+ heading: "Restore successful",
+ type: "success"
});
},
onClose: async () => {
@@ -49,15 +49,15 @@ export const openNotebookTopic = item => {
useTrashStore.getState().setTrash();
useSelectionStore.getState().setSelectionMode(false);
ToastEvent.show({
- heading: 'Permanantly deleted items',
- type: 'success',
- context: 'local'
+ heading: "Permanantly deleted items",
+ type: "success",
+ context: "local"
});
}
});
return;
}
- if (item.type === 'topic') {
+ if (item.type === "topic") {
TopicNotes.navigate(item, true);
} else {
Notebook.navigate(item, true);
@@ -66,18 +66,18 @@ export const openNotebookTopic = item => {
export const NotebookWrapper = React.memo(
({ item, index, dateBy }) => {
- const isTrash = item.type === 'trash';
+ const isTrash = item.type === "trash";
return (
openNotebookTopic(item)}
- height={item.type === 'topic' ? 80 : 110}
+ height={item.type === "topic" ? 80 : 110}
item={item}
>
{
- const colors = useThemeStore(state => state.colors);
- const selectionMode = useSelectionStore(state => state.selectionMode);
- const setNotebooks = useNotebookStore(state => state.setNotebooks);
- const setMenuPins = useMenuStore(state => state.setMenuPins);
- const setSelectedItem = useSelectionStore(state => state.setSelectedItem);
- const setSelectionMode = useSelectionStore(state => state.setSelectionMode);
+ const colors = useThemeStore((state) => state.colors);
+ const selectionMode = useSelectionStore((state) => state.selectionMode);
+ const setNotebooks = useNotebookStore((state) => state.setNotebooks);
+ const setMenuPins = useMenuStore((state) => state.setMenuPins);
+ const setSelectedItem = useSelectionStore((state) => state.setSelectedItem);
+ const setSelectionMode = useSelectionStore((state) => state.setSelectionMode);
const [isPinnedToMenu, setIsPinnedToMenu] = useState(false);
const [width, setWidth] = useState(dWidth - 16);
useEffect(() => {
- if (note.type === 'note') return;
+ if (note.type === "note") return;
setIsPinnedToMenu(db.settings.isPinned(note.id));
}, []);
const updateNotes = () => {
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes"
);
};
const actions = [
{
- title: 'Pin ' + note.type,
- icon: note.pinned ? 'pin-off' : 'pin',
- visible: note.type === 'note' || note.type === 'notebook',
+ title: "Pin " + note.type,
+ icon: note.pinned ? "pin-off" : "pin",
+ visible: note.type === "note" || note.type === "notebook",
onPress: async () => {
if (!note.id) return;
- if (note.type === 'note') {
+ if (note.type === "note") {
if (db.notes.pinned.length === 3 && !note.pinned) {
ToastEvent.show({
- heading: 'Cannot pin more than 3 notes',
- type: 'error'
+ heading: "Cannot pin more than 3 notes",
+ type: "error"
});
return;
}
@@ -61,8 +61,8 @@ export const ActionStrip = ({ note, setActionStrip }) => {
} else {
if (db.notebooks.pinned.length === 3 && !note.pinned) {
ToastEvent.show({
- heading: 'Cannot pin more than 3 notebooks',
- type: 'error'
+ heading: "Cannot pin more than 3 notebooks",
+ type: "error"
});
return;
}
@@ -74,11 +74,11 @@ export const ActionStrip = ({ note, setActionStrip }) => {
}
},
{
- title: 'Add to favorites',
- icon: note.favorite ? 'star-off' : 'star',
+ title: "Add to favorites",
+ icon: note.favorite ? "star-off" : "star",
onPress: async () => {
if (!note.id) return;
- if (note.type === 'note') {
+ if (note.type === "note") {
await db.notes.note(note.id).favorite();
} else {
await db.notebooks.notebook(note.id).favorite();
@@ -86,23 +86,25 @@ export const ActionStrip = ({ note, setActionStrip }) => {
updateNotes();
setActionStrip(false);
},
- visible: note.type === 'note',
- color: !note.favorite ? 'orange' : null
+ visible: note.type === "note",
+ color: !note.favorite ? "orange" : null
},
{
- title: isPinnedToMenu ? 'Remove Shortcut from Menu' : 'Add Shortcut to Menu',
- icon: isPinnedToMenu ? 'link-variant-remove' : 'link-variant',
+ title: isPinnedToMenu
+ ? "Remove Shortcut from Menu"
+ : "Add Shortcut to Menu",
+ icon: isPinnedToMenu ? "link-variant-remove" : "link-variant",
onPress: async () => {
try {
if (isPinnedToMenu) {
await db.settings.unpin(note.id);
ToastEvent.show({
- heading: 'Shortcut removed from menu',
- type: 'success'
+ heading: "Shortcut removed from menu",
+ type: "success"
});
} else {
- if (note.type === 'topic') {
+ if (note.type === "topic") {
await db.settings.pin(note.type, {
id: note.id,
notebookId: note.notebookId
@@ -111,8 +113,8 @@ export const ActionStrip = ({ note, setActionStrip }) => {
await db.settings.pin(note.type, { id: note.id });
}
ToastEvent.show({
- heading: 'Shortcut added to menu',
- type: 'success'
+ heading: "Shortcut added to menu",
+ type: "success"
});
}
setIsPinnedToMenu(db.settings.isPinned(note.id));
@@ -121,12 +123,12 @@ export const ActionStrip = ({ note, setActionStrip }) => {
setActionStrip(false);
} catch (e) {}
},
- visible: note.type !== 'note'
+ visible: note.type !== "note"
},
{
- title: 'Copy Note',
- icon: 'content-copy',
- visible: note.type === 'note',
+ title: "Copy Note",
+ icon: "content-copy",
+ visible: note.type === "note",
onPress: async () => {
if (note.locked) {
openVault({
@@ -134,75 +136,77 @@ export const ActionStrip = ({ note, setActionStrip }) => {
novault: true,
locked: true,
item: note,
- title: 'Copy note',
- description: 'Unlock note to copy to clipboard.'
+ title: "Copy note",
+ description: "Unlock note to copy to clipboard."
});
} else {
let text = await toTXT(note);
text = `${note.title}\n \n ${text}`;
Clipboard.setString(text);
ToastEvent.show({
- heading: 'Note copied to clipboard',
- type: 'success'
+ heading: "Note copied to clipboard",
+ type: "success"
});
}
setActionStrip(false);
}
},
{
- title: 'Restore ' + note.itemType,
- icon: 'delete-restore',
+ title: "Restore " + note.itemType,
+ icon: "delete-restore",
onPress: async () => {
await db.trash.restore(note.id);
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes',
- 'Trash',
- 'Notebooks'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes",
+ "Trash",
+ "Notebooks"
);
ToastEvent.show({
heading:
- note.type === 'note' ? 'Note restored from trash' : 'Notebook restored from trash',
- type: 'success'
+ note.type === "note"
+ ? "Note restored from trash"
+ : "Notebook restored from trash",
+ type: "success"
});
setActionStrip(false);
},
- visible: note.type === 'trash'
+ visible: note.type === "trash"
},
{
- title: 'Delete' + note.itemType,
- icon: 'delete',
- visible: note.type === 'trash',
+ title: "Delete" + note.itemType,
+ icon: "delete",
+ visible: note.type === "trash",
onPress: () => {
presentDialog({
title: `Permanent delete`,
paragraph: `Are you sure you want to delete this ${note.itemType} permanantly from trash?`,
- positiveText: 'Delete',
- negativeText: 'Cancel',
+ positiveText: "Delete",
+ negativeText: "Cancel",
positivePress: async () => {
await db.trash.delete(note.id);
useTrashStore.getState().setTrash();
useSelectionStore.getState().setSelectionMode(false);
ToastEvent.show({
- heading: 'Permanantly deleted items',
- type: 'success',
- context: 'local'
+ heading: "Permanantly deleted items",
+ type: "success",
+ context: "local"
});
},
- positiveType: 'errorShade'
+ positiveType: "errorShade"
});
setActionStrip(false);
}
},
{
- title: 'Delete' + note.type,
- icon: 'delete',
- visible: note.type !== 'trash',
+ title: "Delete" + note.type,
+ icon: "delete",
+ visible: note.type !== "trash",
onPress: async () => {
try {
await deleteItems(note);
@@ -211,8 +215,8 @@ export const ActionStrip = ({ note, setActionStrip }) => {
}
},
{
- title: 'Close',
- icon: 'close',
+ title: "Close",
+ icon: "close",
onPress: () => setActionStrip(false),
color: colors.light,
bg: colors.red,
@@ -222,19 +226,19 @@ export const ActionStrip = ({ note, setActionStrip }) => {
return (
{
+ onLayout={(event) => {
setWidth(event.nativeEvent.layout.width);
}}
entering={SlideInUp.springify().mass(0.4)}
exiting={SlideOutDown}
style={{
- position: 'absolute',
+ position: "absolute",
zIndex: 999,
- width: '102%',
- height: '100%',
- flexDirection: 'row',
- justifyContent: 'flex-end',
- alignItems: 'center'
+ width: "102%",
+ height: "100%",
+ flexDirection: "row",
+ justifyContent: "flex-end",
+ alignItems: "center"
}}
>
{
title="Select"
icon="check"
tooltipText="Select Item"
- onPress={event => {
+ onPress={(event) => {
if (!selectionMode) {
setSelectionMode(true);
}
@@ -256,7 +260,7 @@ export const ActionStrip = ({ note, setActionStrip }) => {
}}
height={30}
/>
- {actions.map(item =>
+ {actions.map((item) =>
item.visible ? (
{
height: width / 1.4 / actions.length,
backgroundColor: item.bg || colors.nav,
borderRadius: 100,
- justifyContent: 'center',
- alignItems: 'center',
+ justifyContent: "center",
+ alignItems: "center",
...getElevation(5),
marginLeft: 15
}}
diff --git a/apps/mobile/app/components/list-items/selection-wrapper/back-fill.js b/apps/mobile/app/components/list-items/selection-wrapper/back-fill.js
index b6fe3921b..00c7241d8 100644
--- a/apps/mobile/app/components/list-items/selection-wrapper/back-fill.js
+++ b/apps/mobile/app/components/list-items/selection-wrapper/back-fill.js
@@ -1,26 +1,33 @@
-import React from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { useEditorStore } from '../../../stores/use-editor-store';
-import { hexToRGBA } from '../../../utils/color-scheme/utils';
+import React from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { useEditorStore } from "../../../stores/use-editor-store";
+import { hexToRGBA } from "../../../utils/color-scheme/utils";
export const Filler = ({ item, background }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
- const currentEditingNote = useEditorStore(state => state.currentEditingNote);
+ const currentEditingNote = useEditorStore(
+ (state) => state.currentEditingNote
+ );
- const color = 'gray';
+ const color = "gray";
return currentEditingNote === item.id ? (
) : null;
diff --git a/apps/mobile/app/components/list-items/selection-wrapper/index.js b/apps/mobile/app/components/list-items/selection-wrapper/index.js
index c99b42c5d..c8cb392b2 100644
--- a/apps/mobile/app/components/list-items/selection-wrapper/index.js
+++ b/apps/mobile/app/components/list-items/selection-wrapper/index.js
@@ -1,20 +1,36 @@
-import React, { useEffect, useState } from 'react';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../../services/event-manager';
-import { useSettingStore } from '../../../stores/use-setting-store';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { history } from '../../../utils';
-import { PressableButton } from '../../ui/pressable';
-import { ActionStrip } from './action-strip';
-import { Filler } from './back-fill';
-import { SelectionIcon } from './selection';
+import React, { useEffect, useState } from "react";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../../services/event-manager";
+import { useSettingStore } from "../../../stores/use-setting-store";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { history } from "../../../utils";
+import { PressableButton } from "../../ui/pressable";
+import { ActionStrip } from "./action-strip";
+import { Filler } from "./back-fill";
+import { SelectionIcon } from "./selection";
-const SelectionWrapper = ({ children, item, background, onLongPress, onPress, testID }) => {
- const colors = useThemeStore(state => state.colors);
+const SelectionWrapper = ({
+ children,
+ item,
+ background,
+ onLongPress,
+ onPress,
+ testID
+}) => {
+ const colors = useThemeStore((state) => state.colors);
const [actionStrip, setActionStrip] = useState(false);
- const notebooksListMode = useSettingStore(state => state.settings.notebooksListMode);
- const notesListMode = useSettingStore(state => state.settings.notesListMode);
- const listMode = item.type === 'notebook' ? notebooksListMode : notesListMode;
- const compactMode = (item.type === 'notebook' || item.type === 'note') && listMode === 'compact';
+ const notebooksListMode = useSettingStore(
+ (state) => state.settings.notebooksListMode
+ );
+ const notesListMode = useSettingStore(
+ (state) => state.settings.notesListMode
+ );
+ const listMode = item.type === "notebook" ? notebooksListMode : notesListMode;
+ const compactMode =
+ (item.type === "notebook" || item.type === "note") &&
+ listMode === "compact";
const _onLongPress = () => {
if (history.selectedItemsList.length > 0) return;
@@ -34,10 +50,10 @@ const SelectionWrapper = ({ children, item, background, onLongPress, onPress, te
};
useEffect(() => {
- eSubscribeEvent('navigate', closeStrip);
+ eSubscribeEvent("navigate", closeStrip);
return () => {
- eUnSubscribeEvent('navigate', closeStrip);
+ eUnSubscribeEvent("navigate", closeStrip);
};
}, []);
@@ -51,17 +67,19 @@ const SelectionWrapper = ({ children, item, background, onLongPress, onPress, te
customAlpha={!colors.night ? -0.02 : 0.02}
customOpacity={1}
customStyle={{
- flexDirection: 'row',
- justifyContent: 'space-between',
- alignItems: 'center',
- width: '100%',
+ flexDirection: "row",
+ justifyContent: "space-between",
+ alignItems: "center",
+ width: "100%",
borderRadius: 0,
- overflow: 'hidden',
+ overflow: "hidden",
paddingHorizontal: 12,
paddingVertical: compactMode ? 8 : 12
}}
>
- {item.type === 'note' ? : null}
+ {item.type === "note" ? (
+
+ ) : null}
{children}
- {actionStrip ? : null}
+ {actionStrip ? (
+
+ ) : null}
);
};
diff --git a/apps/mobile/app/components/list-items/selection-wrapper/selection.js b/apps/mobile/app/components/list-items/selection-wrapper/selection.js
index d9c7938e4..01d5227a1 100644
--- a/apps/mobile/app/components/list-items/selection-wrapper/selection.js
+++ b/apps/mobile/app/components/list-items/selection-wrapper/selection.js
@@ -1,22 +1,26 @@
-import React, { useEffect, useState } from 'react';
-import { TouchableOpacity, View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { useSelectionStore } from '../../../stores/use-selection-store';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { SIZE } from '../../../utils/size';
+import React, { useEffect, useState } from "react";
+import { TouchableOpacity, View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { useSelectionStore } from "../../../stores/use-selection-store";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { SIZE } from "../../../utils/size";
export const SelectionIcon = ({ setActionStrip, item, compactMode }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
- const selectionMode = useSelectionStore(state => state.selectionMode);
- const selectedItemsList = useSelectionStore(state => state.selectedItemsList);
- const setSelectedItem = useSelectionStore(state => state.setSelectedItem);
+ const selectionMode = useSelectionStore((state) => state.selectionMode);
+ const selectedItemsList = useSelectionStore(
+ (state) => state.selectedItemsList
+ );
+ const setSelectedItem = useSelectionStore((state) => state.setSelectedItem);
const [selected, setSelected] = useState(false);
useEffect(() => {
if (selectionMode) {
setActionStrip(false);
- let exists = selectedItemsList.filter(o => o.dateCreated === item.dateCreated);
+ let exists = selectedItemsList.filter(
+ (o) => o.dateCreated === item.dateCreated
+ );
if (exists[0]) {
if (!selected) {
@@ -37,12 +41,12 @@ export const SelectionIcon = ({ setActionStrip, item, compactMode }) => {
return selectionMode ? (
{
activeOpacity={1}
onPress={onPress}
style={{
- justifyContent: 'center',
- alignItems: 'center',
+ justifyContent: "center",
+ alignItems: "center",
height: 70
}}
>
{selected && (
-
+
)}
diff --git a/apps/mobile/app/components/list-items/tag/index.js b/apps/mobile/app/components/list-items/tag/index.js
index 8f2459235..97b135b13 100644
--- a/apps/mobile/app/components/list-items/tag/index.js
+++ b/apps/mobile/app/components/list-items/tag/index.js
@@ -1,19 +1,19 @@
-import React from 'react';
-import { View } from 'react-native';
-import { notesnook } from '../../../../e2e/test.ids';
-import { TaggedNotes } from '../../../screens/notes/tagged';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { db } from '../../../common/database';
-import { SIZE } from '../../../utils/size';
-import { Properties } from '../../properties';
-import { IconButton } from '../../ui/icon-button';
-import { PressableButton } from '../../ui/pressable';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
+import React from "react";
+import { View } from "react-native";
+import { notesnook } from "../../../../e2e/test.ids";
+import { TaggedNotes } from "../../../screens/notes/tagged";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { db } from "../../../common/database";
+import { SIZE } from "../../../utils/size";
+import { Properties } from "../../properties";
+import { IconButton } from "../../ui/icon-button";
+import { PressableButton } from "../../ui/pressable";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
const TagItem = React.memo(
({ item, index }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const onPress = () => {
TaggedNotes.navigate(item, true);
};
@@ -27,16 +27,16 @@ const TagItem = React.memo(
opacity={1}
customStyle={{
paddingHorizontal: 12,
- flexDirection: 'row',
+ flexDirection: "row",
paddingVertical: 12,
- alignItems: 'center',
- width: '100%',
- justifyContent: 'space-between'
+ alignItems: "center",
+ width: "100%",
+ justifyContent: "space-between"
}}
>
@@ -58,9 +58,9 @@ const TagItem = React.memo(
}}
>
{item && item.noteIds.length && item.noteIds.length > 1
- ? item.noteIds.length + ' notes'
+ ? item.noteIds.length + " notes"
: item.noteIds.length === 1
- ? item.noteIds.length + ' note'
+ ? item.noteIds.length + " note"
: null}
@@ -74,11 +74,11 @@ const TagItem = React.memo(
}}
testID={notesnook.ids.tag.menu}
customStyle={{
- justifyContent: 'center',
+ justifyContent: "center",
height: 35,
width: 35,
borderRadius: 100,
- alignItems: 'center'
+ alignItems: "center"
}}
/>
@@ -96,6 +96,6 @@ const TagItem = React.memo(
}
);
-TagItem.displayName = 'TagItem';
+TagItem.displayName = "TagItem";
export default TagItem;
diff --git a/apps/mobile/app/components/list/card.js b/apps/mobile/app/components/list/card.js
index 9711d624e..038d199cb 100644
--- a/apps/mobile/app/components/list/card.js
+++ b/apps/mobile/app/components/list/card.js
@@ -1,23 +1,23 @@
-import React from 'react';
-import { View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { useMessageStore } from '../../stores/use-message-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { hexToRGBA } from '../../utils/color-scheme/utils';
-import { SIZE } from '../../utils/size';
-import { PressableButton } from '../ui/pressable';
-import Paragraph from '../ui/typography/paragraph';
+import React from "react";
+import { View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { useMessageStore } from "../../stores/use-message-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { hexToRGBA } from "../../utils/color-scheme/utils";
+import { SIZE } from "../../utils/size";
+import { PressableButton } from "../ui/pressable";
+import Paragraph from "../ui/typography/paragraph";
export const Card = ({ color, warning }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
color = color ? color : colors.accent;
- const messageBoardState = useMessageStore(state => state.message);
- const announcement = useMessageStore(state => state.announcement);
+ const messageBoardState = useMessageStore((state) => state.message);
+ const announcement = useMessageStore((state) => state.announcement);
return !messageBoardState.visible || announcement || warning ? null : (
{
type="gray"
customStyle={{
paddingVertical: 12,
- width: '95%',
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'flex-start',
+ width: "95%",
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "flex-start",
paddingHorizontal: 0
}}
>
@@ -36,19 +36,21 @@ export const Card = ({ color, warning }) => {
style={{
width: 40,
backgroundColor:
- messageBoardState.type === 'error'
+ messageBoardState.type === "error"
? hexToRGBA(colors.red, 0.15)
: hexToRGBA(color, 0.15),
height: 40,
marginLeft: 10,
borderRadius: 100,
- alignItems: 'center',
- justifyContent: 'center'
+ alignItems: "center",
+ justifyContent: "center"
}}
>
@@ -56,7 +58,7 @@ export const Card = ({ color, warning }) => {
@@ -64,7 +66,7 @@ export const Card = ({ color, warning }) => {
@@ -76,15 +78,15 @@ export const Card = ({ color, warning }) => {
style={{
width: 40,
height: 40,
- justifyContent: 'center',
- alignItems: 'center',
- position: 'absolute',
+ justifyContent: "center",
+ alignItems: "center",
+ position: "absolute",
right: 6
}}
>
diff --git a/apps/mobile/app/components/list/empty.js b/apps/mobile/app/components/list/empty.js
index 3c188ca67..ff8a2b78e 100644
--- a/apps/mobile/app/components/list/empty.js
+++ b/apps/mobile/app/components/list/empty.js
@@ -1,49 +1,61 @@
-import React from 'react';
-import { ActivityIndicator, useWindowDimensions, View } from 'react-native';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { useTip } from '../../services/tip-manager';
-import { COLORS_NOTE } from '../../utils/color-scheme';
-import { SIZE } from '../../utils/size';
-import { Button } from '../ui/button';
-import Seperator from '../ui/seperator';
-import { Tip } from '../tip';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import { notesnook } from '../../../e2e/test.ids';
+import React from "react";
+import { ActivityIndicator, useWindowDimensions, View } from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { useTip } from "../../services/tip-manager";
+import { COLORS_NOTE } from "../../utils/color-scheme";
+import { SIZE } from "../../utils/size";
+import { Button } from "../ui/button";
+import Seperator from "../ui/seperator";
+import { Tip } from "../tip";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import { notesnook } from "../../../e2e/test.ids";
export const Empty = React.memo(
({ loading = true, placeholderData, headerProps, type, screen }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const insets = useSafeAreaInsets();
const { height } = useWindowDimensions();
- const introCompleted = useSettingStore(state => state.settings.introCompleted);
+ const introCompleted = useSettingStore(
+ (state) => state.settings.introCompleted
+ );
const tip = useTip(
- screen === 'Notes' && introCompleted ? 'first-note' : placeholderData.type || type,
- screen === 'Notes' ? 'notes' : null
+ screen === "Notes" && introCompleted
+ ? "first-note"
+ : placeholderData.type || type,
+ screen === "Notes" ? "notes" : null
);
const color =
- colors[COLORS_NOTE[headerProps.color?.toLowerCase()] ? headerProps.color : 'accent'];
+ colors[
+ COLORS_NOTE[headerProps.color?.toLowerCase()]
+ ? headerProps.color
+ : "accent"
+ ];
return (
{!loading ? (
<>
@@ -56,11 +68,13 @@ export const Empty = React.memo(
icon="arrow-right"
onPress={placeholderData.action}
accentColor={
- COLORS_NOTE[headerProps.color?.toLowerCase()] ? headerProps.color : 'accent'
+ COLORS_NOTE[headerProps.color?.toLowerCase()]
+ ? headerProps.color
+ : "accent"
}
accentText="light"
style={{
- alignSelf: 'flex-start',
+ alignSelf: "flex-start",
borderRadius: 5,
height: 40
}}
@@ -71,9 +85,9 @@ export const Empty = React.memo(
<>
{placeholderData.heading}
@@ -83,7 +97,9 @@ export const Empty = React.memo(
>
diff --git a/apps/mobile/app/components/list/index.js b/apps/mobile/app/components/list/index.js
index 42273a5fc..b0e5474e6 100644
--- a/apps/mobile/app/components/list/index.js
+++ b/apps/mobile/app/components/list/index.js
@@ -1,21 +1,21 @@
-import React, { useRef } from 'react';
-import { FlatList, RefreshControl, View } from 'react-native';
-import Animated, { FadeInDown } from 'react-native-reanimated';
-import { notesnook } from '../../../e2e/test.ids';
-import { eSendEvent } from '../../services/event-manager';
-import Sync from '../../services/sync';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { db } from '../../common/database';
-import { eScrollEvent } from '../../utils/events';
-import { tabBarRef } from '../../utils/global-refs';
-import JumpToSectionDialog from '../dialogs/jump-to-section';
-import { Footer } from '../list-items/footer';
-import { Header } from '../list-items/headers/header';
-import { SectionHeader } from '../list-items/headers/section-header';
-import { NoteWrapper } from '../list-items/note/wrapper';
-import { NotebookWrapper } from '../list-items/notebook/wrapper';
-import TagItem from '../list-items/tag';
-import { Empty } from './empty';
+import React, { useRef } from "react";
+import { FlatList, RefreshControl, View } from "react-native";
+import Animated, { FadeInDown } from "react-native-reanimated";
+import { notesnook } from "../../../e2e/test.ids";
+import { eSendEvent } from "../../services/event-manager";
+import Sync from "../../services/sync";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { db } from "../../common/database";
+import { eScrollEvent } from "../../utils/events";
+import { tabBarRef } from "../../utils/global-refs";
+import JumpToSectionDialog from "../dialogs/jump-to-section";
+import { Footer } from "../list-items/footer";
+import { Header } from "../list-items/headers/header";
+import { SectionHeader } from "../list-items/headers/section-header";
+import { NoteWrapper } from "../list-items/note/wrapper";
+import { NotebookWrapper } from "../list-items/notebook/wrapper";
+import TagItem from "../list-items/tag";
+import { Empty } from "./empty";
const renderItems = {
note: NoteWrapper,
@@ -30,12 +30,13 @@ const RenderItem = ({ item, index, type, ...restArgs }) => {
if (!item) return ;
const Item = renderItems[item.itemType || item.type] || View;
const groupOptions = db.settings?.getGroupOptions(type);
- const dateBy = groupOptions.sortBy !== 'title' ? groupOptions.sortBy : 'dateEdited';
+ const dateBy =
+ groupOptions.sortBy !== "title" ? groupOptions.sortBy : "dateEdited";
const tags =
item.tags
?.slice(0, 3)
- ?.map(item => {
+ ?.map((item) => {
let tag = db.tags.tag(item);
if (!tag) return null;
@@ -45,8 +46,17 @@ const RenderItem = ({ item, index, type, ...restArgs }) => {
alias: tag.alias
};
})
- .filter(t => t !== null) || [];
- return ;
+ .filter((t) => t !== null) || [];
+ return (
+
+ );
};
const List = ({
@@ -56,14 +66,14 @@ const List = ({
placeholderData,
loading,
headerProps = {
- heading: 'Home',
+ heading: "Home",
color: null
},
screen,
ListHeader,
warning
}) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const scrollRef = useRef();
const renderItem = React.useCallback(
@@ -73,7 +83,7 @@ const List = ({
index={index}
color={headerProps.color}
title={headerProps.heading}
- type={screen === 'Notes' ? 'home' : type}
+ type={screen === "Notes" ? "home" : type}
screen={screen}
/>
),
@@ -81,7 +91,7 @@ const List = ({
);
const _onRefresh = async () => {
- Sync.run('global', false, true, () => {
+ Sync.run("global", false, true, () => {
if (refreshCallback) {
refreshCallback();
}
@@ -89,7 +99,7 @@ const List = ({
};
const _onScroll = React.useCallback(
- event => {
+ (event) => {
if (!event) return;
let y = event.nativeEvent.contentOffset.y;
eSendEvent(eScrollEvent, {
@@ -101,12 +111,12 @@ const List = ({
);
let styles = {
- width: '100%',
+ width: "100%",
minHeight: 1,
minWidth: 1
};
- const _keyExtractor = item => item.id || item.title;
+ const _keyExtractor = (item) => item.id || item.title;
return (
<>
@@ -114,7 +124,7 @@ const List = ({
style={{
flex: 1
}}
- entering={type === 'search' ? undefined : FadeInDown}
+ entering={type === "search" ? undefined : FadeInDown}
>
>
diff --git a/apps/mobile/app/components/merge-conflicts/index.js b/apps/mobile/app/components/merge-conflicts/index.js
index 3121c1436..888719ccb 100644
--- a/apps/mobile/app/components/merge-conflicts/index.js
+++ b/apps/mobile/app/components/merge-conflicts/index.js
@@ -1,31 +1,35 @@
-import KeepAwake from '@sayem314/react-native-keep-awake';
-import React, { useEffect, useRef, useState } from 'react';
-import { Modal, SafeAreaView, Text, View } from 'react-native';
-import Animated from 'react-native-reanimated';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import Editor from '../../screens/editor';
-import { editorController } from '../../screens/editor/tiptap/utils';
-import { DDS } from '../../services/device-detection';
-import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import Navigation from '../../services/navigation';
-import Sync from '../../services/sync';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { dHeight } from '../../utils';
-import { db } from '../../common/database';
-import { eOnLoadNote, eShowMergeDialog } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { timeConverter } from '../../utils/time';
-import BaseDialog from '../dialog/base-dialog';
-import DialogButtons from '../dialog/dialog-buttons';
-import DialogContainer from '../dialog/dialog-container';
-import DialogHeader from '../dialog/dialog-header';
-import { Button } from '../ui/button';
-import { IconButton } from '../ui/icon-button';
-import Seperator from '../ui/seperator';
-import Paragraph from '../ui/typography/paragraph';
+import KeepAwake from "@sayem314/react-native-keep-awake";
+import React, { useEffect, useRef, useState } from "react";
+import { Modal, SafeAreaView, Text, View } from "react-native";
+import Animated from "react-native-reanimated";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import Editor from "../../screens/editor";
+import { editorController } from "../../screens/editor/tiptap/utils";
+import { DDS } from "../../services/device-detection";
+import {
+ eSendEvent,
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import Navigation from "../../services/navigation";
+import Sync from "../../services/sync";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { dHeight } from "../../utils";
+import { db } from "../../common/database";
+import { eOnLoadNote, eShowMergeDialog } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { timeConverter } from "../../utils/time";
+import BaseDialog from "../dialog/base-dialog";
+import DialogButtons from "../dialog/dialog-buttons";
+import DialogContainer from "../dialog/dialog-container";
+import DialogHeader from "../dialog/dialog-header";
+import { Button } from "../ui/button";
+import { IconButton } from "../ui/icon-button";
+import Seperator from "../ui/seperator";
+import Paragraph from "../ui/typography/paragraph";
const MergeConflicts = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [visible, setVisible] = useState(false);
const [keep, setKeep] = useState(null);
const [copy, setCopy] = useState(null);
@@ -55,7 +59,7 @@ const MergeConflicts = () => {
if (copy) {
await db.notes.add({
- title: note.title + ' (Copy)',
+ title: note.title + " (Copy)",
content: {
data: copy.data,
type: copy.type
@@ -63,21 +67,24 @@ const MergeConflicts = () => {
});
}
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes"
);
if (editorController.current?.note?.id === note.id) {
// reload the note in editor
- eSendEvent(eOnLoadNote, { ...editorController.current?.note, forced: true });
+ eSendEvent(eOnLoadNote, {
+ ...editorController.current?.note,
+ forced: true
+ });
}
close();
Sync.run();
};
- const show = async item => {
+ const show = async (item) => {
let noteContent = await db.content.raw(item.contentId);
content.current = { ...noteContent };
if (__DEV__) {
@@ -102,42 +109,59 @@ const MergeConflicts = () => {
setDialogVisible(false);
};
- const ConfigBar = ({ isDiscarded, keeping, back, isCurrent, contentToKeep }) => {
+ const ConfigBar = ({
+ isDiscarded,
+ keeping,
+ back,
+ isCurrent,
+ contentToKeep
+ }) => {
return (
- {back && }
-
-
- {isCurrent ? '(This Device)' : '(Incoming)'}
+ {back && (
+
+ )}
+
+
+ {isCurrent ? "(This Device)" : "(Incoming)"}
- {'\n'}
+ {"\n"}
{timeConverter(contentToKeep?.dateEdited)}
{isDiscarded ? (
@@ -187,7 +211,7 @@ const MergeConflicts = () => {
}}
type="accent"
fontSize={SIZE.xs}
- title={keeping && !isDiscarded ? 'Undo' : 'Keep'}
+ title={keeping && !isDiscarded ? "Undo" : "Keep"}
onPress={() => {
setKeep(keeping && !isDiscarded ? null : contentToKeep);
}}
@@ -208,11 +232,11 @@ const MergeConflicts = () => {
close();
}}
supportedOrientations={[
- 'portrait',
- 'portrait-upside-down',
- 'landscape',
- 'landscape-left',
- 'landscape-right'
+ "portrait",
+ "portrait-upside-down",
+ "landscape",
+ "landscape-left",
+ "landscape-right"
]}
visible={true}
>
@@ -244,9 +268,9 @@ const MergeConflicts = () => {
{
onLoad={() => {
const note = db.notes.note(content.current?.noteId)?.data;
if (!note) return;
- eSendEvent(eOnLoadNote + ':conflictPrimary', {
+ eSendEvent(eOnLoadNote + ":conflictPrimary", {
...note,
content: {
...content.current,
@@ -307,7 +331,7 @@ const MergeConflicts = () => {
onLoad={() => {
const note = db.notes.note(content.current?.noteId)?.data;
if (!note) return;
- eSendEvent(eOnLoadNote + ':conflictSecondary', {
+ eSendEvent(eOnLoadNote + ":conflictSecondary", {
...note,
content: { ...content.current.conflicted, isPreview: true }
});
diff --git a/apps/mobile/app/components/note-history/index.js b/apps/mobile/app/components/note-history/index.js
index acbe2ef52..390c66ecb 100644
--- a/apps/mobile/app/components/note-history/index.js
+++ b/apps/mobile/app/components/note-history/index.js
@@ -1,24 +1,24 @@
-import React, { useCallback, useEffect, useState } from 'react';
-import { Text, View } from 'react-native';
-import { FlatList } from 'react-native-gesture-handler';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { presentSheet } from '../../services/event-manager';
-import { db } from '../../common/database';
-import { openLinkInBrowser } from '../../utils/functions';
-import { SIZE } from '../../utils/size';
-import { timeConverter, timeSince } from '../../utils/time';
-import DialogHeader from '../dialog/dialog-header';
-import SheetProvider from '../sheet-provider';
-import { PressableButton } from '../ui/pressable';
-import Seperator from '../ui/seperator';
-import Paragraph from '../ui/typography/paragraph';
-import NotePreview from './preview';
+import React, { useCallback, useEffect, useState } from "react";
+import { Text, View } from "react-native";
+import { FlatList } from "react-native-gesture-handler";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { presentSheet } from "../../services/event-manager";
+import { db } from "../../common/database";
+import { openLinkInBrowser } from "../../utils/functions";
+import { SIZE } from "../../utils/size";
+import { timeConverter, timeSince } from "../../utils/time";
+import DialogHeader from "../dialog/dialog-header";
+import SheetProvider from "../sheet-provider";
+import { PressableButton } from "../ui/pressable";
+import Seperator from "../ui/seperator";
+import Paragraph from "../ui/typography/paragraph";
+import NotePreview from "./preview";
export default function NoteHistory({ note, fwdRef }) {
const [history, setHistory] = useState([]);
const [loading, setLoading] = useState(true);
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
useEffect(() => {
(async () => {
@@ -40,7 +40,7 @@ export default function NoteHistory({ note, fwdRef }) {
content={content}
/>
),
- context: 'note_history'
+ context: "note_history"
});
}
@@ -48,12 +48,12 @@ export default function NoteHistory({ note, fwdRef }) {
let _start = timeConverter(start);
let _end = timeConverter(end + 60000);
if (_start === _end) return _start;
- let final = _end.lastIndexOf(',');
+ let final = _end.lastIndexOf(",");
let part = _end.slice(0, final + 1);
if (_start.includes(part)) {
- return _start + ' —' + _end.replace(part, '');
+ return _start + " —" + _end.replace(part, "");
}
- return _start + ' — ' + _end;
+ return _start + " — " + _end;
};
const renderItem = useCallback(
@@ -62,12 +62,12 @@ export default function NoteHistory({ note, fwdRef }) {
type="grayBg"
onPress={() => preview(item)}
customStyle={{
- justifyContent: 'space-between',
- alignItems: 'center',
+ justifyContent: "space-between",
+ alignItems: "center",
paddingHorizontal: 12,
height: 45,
marginBottom: 10,
- flexDirection: 'row'
+ flexDirection: "row"
}}
>
{getDate(item.dateCreated, item.dateModified)}
@@ -97,19 +97,21 @@ export default function NoteHistory({ note, fwdRef }) {
style={{
paddingHorizontal: 12
}}
- keyExtractor={item => item.id}
+ keyExtractor={(item) => item.id}
data={history}
ListEmptyComponent={
- No note history found on this device.
+
+ No note history found on this device.
+
}
renderItem={renderItem}
@@ -118,15 +120,18 @@ export default function NoteHistory({ note, fwdRef }) {
size={SIZE.xs}
color={colors.icon}
style={{
- alignSelf: 'center'
+ alignSelf: "center"
}}
>
- Note version history is local only.{' '}
+ Note version history is local only.{" "}
{
- openLinkInBrowser('https://docs.notesnook.com/versionhistory', colors);
+ openLinkInBrowser(
+ "https://docs.notesnook.com/versionhistory",
+ colors
+ );
}}
- style={{ color: colors.accent, textDecorationLine: 'underline' }}
+ style={{ color: colors.accent, textDecorationLine: "underline" }}
>
Learn how this works.
diff --git a/apps/mobile/app/components/note-history/preview.js b/apps/mobile/app/components/note-history/preview.js
index ca2290401..5134db10e 100644
--- a/apps/mobile/app/components/note-history/preview.js
+++ b/apps/mobile/app/components/note-history/preview.js
@@ -1,42 +1,45 @@
-import React from 'react';
-import { View } from 'react-native';
-import Editor from '../../screens/editor';
-import EditorOverlay from '../../screens/editor/loading';
-import { editorController } from '../../screens/editor/tiptap/utils';
-import { eSendEvent, ToastEvent } from '../../services/event-manager';
-import Navigation from '../../services/navigation';
-import { useEditorStore } from '../../stores/use-editor-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { db } from '../../common/database';
-import { eCloseProgressDialog, eOnLoadNote } from '../../utils/events';
-import DialogHeader from '../dialog/dialog-header';
-import { Button } from '../ui/button';
-import Paragraph from '../ui/typography/paragraph';
+import React from "react";
+import { View } from "react-native";
+import Editor from "../../screens/editor";
+import EditorOverlay from "../../screens/editor/loading";
+import { editorController } from "../../screens/editor/tiptap/utils";
+import { eSendEvent, ToastEvent } from "../../services/event-manager";
+import Navigation from "../../services/navigation";
+import { useEditorStore } from "../../stores/use-editor-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { db } from "../../common/database";
+import { eCloseProgressDialog, eOnLoadNote } from "../../utils/events";
+import DialogHeader from "../dialog/dialog-header";
+import { Button } from "../ui/button";
+import Paragraph from "../ui/typography/paragraph";
export default function NotePreview({ session, content }) {
- const colors = useThemeStore(state => state.colors);
- const editorId = ':noteHistory';
+ const colors = useThemeStore((state) => state.colors);
+ const editorId = ":noteHistory";
async function restore() {
await db.noteHistory.restore(session.id);
if (useEditorStore.getState()?.currentEditingNote === session?.noteId) {
if (editorController.current?.note) {
- eSendEvent(eOnLoadNote, { ...editorController.current?.note, forced: true });
+ eSendEvent(eOnLoadNote, {
+ ...editorController.current?.note,
+ forced: true
+ });
}
}
- eSendEvent(eCloseProgressDialog, 'note_history');
+ eSendEvent(eCloseProgressDialog, "note_history");
eSendEvent(eCloseProgressDialog);
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes"
);
ToastEvent.show({
- heading: 'Note restored successfully',
- type: 'success'
+ heading: "Note restored successfully",
+ type: "success"
});
}
@@ -44,7 +47,7 @@ export default function NotePreview({ session, content }) {
@@ -71,13 +74,15 @@ export default function NotePreview({ session, content }) {
) : (
- Preview not available, content is encrypted.
+
+ Preview not available, content is encrypted.
+
)}
@@ -86,7 +91,12 @@ export default function NotePreview({ session, content }) {
paddingHorizontal: 12
}}
>
-
+
);
diff --git a/apps/mobile/app/components/premium/compact-features.js b/apps/mobile/app/components/premium/compact-features.js
index 2dd2d90be..8fd0db498 100644
--- a/apps/mobile/app/components/premium/compact-features.js
+++ b/apps/mobile/app/components/premium/compact-features.js
@@ -1,50 +1,55 @@
-import React from 'react';
-import { ScrollView } from 'react-native';
-import { FeatureBlock } from './feature';
+import React from "react";
+import { ScrollView } from "react-native";
+import { FeatureBlock } from "./feature";
-export const CompactFeatures = ({ vertical, features = [], maxHeight = 500, scrollRef }) => {
+export const CompactFeatures = ({
+ vertical,
+ features = [],
+ maxHeight = 500,
+ scrollRef
+}) => {
let data = vertical
? features
: [
{
- highlight: 'Everything',
- content: 'in basic',
- icon: 'emoticon-wink'
+ highlight: "Everything",
+ content: "in basic",
+ icon: "emoticon-wink"
},
{
- highlight: 'Unlimited',
- content: 'notebooks',
- icon: 'notebook'
+ highlight: "Unlimited",
+ content: "notebooks",
+ icon: "notebook"
},
{
- highlight: 'File & image',
- content: 'attachments',
- icon: 'attachment'
+ highlight: "File & image",
+ content: "attachments",
+ icon: "attachment"
},
{
- highlight: 'Instant',
- content: 'syncing',
- icon: 'sync'
+ highlight: "Instant",
+ content: "syncing",
+ icon: "sync"
},
{
- highlight: 'Private',
- content: 'vault',
- icon: 'shield'
+ highlight: "Private",
+ content: "vault",
+ icon: "shield"
},
{
- highlight: 'Rich text',
- content: 'editing',
- icon: 'square-edit-outline'
+ highlight: "Rich text",
+ content: "editing",
+ icon: "square-edit-outline"
},
{
- highlight: 'PDF & markdown',
- content: 'exports',
- icon: 'file'
+ highlight: "PDF & markdown",
+ content: "exports",
+ icon: "file"
},
{
- highlight: 'Encrypted',
- content: 'backups',
- icon: 'backup-restore'
+ highlight: "Encrypted",
+ content: "backups",
+ icon: "backup-restore"
}
];
@@ -57,11 +62,11 @@ export const CompactFeatures = ({ vertical, features = [], maxHeight = 500, scro
}}
showsHorizontalScrollIndicator={false}
style={{
- width: '100%',
+ width: "100%",
maxHeight: maxHeight
}}
>
- {data.map(item => (
+ {data.map((item) => (
))}
diff --git a/apps/mobile/app/components/premium/component.js b/apps/mobile/app/components/premium/component.js
index 0a4eea7d0..9f81864ab 100644
--- a/apps/mobile/app/components/premium/component.js
+++ b/apps/mobile/app/components/premium/component.js
@@ -1,62 +1,64 @@
-import React, { useState } from 'react';
-import { ActivityIndicator, ScrollView, View } from 'react-native';
-import { LAUNCH_ROCKET } from '../../assets/images/assets';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useUserStore } from '../../stores/use-user-store';
-import { DDS } from '../../services/device-detection';
-import { eSendEvent, presentSheet } from '../../services/event-manager';
-import PremiumService from '../../services/premium';
-import { getElevation } from '../../utils';
-import { db } from '../../common/database';
+import React, { useState } from "react";
+import { ActivityIndicator, ScrollView, View } from "react-native";
+import { LAUNCH_ROCKET } from "../../assets/images/assets";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useUserStore } from "../../stores/use-user-store";
+import { DDS } from "../../services/device-detection";
+import { eSendEvent, presentSheet } from "../../services/event-manager";
+import PremiumService from "../../services/premium";
+import { getElevation } from "../../utils";
+import { db } from "../../common/database";
import {
eClosePremiumDialog,
eCloseProgressDialog,
eOpenLoginDialog,
eOpenResultDialog
-} from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import umami from '../../common/analytics';
-import { IconButton } from '../ui/icon-button';
-import { AuthMode } from '../auth';
-import { Button } from '../ui/button';
-import SheetProvider from '../sheet-provider';
-import { SvgView } from '../ui/svg';
-import Seperator from '../ui/seperator';
-import { Toast } from '../toast';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import { Walkthrough } from '../walkthroughs';
-import { features } from './features';
-import { Group } from './group';
-import { PricingPlans } from './pricing-plans';
-import { usePricing } from '../../hooks/use-pricing';
+} from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import umami from "../../common/analytics";
+import { IconButton } from "../ui/icon-button";
+import { AuthMode } from "../auth";
+import { Button } from "../ui/button";
+import SheetProvider from "../sheet-provider";
+import { SvgView } from "../ui/svg";
+import Seperator from "../ui/seperator";
+import { Toast } from "../toast";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import { Walkthrough } from "../walkthroughs";
+import { features } from "./features";
+import { Group } from "./group";
+import { PricingPlans } from "./pricing-plans";
+import { usePricing } from "../../hooks/use-pricing";
export const Component = ({ close, promo, getRef }) => {
- const colors = useThemeStore(state => state.colors);
- const user = useUserStore(state => state.user);
+ const colors = useThemeStore((state) => state.colors);
+ const user = useUserStore((state) => state.user);
const userCanRequestTrial =
user && (!user.subscription || !user.subscription.expiry) ? true : false;
const [floatingButton, setFloatingButton] = useState(false);
- const pricing = usePricing('monthly');
+ const pricing = usePricing("monthly");
const onPress = async () => {
if (user) {
- umami.pageView('/pro-plans', `/pro-screen`);
+ umami.pageView("/pro-plans", `/pro-screen`);
presentSheet({
- context: 'pricing_plans',
- component:
+ context: "pricing_plans",
+ component: (
+
+ )
});
} else {
close();
- umami.pageView('/signup', `/pro-screen`);
+ umami.pageView("/signup", `/pro-screen`);
setTimeout(() => {
eSendEvent(eOpenLoginDialog, AuthMode.trialSignup);
}, 400);
}
};
- const onScroll = event => {
+ const onScroll = (event) => {
let contentSize = event.nativeEvent.contentSize.height;
contentSize = contentSize - event.nativeEvent.layoutMeasurement.height;
let yOffset = event.nativeEvent.contentOffset.y;
@@ -70,11 +72,11 @@ export const Component = ({ close, promo, getRef }) => {
return (
@@ -83,7 +85,7 @@ export const Component = ({ close, promo, getRef }) => {
close();
}}
customStyle={{
- position: 'absolute',
+ position: "absolute",
right: DDS.isTab ? 30 : 15,
top: 30,
zIndex: 10,
@@ -106,24 +108,28 @@ export const Component = ({ close, promo, getRef }) => {
-
+
- Notesnook{' '}
+ Notesnook{" "}
Pro
@@ -140,7 +146,7 @@ export const Component = ({ close, promo, getRef }) => {
) : (
{
size={SIZE.md}
style={{
paddingHorizontal: 12,
- textAlign: 'center',
- alignSelf: 'center',
+ textAlign: "center",
+ alignSelf: "center",
paddingBottom: 20,
- width: '90%'
+ width: "90%"
}}
>
Ready to take the next step on your private note taking journey?
@@ -172,7 +178,7 @@ export const Component = ({ close, promo, getRef }) => {
eSendEvent(eClosePremiumDialog);
eSendEvent(eCloseProgressDialog);
await sleep(300);
- Walkthrough.present('trialstarted', false, true);
+ Walkthrough.present("trialstarted", false, true);
} catch (e) {}
}}
title="Try free for 14 days"
@@ -189,8 +195,10 @@ export const Component = ({ close, promo, getRef }) => {
{
color={colors.icon}
size={SIZE.xs}
style={{
- alignSelf: 'center',
- textAlign: 'center',
+ alignSelf: "center",
+ textAlign: "center",
marginTop: 10,
- maxWidth: '80%'
+ maxWidth: "80%"
}}
>
{user
? `On clicking "Try free for 14 days", your free trial will be activated.`
- : `After sign up you will be asked to activate your free trial.`}{' '}
-
+ : `After sign up you will be asked to activate your free trial.`}{" "}
+
No credit card is required.
@@ -238,11 +246,13 @@ export const Component = ({ close, promo, getRef }) => {
{floatingButton ? (
{
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [visible, setVisible] = useState(false);
const [status, setStatus] = useState({
- title: 'Your trial is ending soon',
+ title: "Your trial is ending soon",
offer: null,
extend: true
});
- const pricing = usePricing('yearly');
+ const pricing = usePricing("yearly");
console.log(pricing?.info?.discount);
const promo = status.offer
@@ -32,8 +40,10 @@ export const Expiring = () => {
promoCode:
pricing?.info?.discount > 30
? pricing.info.sku
- : 'com.streetwriters.notesnook.sub.yr.trialoffer',
- text: `GET ${pricing?.info?.discount > 30 ? pricing?.info?.discount : 30}% OFF on yearly`,
+ : "com.streetwriters.notesnook.sub.yr.trialoffer",
+ text: `GET ${
+ pricing?.info?.discount > 30 ? pricing?.info?.discount : 30
+ }% OFF on yearly`,
discount: pricing?.info?.discount > 30 ? pricing?.info?.discount : 30
}
: null;
@@ -45,7 +55,7 @@ export const Expiring = () => {
};
}, []);
- const open = status => {
+ const open = (status) => {
setStatus(status);
setVisible(true);
};
@@ -60,20 +70,20 @@ export const Expiring = () => {
@@ -82,8 +92,8 @@ export const Expiring = () => {
{status.offer ? (
@@ -95,13 +105,14 @@ export const Expiring = () => {
- Upgrade now to continue using all the pro features after your trial ends
+ Upgrade now to continue using all the pro features after
+ your trial ends
>
)}
@@ -116,7 +127,7 @@ export const Expiring = () => {
}}
size={SIZE.xs + 1}
style={{
- textDecorationLine: 'underline',
+ textDecorationLine: "underline",
color: colors.icon,
marginTop: 10
}}
@@ -131,7 +142,7 @@ export const Expiring = () => {
{
onPress={async () => {
setVisible(false);
await sleep(300);
- PremiumService.sheet(null, promo?.discount > 30 ? null : promo);
+ PremiumService.sheet(
+ null,
+ promo?.discount > 30 ? null : promo
+ );
}}
fontSize={SIZE.md + 2}
style={{
@@ -157,16 +171,16 @@ export const Expiring = () => {
type="gray"
title="Not sure yet? Extend trial for 7 days"
textStyle={{
- textDecorationLine: 'underline'
+ textDecorationLine: "underline"
}}
onPress={async () => {
setVisible(false);
await sleep(300);
eSendEvent(eOpenResultDialog, {
- title: 'Your trial has been extended',
+ title: "Your trial has been extended",
paragraph:
- 'Try out all features of Notesnook free for 7 more days. No limitations. No commitments.',
- button: 'Continue'
+ "Try out all features of Notesnook free for 7 more days. No limitations. No commitments.",
+ button: "Continue"
});
}}
fontSize={SIZE.xs}
diff --git a/apps/mobile/app/components/premium/feature.js b/apps/mobile/app/components/premium/feature.js
index f15ff763a..865daec66 100644
--- a/apps/mobile/app/components/premium/feature.js
+++ b/apps/mobile/app/components/premium/feature.js
@@ -1,19 +1,26 @@
-import React from 'react';
-import { Text, View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { SIZE } from '../../utils/size';
-import Paragraph from '../ui/typography/paragraph';
-import { ProTag } from './pro-tag';
+import React from "react";
+import { Text, View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { SIZE } from "../../utils/size";
+import Paragraph from "../ui/typography/paragraph";
+import { ProTag } from "./pro-tag";
-export const FeatureBlock = ({ vertical, highlight, content, icon, pro, proTagBg }) => {
- const colors = useThemeStore(state => state.colors);
+export const FeatureBlock = ({
+ vertical,
+ highlight,
+ content,
+ icon,
+ pro,
+ proTagBg
+}) => {
+ const colors = useThemeStore((state) => state.colors);
return vertical ? (
{highlight}
- {'\n'}
+ {"\n"}
{content}
diff --git a/apps/mobile/app/components/premium/features.js b/apps/mobile/app/components/premium/features.js
index c44953298..ac91a6b45 100644
--- a/apps/mobile/app/components/premium/features.js
+++ b/apps/mobile/app/components/premium/features.js
@@ -1,224 +1,227 @@
export const features = [
{
- title: 'Focused on privacy',
+ title: "Focused on privacy",
detail:
- 'Everything you do in Notesnook stays private. We use XChaCha20-Poly1305-IETF and Argon2 to encrypt your notes.',
+ "Everything you do in Notesnook stays private. We use XChaCha20-Poly1305-IETF and Argon2 to encrypt your notes.",
features: [
{
- highlight: 'Zero ads',
- content: '& zero trackers',
- icon: 'billboard'
+ highlight: "Zero ads",
+ content: "& zero trackers",
+ icon: "billboard"
},
{
- highlight: 'On device',
- content: 'encryption',
- icon: 'cellphone'
+ highlight: "On device",
+ content: "encryption",
+ icon: "cellphone"
},
{
- highlight: 'Secure app',
- content: 'lock for all',
- icon: 'cellphone-lock'
+ highlight: "Secure app",
+ content: "lock for all",
+ icon: "cellphone-lock"
},
{
- highlight: '100% end-to-end ',
- content: 'encrypted',
- icon: 'lock'
+ highlight: "100% end-to-end ",
+ content: "encrypted",
+ icon: "lock"
},
{
- highlight: 'Password protected',
- content: 'notes sharing',
- icon: 'file-lock'
+ highlight: "Password protected",
+ content: "notes sharing",
+ icon: "file-lock"
}
]
},
{
- title: 'No limit on notes or devices',
+ title: "No limit on notes or devices",
detail:
"Basic or Pro, you can create unlimited number of notes and access them on all your devices. You won't be running out of space or blocks ever."
},
{
- title: 'Attach files & images',
- detail: 'Add your documents, PDFs, images and videos, and keep them safe and organized.',
+ title: "Attach files & images",
+ detail:
+ "Add your documents, PDFs, images and videos, and keep them safe and organized.",
pro: true,
features: [
{
- highlight: 'Bullet proof',
- content: 'encryption',
- icon: 'lock'
+ highlight: "Bullet proof",
+ content: "encryption",
+ icon: "lock"
},
{
- highlight: 'High quality',
- content: '4k images',
- icon: 'image-multiple'
+ highlight: "High quality",
+ content: "4k images",
+ icon: "image-multiple"
},
{
- highlight: 'No monthly',
- content: 'storage limit',
- icon: 'harddisk'
+ highlight: "No monthly",
+ content: "storage limit",
+ icon: "harddisk"
},
{
- highlight: 'Generous 500 MB',
- content: 'max file size',
- icon: 'file-cabinet'
+ highlight: "Generous 500 MB",
+ content: "max file size",
+ icon: "file-cabinet"
},
{
- highlight: 'No restriction',
- content: 'on file type',
- icon: 'file'
+ highlight: "No restriction",
+ content: "on file type",
+ icon: "file"
}
]
},
{
- title: 'Keep secrets always locked with private vault',
+ title: "Keep secrets always locked with private vault",
detail:
- 'An extra layer of security for any important data. Notes in the vault always stay encrypted and require a password to be accessed or edited everytime.',
+ "An extra layer of security for any important data. Notes in the vault always stay encrypted and require a password to be accessed or edited everytime.",
pro: true
},
{
- title: 'Organize yourself in the best way',
- detail: 'We offer multiple ways to keep you organized. The only limit is your imagination.',
+ title: "Organize yourself in the best way",
+ detail:
+ "We offer multiple ways to keep you organized. The only limit is your imagination.",
features: [
{
- highlight: 'Unlimited',
- content: 'notebooks & tags*',
- icon: 'emoticon',
+ highlight: "Unlimited",
+ content: "notebooks & tags*",
+ icon: "emoticon",
pro: true
},
{
- highlight: 'Organize',
- content: 'with colors',
- icon: 'palette',
+ highlight: "Organize",
+ content: "with colors",
+ icon: "palette",
pro: true
},
{
- highlight: 'Side menu',
- content: 'shortcuts',
- icon: 'link-variant'
+ highlight: "Side menu",
+ content: "shortcuts",
+ icon: "link-variant"
},
{
- highlight: 'Pin note in',
- content: 'notifications',
- icon: 'pin',
- platform: 'android'
+ highlight: "Pin note in",
+ content: "notifications",
+ icon: "pin",
+ platform: "android"
}
],
- info: '* Free users are limited to keeping 3 notebooks (no limit on topics) and 5 tags.'
+ info: "* Free users are limited to keeping 3 notebooks (no limit on topics) and 5 tags."
},
{
- title: 'Instant syncing',
+ title: "Instant syncing",
detail:
- 'Seemlessly work from anywhere on any device. Every change is synced instantly to all your devices.',
+ "Seemlessly work from anywhere on any device. Every change is synced instantly to all your devices.",
pro: true
},
{
- title: 'Rich tools for rich editing',
+ title: "Rich tools for rich editing",
detail:
- 'Having the right tool at the right time is crucial for note taking. Lists, tables, codeblocks — you name it, we have it.',
+ "Having the right tool at the right time is crucial for note taking. Lists, tables, codeblocks — you name it, we have it.",
features: [
{
- highlight: 'Basic formating',
- content: 'and lists',
- icon: 'format-bold'
+ highlight: "Basic formating",
+ content: "and lists",
+ icon: "format-bold"
},
{
- highlight: 'Checklists',
- content: '& tables',
- icon: 'table',
+ highlight: "Checklists",
+ content: "& tables",
+ icon: "table",
pro: true
},
{
- highlight: 'Markdown',
- content: 'support',
- icon: 'language-markdown',
+ highlight: "Markdown",
+ content: "support",
+ icon: "language-markdown",
pro: true
},
{
- highlight: 'Write notes from',
- content: 'notifications',
- icon: 'bell',
- platform: 'android'
+ highlight: "Write notes from",
+ content: "notifications",
+ icon: "bell",
+ platform: "android"
}
]
},
{
- title: 'Safe publishing to the Internet',
+ title: "Safe publishing to the Internet",
detail:
- 'Publishing is nothing new but we offer fully encrypted, anonymous publishing. Take any note & share it with the world.',
+ "Publishing is nothing new but we offer fully encrypted, anonymous publishing. Take any note & share it with the world.",
features: [
{
- highlight: 'Password protected',
- content: 'sharing',
- icon: 'send-lock'
+ highlight: "Password protected",
+ content: "sharing",
+ icon: "send-lock"
},
{
- highlight: 'Self destruct',
- content: 'monographs',
- icon: 'bomb'
+ highlight: "Self destruct",
+ content: "monographs",
+ icon: "bomb"
}
]
},
{
- title: 'Export and take your notes anywhere',
+ title: "Export and take your notes anywhere",
pro: true,
detail:
- 'You own your notes, not us. No proprietary formats. No vendor lock in. No waiting for hours to download your notes.',
- info: '* Free users can export notes in well formatted plain text.',
+ "You own your notes, not us. No proprietary formats. No vendor lock in. No waiting for hours to download your notes.",
+ info: "* Free users can export notes in well formatted plain text.",
features: [
{
- highlight: 'Export as ',
- content: 'Markdown',
- icon: 'language-markdown',
+ highlight: "Export as ",
+ content: "Markdown",
+ icon: "language-markdown",
pro: true
},
{
- highlight: 'Export as',
- content: 'PDF',
- icon: 'file-pdf-box',
+ highlight: "Export as",
+ content: "PDF",
+ icon: "file-pdf-box",
pro: true
},
{
- highlight: 'Export as',
- content: 'HTML',
- icon: 'language-html5',
+ highlight: "Export as",
+ content: "HTML",
+ icon: "language-html5",
pro: true
},
{
- highlight: 'Export as',
- content: 'text',
- icon: 'clipboard-text-outline'
+ highlight: "Export as",
+ content: "text",
+ icon: "clipboard-text-outline"
}
]
},
{
- title: 'Backup & keep your notes safe',
+ title: "Backup & keep your notes safe",
detail:
- 'Do not worry about losing your data. Turn on automatic backups on weekly or daily basis.',
+ "Do not worry about losing your data. Turn on automatic backups on weekly or daily basis.",
features: [
{
- highlight: 'Backup',
- content: 'encryption',
- icon: 'backup-restore'
+ highlight: "Backup",
+ content: "encryption",
+ icon: "backup-restore"
}
],
pro: true
},
{
- title: 'Personalize & make Notesnook your own',
- detail: 'Change app themes to match your style. Custom themes are coming soon.',
+ title: "Personalize & make Notesnook your own",
+ detail:
+ "Change app themes to match your style. Custom themes are coming soon.",
features: [
{
- highlight: 'Automatic',
- content: 'dark mode',
- icon: 'theme-light-dark',
+ highlight: "Automatic",
+ content: "dark mode",
+ icon: "theme-light-dark",
pro: false
},
{
- highlight: 'Change accent',
- content: 'color',
- icon: 'invert-colors',
+ highlight: "Change accent",
+ content: "color",
+ icon: "invert-colors",
pro: true
}
]
diff --git a/apps/mobile/app/components/premium/group.js b/apps/mobile/app/components/premium/group.js
index 0b607840f..136a9ec5d 100644
--- a/apps/mobile/app/components/premium/group.js
+++ b/apps/mobile/app/components/premium/group.js
@@ -1,14 +1,14 @@
-import React from 'react';
-import { ScrollView, View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { SIZE } from '../../utils/size';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import { FeatureBlock } from './feature';
-import { ProTag } from './pro-tag';
+import React from "react";
+import { ScrollView, View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { SIZE } from "../../utils/size";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import { FeatureBlock } from "./feature";
+import { ProTag } from "./pro-tag";
export const Group = ({ item, index }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
{
}}
>
{item?.pro ? (
-
+
) : null}
{item.title}
{item.detail}
@@ -32,7 +35,7 @@ export const Group = ({ item, index }) => {
horizontal
showsHorizontalScrollIndicator={false}
>
- {item.features?.map(item => (
+ {item.features?.map((item) => (
{
+ open = (promoInfo) => {
this.setState({
visible: true,
promo: promoInfo
@@ -52,7 +55,11 @@ class PremiumDialog extends React.Component {
background={this.props.colors.bg}
onRequestClose={this.onClose}
>
- this.actionSheetRef} promo={this.state.promo} close={this.close} />
+ this.actionSheetRef}
+ promo={this.state.promo}
+ close={this.close}
+ />
);
}
diff --git a/apps/mobile/app/components/premium/offer.js b/apps/mobile/app/components/premium/offer.js
index 3f2bd9765..8fd104ebb 100644
--- a/apps/mobile/app/components/premium/offer.js
+++ b/apps/mobile/app/components/premium/offer.js
@@ -1,22 +1,26 @@
-import React from 'react';
-import { Text } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { SIZE } from '../../utils/size';
-import Paragraph from '../ui/typography/paragraph';
+import React from "react";
+import { Text } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { SIZE } from "../../utils/size";
+import Paragraph from "../ui/typography/paragraph";
-export const Offer = ({ off = '30', text = 'on yearly plan, offer ends soon', padding = 0 }) => {
- const colors = useThemeStore(state => state.colors);
+export const Offer = ({
+ off = "30",
+ text = "on yearly plan, offer ends soon",
+ padding = 0
+}) => {
+ const colors = useThemeStore((state) => state.colors);
return (
GET {off}
- % OFF!{'\n'}
+ % OFF!{"\n"}
{text}
);
diff --git a/apps/mobile/app/components/premium/premium-toast.js b/apps/mobile/app/components/premium/premium-toast.js
index 04fbd81cb..1e03e8a4e 100644
--- a/apps/mobile/app/components/premium/premium-toast.js
+++ b/apps/mobile/app/components/premium/premium-toast.js
@@ -1,24 +1,32 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { View } from 'react-native';
-import Animated, { FadeInUp, FadeOutUp } from 'react-native-reanimated';
-import { editorState } from '../../screens/editor/tiptap/utils';
-import { DDS } from '../../services/device-detection';
-import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { getElevation } from '../../utils';
-import { eCloseActionSheet, eOpenPremiumDialog, eShowGetPremium } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import { Button } from '../ui/button';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
+import React, { useEffect, useRef, useState } from "react";
+import { View } from "react-native";
+import Animated, { FadeInUp, FadeOutUp } from "react-native-reanimated";
+import { editorState } from "../../screens/editor/tiptap/utils";
+import { DDS } from "../../services/device-detection";
+import {
+ eSendEvent,
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { getElevation } from "../../utils";
+import {
+ eCloseActionSheet,
+ eOpenPremiumDialog,
+ eShowGetPremium
+} from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import { Button } from "../ui/button";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
-export const PremiumToast = ({ close, context = 'global', offset = 0 }) => {
- const colors = useThemeStore(state => state.colors);
+export const PremiumToast = ({ close, context = "global", offset = 0 }) => {
+ const colors = useThemeStore((state) => state.colors);
const [msg, setMsg] = useState(null);
const timer = useRef();
- const open = event => {
+ const open = (event) => {
if (!event) {
clearTimeout(timer);
timer.current = null;
@@ -62,17 +70,17 @@ export const PremiumToast = ({ close, context = 'global', offset = 0 }) => {
entering={FadeInUp}
exiting={FadeOutUp}
style={{
- position: 'absolute',
+ position: "absolute",
backgroundColor: colors.nav,
zIndex: 999,
...getElevation(20),
padding: 12,
borderRadius: 10,
- flexDirection: 'row',
- alignSelf: 'center',
- justifyContent: 'space-between',
+ flexDirection: "row",
+ alignSelf: "center",
+ justifyContent: "space-between",
top: offset,
- maxWidth: DDS.isLargeTablet() ? 400 : '98%'
+ maxWidth: DDS.isLargeTablet() ? 400 : "98%"
}}
>
{
>
{
{
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
{!compact && (
- {product?.type === 'yearly' || product?.offerType === 'yearly' ? 'Yearly' : 'Monthly'}
+ {product?.type === "yearly" || product?.offerType === "yearly"
+ ? "Yearly"
+ : "Monthly"}
- {product?.info && {product.info}}
+ {product?.info && (
+ {product.info}
+ )}
)}
{product?.data?.localizedPrice}/
- {product?.type === 'yearly' || product?.offerType === 'yearly' ? '/year' : '/month'}
+ {product?.type === "yearly" || product?.offerType === "yearly"
+ ? "/year"
+ : "/month"}
diff --git a/apps/mobile/app/components/premium/pricing-plans.js b/apps/mobile/app/components/premium/pricing-plans.js
index 1266b28ca..716dee99e 100644
--- a/apps/mobile/app/components/premium/pricing-plans.js
+++ b/apps/mobile/app/components/premium/pricing-plans.js
@@ -1,54 +1,63 @@
-import React, { useEffect, useState } from 'react';
-import { ActivityIndicator, Platform, Text, View } from 'react-native';
-import * as RNIap from 'react-native-iap';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useUserStore } from '../../stores/use-user-store';
-import { eSendEvent, presentSheet, ToastEvent } from '../../services/event-manager';
-import PremiumService from '../../services/premium';
-import { db } from '../../common/database';
+import React, { useEffect, useState } from "react";
+import { ActivityIndicator, Platform, Text, View } from "react-native";
+import * as RNIap from "react-native-iap";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useUserStore } from "../../stores/use-user-store";
+import {
+ eSendEvent,
+ presentSheet,
+ ToastEvent
+} from "../../services/event-manager";
+import PremiumService from "../../services/premium";
+import { db } from "../../common/database";
import {
eClosePremiumDialog,
eCloseProgressDialog,
eCloseSimpleDialog,
eOpenLoginDialog
-} from '../../utils/events';
-import { openLinkInBrowser } from '../../utils/functions';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import umami from '../../common/analytics';
-import { Button } from '../ui/button';
-import { Dialog } from '../dialog';
-import BaseDialog from '../dialog/base-dialog';
-import { presentDialog } from '../dialog/functions';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import { Walkthrough } from '../walkthroughs';
-import { PricingItem } from './pricing-item';
-import { usePricing } from '../../hooks/use-pricing';
+} from "../../utils/events";
+import { openLinkInBrowser } from "../../utils/functions";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import umami from "../../common/analytics";
+import { Button } from "../ui/button";
+import { Dialog } from "../dialog";
+import BaseDialog from "../dialog/base-dialog";
+import { presentDialog } from "../dialog/functions";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import { Walkthrough } from "../walkthroughs";
+import { PricingItem } from "./pricing-item";
+import { usePricing } from "../../hooks/use-pricing";
const promoCyclesMonthly = {
- 1: 'first month',
- 2: 'first 2 months',
- 3: 'first 3 months'
+ 1: "first month",
+ 2: "first 2 months",
+ 3: "first 3 months"
};
const promoCyclesYearly = {
- 1: 'first year',
- 2: 'first 2 years',
- 3: 'first 3 years'
+ 1: "first year",
+ 2: "first 2 years",
+ 3: "first 3 years"
};
-export const PricingPlans = ({ promo, marginTop, heading = true, compact = false }) => {
- const colors = useThemeStore(state => state.colors);
- const user = useUserStore(state => state.user);
+export const PricingPlans = ({
+ promo,
+ marginTop,
+ heading = true,
+ compact = false
+}) => {
+ const colors = useThemeStore((state) => state.colors);
+ const user = useUserStore((state) => state.user);
const [product, setProduct] = useState(null);
const [buying, setBuying] = useState(false);
const [loading, setLoading] = useState(false);
const userCanRequestTrial =
user && (!user.subscription || !user.subscription.expiry) ? true : false;
const [upgrade, setUpgrade] = useState(!userCanRequestTrial);
- const yearlyPlan = usePricing('yearly');
- const monthlyPlan = usePricing('monthly');
+ const yearlyPlan = usePricing("yearly");
+ const monthlyPlan = usePricing("monthly");
const getSkus = async () => {
try {
@@ -59,41 +68,43 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
setLoading(false);
} catch (e) {
setLoading(false);
- console.log('error getting sku', e);
+ console.log("error getting sku", e);
}
};
- const getPromo = async code => {
+ const getPromo = async (code) => {
try {
let productId;
- if (code.startsWith('com.streetwriters.notesnook')) {
+ if (code.startsWith("com.streetwriters.notesnook")) {
productId = code;
} else {
- productId = await db.offers.getCode(code.split(':')[0], Platform.OS);
+ productId = await db.offers.getCode(code.split(":")[0], Platform.OS);
}
let products = await PremiumService.getProducts();
- let product = products.find(p => p.productId === productId);
+ let product = products.find((p) => p.productId === productId);
if (!product) return false;
- let isMonthly = product.productId.indexOf('.mo') > -1;
+ let isMonthly = product.productId.indexOf(".mo") > -1;
let cycleText = isMonthly
? promoCyclesMonthly[
- product.introductoryPriceCyclesAndroid || product.introductoryPriceNumberOfPeriodsIOS
+ product.introductoryPriceCyclesAndroid ||
+ product.introductoryPriceNumberOfPeriodsIOS
]
: promoCyclesYearly[
- product.introductoryPriceCyclesAndroid || product.introductoryPriceNumberOfPeriodsIOS
+ product.introductoryPriceCyclesAndroid ||
+ product.introductoryPriceNumberOfPeriodsIOS
];
setProduct({
- type: 'promo',
- offerType: isMonthly ? 'monthly' : 'yearly',
+ type: "promo",
+ offerType: isMonthly ? "monthly" : "yearly",
data: product,
cycleText: cycleText,
- info: 'Pay monthly, cancel anytime'
+ info: "Pay monthly, cancel anytime"
});
return true;
} catch (e) {
- console.log('PROMOCODE ERROR:', code, e);
+ console.log("PROMOCODE ERROR:", code, e);
return false;
}
};
@@ -102,7 +113,7 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
getSkus();
}, []);
- const buySubscription = async product => {
+ const buySubscription = async (product) => {
if (buying) return;
setBuying(true);
try {
@@ -110,20 +121,30 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
setBuying(false);
return;
}
- umami.pageView('/iap-native', `${compact ? 'pro-sheet' : 'pro-screen'}/pro-plans`);
- await RNIap.requestSubscription(product?.productId, false, null, null, null, user.id);
+ umami.pageView(
+ "/iap-native",
+ `${compact ? "pro-sheet" : "pro-screen"}/pro-plans`
+ );
+ await RNIap.requestSubscription(
+ product?.productId,
+ false,
+ null,
+ null,
+ null,
+ user.id
+ );
setBuying(false);
eSendEvent(eCloseProgressDialog);
eSendEvent(eClosePremiumDialog);
await sleep(500);
presentSheet({
- title: 'Thank you for subscribing!',
+ title: "Thank you for subscribing!",
paragraph: `Your Notesnook Pro subscription will be activated soon. If your account is not upgraded to Notesnook Pro, your money will be refunded to you. In case of any issues, please reach out to us at support@streetwriters.co`,
action: async () => {
eSendEvent(eCloseProgressDialog);
},
- icon: 'check',
- actionText: 'Continue'
+ icon: "check",
+ actionText: "Continue"
});
} catch (e) {
setBuying(false);
@@ -135,8 +156,8 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
@@ -158,7 +179,7 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
<>
@@ -186,7 +207,7 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
eSendEvent(eClosePremiumDialog);
eSendEvent(eCloseProgressDialog);
await sleep(300);
- Walkthrough.present('trialstarted', false, true);
+ Walkthrough.present("trialstarted", false, true);
} catch (e) {}
}}
title={`Try free for 14 days`}
@@ -201,25 +222,25 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
>
) : (
<>
- {product?.type === 'promo' ? (
+ {product?.type === "promo" ? (
{product.data.introductoryPrice}
({product.data.localizedPrice})
- {' '}
+ {" "}
for {product.cycleText}
) : null}
@@ -231,19 +252,20 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
{monthlyPlan && monthlyPlan?.info?.discount > 0 ? (
- Get {monthlyPlan?.info?.discount}% off in {monthlyPlan?.info?.country}
+ Get {monthlyPlan?.info?.discount}% off in{" "}
+ {monthlyPlan?.info?.country}
) : (
buySubscription(monthlyPlan?.product)}
compact={compact}
product={{
- type: 'monthly',
+ type: "monthly",
data: monthlyPlan?.product,
- info: 'Pay monthly, cancel anytime.'
+ info: "Pay monthly, cancel anytime."
}}
/>
@@ -284,14 +306,14 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
onPress={() => buySubscription(yearlyPlan?.product)}
compact={compact}
product={{
- type: 'yearly',
+ type: "yearly",
data: yearlyPlan?.product,
- info: 'Pay yearly'
+ info: "Pay yearly"
}}
/>
- {Platform.OS !== 'ios' ? (
+ {Platform.OS !== "ios" ? (
{
presentDialog({
- context: 'local',
+ context: "local",
input: true,
- inputPlaceholder: 'Enter code',
- positiveText: 'Apply',
- positivePress: async value => {
+ inputPlaceholder: "Enter code",
+ positiveText: "Apply",
+ positivePress: async (value) => {
if (!value) return;
console.log(value);
eSendEvent(eCloseSimpleDialog);
setBuying(true);
try {
if (!(await getPromo(value)))
- throw new Error('Error applying promo code');
+ throw new Error("Error applying promo code");
ToastEvent.show({
- heading: 'Discount applied!',
- type: 'success',
- context: 'local'
+ heading: "Discount applied!",
+ type: "success",
+ context: "local"
});
setBuying(false);
} catch (e) {
setBuying(false);
ToastEvent.show({
- heading: 'Promo code invalid or expired',
+ heading: "Promo code invalid or expired",
message: e.message,
- type: 'error',
- context: 'local'
+ type: "error",
+ context: "local"
});
}
},
- title: 'Have a promo code?',
- paragraph: 'Enter your promo code to get a special discount.'
+ title: "Have a promo code?",
+ paragraph:
+ "Enter your promo code to get a special discount."
});
}}
title="I have a promo code"
@@ -363,26 +386,26 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
borderRadius: 100
}}
/>
- {Platform.OS !== 'ios' &&
+ {Platform.OS !== "ios" &&
promo &&
- !promo.promoCode.startsWith('com.streetwriters.notesnook') ? (
+ !promo.promoCode.startsWith("com.streetwriters.notesnook") ? (
- Use promo code{' '}
+ Use promo code{" "}
{promo.promoCode}
- {' '}
+ {" "}
at checkout
) : null}
@@ -421,16 +444,16 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
color={colors.icon}
size={SIZE.xs}
style={{
- alignSelf: 'center',
- textAlign: 'center',
+ alignSelf: "center",
+ textAlign: "center",
marginTop: 10,
- maxWidth: '80%'
+ maxWidth: "80%"
}}
>
{user
? `On clicking "Try free for 14 days", your free trial will be activated.`
- : `After sign up you will be asked to activate your free trial.`}{' '}
-
+ : `After sign up you will be asked to activate your free trial.`}{" "}
+
No credit card is required.
@@ -438,78 +461,79 @@ export const PricingPlans = ({ promo, marginTop, heading = true, compact = false
{user && upgrade ? (
<>
- {Platform.OS === 'ios' ? (
+ {Platform.OS === "ios" ? (
- By subscribing, you will be charged to your iTunes Account for the selected plan.
- Subscriptions will automatically renew unless cancelled within 24-hours before the end
- of the current period.
+ By subscribing, you will be charged to your iTunes Account for the
+ selected plan. Subscriptions will automatically renew unless
+ cancelled within 24-hours before the end of the current period.
) : (
- By subscribing, your will be charged on your Google Account, and your subscription
- will automatically renew until you cancel prior to the end of the then current period.
+ By subscribing, your will be charged on your Google Account, and
+ your subscription will automatically renew until you cancel prior
+ to the end of the then current period.
)}
- By subscribing, you agree to our{' '}
+ By subscribing, you agree to our{" "}
{
- openLinkInBrowser('https://notesnook.com/tos', colors)
- .catch(e => {})
- .then(r => {
- console.log('closed');
+ openLinkInBrowser("https://notesnook.com/tos", colors)
+ .catch((e) => {})
+ .then((r) => {
+ console.log("closed");
});
}}
style={{
- textDecorationLine: 'underline'
+ textDecorationLine: "underline"
}}
color={colors.accent}
>
- Terms of Service{' '}
+ Terms of Service{" "}
- and{' '}
+ and{" "}
{
- openLinkInBrowser('https://notesnook.com/privacy', colors)
- .catch(e => {})
- .then(r => {
- console.log('closed');
+ openLinkInBrowser("https://notesnook.com/privacy", colors)
+ .catch((e) => {})
+ .then((r) => {
+ console.log("closed");
});
}}
style={{
- textDecorationLine: 'underline'
+ textDecorationLine: "underline"
}}
color={colors.accent}
>
diff --git a/apps/mobile/app/components/premium/pro-tag.js b/apps/mobile/app/components/premium/pro-tag.js
index e375990fc..d38208d03 100644
--- a/apps/mobile/app/components/premium/pro-tag.js
+++ b/apps/mobile/app/components/premium/pro-tag.js
@@ -1,11 +1,11 @@
-import React from 'react';
-import { View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { useThemeStore } from '../../stores/use-theme-store';
-import Paragraph from '../ui/typography/paragraph';
+import React from "react";
+import { View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { useThemeStore } from "../../stores/use-theme-store";
+import Paragraph from "../ui/typography/paragraph";
export const ProTag = ({ width, size, background }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
{
backgroundColor: background || colors.bg,
borderRadius: 100,
width: width || 60,
- justifyContent: 'center',
- alignItems: 'center',
+ justifyContent: "center",
+ alignItems: "center",
paddingVertical: 2.5,
- flexDirection: 'row'
+ flexDirection: "row"
}}
>
{
const [note, setNote] = useState(item);
- const setColorNotes = useMenuStore(state => state.setColorNotes);
- const dimensions = useSettingStore(state => state.dimensions);
+ const setColorNotes = useMenuStore((state) => state.setColorNotes);
+ const dimensions = useSettingStore((state) => state.dimensions);
let width = dimensions.width > 600 ? 600 : 500;
- const changeColor = async color => {
+ const changeColor = async (color) => {
if (note.color === color.name) {
await db.notes.note(note.id).uncolor();
} else {
@@ -30,16 +30,16 @@ export const ColorTags = ({ item, close }) => {
setNote({ ..._note });
setColorNotes();
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes"
);
eSendEvent(refreshNotesPage);
};
- const _renderColor = c => {
+ const _renderColor = (c) => {
const color = {
name: c,
value: COLORS_NOTE[c?.toLowerCase()]
@@ -56,8 +56,8 @@ export const ColorTags = ({ item, close }) => {
width: DDS.isTab ? width / 10 : dWidth / 9,
height: DDS.isTab ? width / 10 : dWidth / 9,
borderRadius: 100,
- justifyContent: 'center',
- alignItems: 'center'
+ justifyContent: "center",
+ alignItems: "center"
}}
>
{note.color?.toLowerCase() === color.name ? (
@@ -70,14 +70,14 @@ export const ColorTags = ({ item, close }) => {
return (
{Object.keys(COLORS_NOTE).map(_renderColor)}
diff --git a/apps/mobile/app/components/properties/date-meta.js b/apps/mobile/app/components/properties/date-meta.js
index 2ec2e7707..949c9b618 100644
--- a/apps/mobile/app/components/properties/date-meta.js
+++ b/apps/mobile/app/components/properties/date-meta.js
@@ -1,37 +1,37 @@
-import React from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { SIZE } from '../../utils/size';
-import { timeConverter } from '../../utils/time';
-import Paragraph from '../ui/typography/paragraph';
+import React from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { SIZE } from "../../utils/size";
+import { timeConverter } from "../../utils/time";
+import Paragraph from "../ui/typography/paragraph";
export const DateMeta = ({ item }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
- const getNameFromKey = key => {
+ const getNameFromKey = (key) => {
switch (key) {
- case 'dateCreated':
- return 'Created at:';
- case 'dateEdited':
- return 'Last edited at:';
- case 'dateModified':
- return 'Last modified at:';
- case 'dateDeleted':
- return 'Deleted at:';
- case 'dateUploaded':
- return 'Uploaded at:';
+ case "dateCreated":
+ return "Created at:";
+ case "dateEdited":
+ return "Last edited at:";
+ case "dateModified":
+ return "Last modified at:";
+ case "dateDeleted":
+ return "Deleted at:";
+ case "dateUploaded":
+ return "Uploaded at:";
default:
return key;
}
};
- const renderItem = key =>
- key.startsWith('date') ? (
+ const renderItem = (key) =>
+ key.startsWith("date") ? (
diff --git a/apps/mobile/app/components/properties/dev-mode.js b/apps/mobile/app/components/properties/dev-mode.js
index cf9cd96e7..a45d2f962 100644
--- a/apps/mobile/app/components/properties/dev-mode.js
+++ b/apps/mobile/app/components/properties/dev-mode.js
@@ -1,19 +1,19 @@
-import Clipboard from '@react-native-clipboard/clipboard';
-import React from 'react';
-import { View } from 'react-native';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { ToastEvent } from '../../services/event-manager';
-import { db } from '../../common/database';
-import { SIZE } from '../../utils/size';
-import { Button } from '../ui/button';
+import Clipboard from "@react-native-clipboard/clipboard";
+import React from "react";
+import { View } from "react-native";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { ToastEvent } from "../../services/event-manager";
+import { db } from "../../common/database";
+import { SIZE } from "../../utils/size";
+import { Button } from "../ui/button";
export const DevMode = ({ item }) => {
- const devMode = useSettingStore(state => state.settings.devMode);
+ const devMode = useSettingStore((state) => state.settings.devMode);
return devMode ? (
{
{
let additionalData = {};
- if (item.type === 'note') {
+ if (item.type === "note") {
let content = await db.content.raw(item.contentId);
if (content) {
content = db.debug.strip(content);
@@ -34,9 +34,9 @@ export const DevMode = ({ item }) => {
Clipboard.setString(db.debug.strip(_note));
ToastEvent.show({
- heading: 'Debug data copied!',
- type: 'success',
- context: 'local'
+ heading: "Debug data copied!",
+ type: "success",
+ context: "local"
});
}}
fontSize={SIZE.sm}
@@ -45,7 +45,7 @@ export const DevMode = ({ item }) => {
height={30}
type="warn"
style={{
- alignSelf: 'flex-end'
+ alignSelf: "flex-end"
}}
/>
diff --git a/apps/mobile/app/components/properties/index.js b/apps/mobile/app/components/properties/index.js
index b4990fdaf..a374977ea 100644
--- a/apps/mobile/app/components/properties/index.js
+++ b/apps/mobile/app/components/properties/index.js
@@ -1,26 +1,31 @@
-import React from 'react';
-import { Platform, View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { DDS } from '../../services/device-detection';
-import { presentSheet } from '../../services/event-manager';
-import { db } from '../../common/database';
-import { SIZE } from '../../utils/size';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import { ColorTags } from './color-tags';
-import { DateMeta } from './date-meta';
-import { DevMode } from './dev-mode';
-import { Items } from './items';
-import Notebooks from './notebooks';
-import { Synced } from './synced';
-import { Tags } from './tags';
-import { Topics } from './topics';
-import SearchService from '../../services/search';
-import { COLORS_NOTE } from '../../utils/color-scheme';
-import { ScrollView } from 'react-native-gesture-handler';
+import React from "react";
+import { Platform, View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { DDS } from "../../services/device-detection";
+import { presentSheet } from "../../services/event-manager";
+import { db } from "../../common/database";
+import { SIZE } from "../../utils/size";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import { ColorTags } from "./color-tags";
+import { DateMeta } from "./date-meta";
+import { DevMode } from "./dev-mode";
+import { Items } from "./items";
+import Notebooks from "./notebooks";
+import { Synced } from "./synced";
+import { Tags } from "./tags";
+import { Topics } from "./topics";
+import SearchService from "../../services/search";
+import { COLORS_NOTE } from "../../utils/color-scheme";
+import { ScrollView } from "react-native-gesture-handler";
-export const Properties = ({ close = () => {}, item, buttons = [], getRef }) => {
- const colors = useThemeStore(state => state.colors);
+export const Properties = ({
+ close = () => {},
+ item,
+ buttons = [],
+ getRef
+}) => {
+ const colors = useThemeStore((state) => state.colors);
const alias = item.alias || item.title;
const isColor = !!COLORS_NOTE[item.title];
@@ -39,11 +44,11 @@ export const Properties = ({ close = () => {}, item, buttons = [], getRef }) =>
paddingHorizontal: 0,
borderBottomRightRadius: DDS.isLargeTablet() ? 10 : 1,
borderBottomLeftRadius: DDS.isLargeTablet() ? 10 : 1,
- maxHeight: '95%'
+ maxHeight: "95%"
}}
>
{!item || !item.id ? (
-
+
Start writing to save your note.
) : (
@@ -59,7 +64,7 @@ export const Properties = ({ close = () => {}, item, buttons = [], getRef }) =>
}}
>
- {item.type === 'tag' && !isColor ? (
+ {item.type === "tag" && !isColor ? (
#
@@ -75,21 +80,25 @@ export const Properties = ({ close = () => {}, item, buttons = [], getRef }) =>
numberOfLines={2}
color={colors.icon}
>
- {(item.type === 'notebook' || item.itemType === 'notebook') && item?.description
+ {(item.type === "notebook" || item.itemType === "notebook") &&
+ item?.description
? item.description
: null}
- {(item.type === 'note' || item.itemType === 'note') && item?.headline
+ {(item.type === "note" || item.itemType === "note") &&
+ item?.headline
? item.headline
: null}
) : null}
- {item.type === 'note' ? : null}
+ {item.type === "note" ? : null}
- {item.type === 'note' ? : null}
+ {item.type === "note" ? (
+
+ ) : null}
@@ -102,7 +111,7 @@ export const Properties = ({ close = () => {}, item, buttons = [], getRef }) =>
}}
/>
- {item.type === 'note' ? : null}
+ {item.type === "note" ? : null}
{
let props = [];
let android = [];
switch (type) {
- case 'trash':
+ case "trash":
props[0] = item;
- props.push(['PermDelete', 'Restore']);
+ props.push(["PermDelete", "Restore"]);
break;
- case 'note':
- android = Platform.OS === 'android' ? ['PinToNotif'] : [];
+ case "note":
+ android = Platform.OS === "android" ? ["PinToNotif"] : [];
props[0] = db.notes.note(item.id).data;
props.push([
- 'Add to notebook',
- 'Share',
- 'Export',
- 'Copy',
- 'Publish',
- 'Pin',
- 'Favorite',
- 'Attachments',
- 'Vault',
- 'Delete',
- 'RemoveTopic',
- 'History',
- 'ReadOnly',
- 'Local only',
- 'Duplicate',
+ "Add to notebook",
+ "Share",
+ "Export",
+ "Copy",
+ "Publish",
+ "Pin",
+ "Favorite",
+ "Attachments",
+ "Vault",
+ "Delete",
+ "RemoveTopic",
+ "History",
+ "ReadOnly",
+ "Local only",
+ "Duplicate",
...android,
...buttons
]);
break;
- case 'notebook':
+ case "notebook":
props[0] = db.notebooks.notebook(item.id).data;
- props.push(['Edit Notebook', 'Pin', 'Add Shortcut', 'Delete']);
+ props.push(["Edit Notebook", "Pin", "Add Shortcut", "Delete"]);
break;
- case 'topic':
- props[0] = db.notebooks.notebook(item.notebookId).topics.topic(item.id)._topic;
- props.push(['Move notes', 'Edit Topic', 'Add Shortcut', 'Delete']);
+ case "topic":
+ props[0] = db.notebooks
+ .notebook(item.notebookId)
+ .topics.topic(item.id)._topic;
+ props.push(["Move notes", "Edit Topic", "Add Shortcut", "Delete"]);
break;
- case 'tag':
+ case "tag":
props[0] = db.tags.tag(item.id);
- props.push(['Add Shortcut', 'Delete', 'Rename Tag']);
+ props.push(["Add Shortcut", "Delete", "Rename Tag"]);
break;
}
if (!props[0]) return;
diff --git a/apps/mobile/app/components/properties/items.js b/apps/mobile/app/components/properties/items.js
index 18a54fb03..08feb9f4b 100644
--- a/apps/mobile/app/components/properties/items.js
+++ b/apps/mobile/app/components/properties/items.js
@@ -1,21 +1,21 @@
-import React from 'react';
-import { View } from 'react-native';
-import { FlatList } from 'react-native-gesture-handler';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { DDS } from '../../services/device-detection';
-import { SIZE } from '../../utils/size';
-import { Button } from '../ui/button';
-import { PressableButton } from '../ui/pressable';
-import Paragraph from '../ui/typography/paragraph';
-import { useActions } from '../../hooks/use-actions';
+import React from "react";
+import { View } from "react-native";
+import { FlatList } from "react-native-gesture-handler";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { DDS } from "../../services/device-detection";
+import { SIZE } from "../../utils/size";
+import { Button } from "../ui/button";
+import { PressableButton } from "../ui/pressable";
+import Paragraph from "../ui/typography/paragraph";
+import { useActions } from "../../hooks/use-actions";
export const Items = ({ item, buttons, close }) => {
- const colors = useThemeStore(state => state.colors);
- const dimensions = useSettingStore(state => state.dimensions);
+ const colors = useThemeStore((state) => state.colors);
+ const dimensions = useSettingStore((state) => state.dimensions);
const actions = useActions({ item, close });
- const data = actions.filter(i => buttons.indexOf(i.name) > -1 && !i.hidden);
+ const data = actions.filter((i) => buttons.indexOf(i.name) > -1 && !i.hidden);
let width = dimensions.width > 600 ? 600 : dimensions.width;
let columnItemsCount = DDS.isLargeTablet() ? 7 : 5;
@@ -27,24 +27,24 @@ export const Items = ({ item, buttons, close }) => {
@@ -54,14 +54,14 @@ export const Items = ({ item, buttons, close }) => {
color={
item.on
? colors.accent
- : item.name === 'Delete' || item.name === 'PermDelete'
+ : item.name === "Delete" || item.name === "PermDelete"
? colors.errorText
: colors.icon
}
/>
-
+
{item.title}
@@ -72,44 +72,48 @@ export const Items = ({ item, buttons, close }) => {
buttonType={{
text: item.on
? colors.accent
- : item.name === 'Delete' || item.name === 'PermDelete'
+ : item.name === "Delete" || item.name === "PermDelete"
? colors.errorText
: colors.pri
}}
onPress={item.func}
title={item.title}
icon={item.icon}
- type={item.on ? 'shade' : 'gray'}
+ type={item.on ? "shade" : "gray"}
fontSize={SIZE.sm}
style={{
borderRadius: 0,
- justifyContent: 'flex-start',
- alignSelf: 'flex-start',
- width: '100%'
+ justifyContent: "flex-start",
+ alignSelf: "flex-start",
+ width: "100%"
}}
/>
);
- return item.type === 'note' ? (
+ return item.type === "note" ? (
item.title}
+ keyExtractor={(item) => item.title}
numColumns={buttons.length < 5 ? buttons.length : columnItemsCount}
style={{
- marginTop: item.type !== 'note' ? 10 : 0,
+ marginTop: item.type !== "note" ? 10 : 0,
paddingTop: 10
}}
columnWrapperStyle={{
- justifyContent: 'flex-start'
+ justifyContent: "flex-start"
}}
contentContainerStyle={{
- alignSelf: 'center',
- width: buttons.length < 5 ? '100%' : null,
+ alignSelf: "center",
+ width: buttons.length < 5 ? "100%" : null,
paddingLeft: buttons.length < 5 ? 10 : 0
}}
renderItem={_renderRowItem}
/>
) : (
- item.title} renderItem={renderColumnItem} />
+ item.title}
+ renderItem={renderColumnItem}
+ />
);
};
diff --git a/apps/mobile/app/components/properties/notebooks.js b/apps/mobile/app/components/properties/notebooks.js
index b6d94f958..93ab48c6f 100644
--- a/apps/mobile/app/components/properties/notebooks.js
+++ b/apps/mobile/app/components/properties/notebooks.js
@@ -1,20 +1,20 @@
-import React from 'react';
-import { ScrollView, View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { eSendEvent } from '../../services/event-manager';
-import Navigation from '../../services/navigation';
-import { db } from '../../common/database';
-import { eOnNewTopicAdded, refreshNotesPage } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { Button } from '../ui/button';
-import { PressableButton } from '../ui/pressable';
-import Heading from '../ui/typography/heading';
-import { TopicNotes } from '../../screens/notes/topic-notes';
-import Notebook from '../../screens/notebook';
+import React from "react";
+import { ScrollView, View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { eSendEvent } from "../../services/event-manager";
+import Navigation from "../../services/navigation";
+import { db } from "../../common/database";
+import { eOnNewTopicAdded, refreshNotesPage } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { Button } from "../ui/button";
+import { PressableButton } from "../ui/pressable";
+import Heading from "../ui/typography/heading";
+import { TopicNotes } from "../../screens/notes/topic-notes";
+import Notebook from "../../screens/notebook";
export default function Notebooks({ note, close }) {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
function getNotebooks(item) {
if (!item.notebooks || item.notebooks.length < 1) return [];
@@ -27,7 +27,7 @@ export default function Notebooks({ note, close }) {
id: notebook.id,
title: item_notebook.title,
topics: notebook.topics
- .map(item => {
+ .map((item) => {
let topic = item_notebook.topics.topic(item)?._topic;
if (!topic) return null;
return {
@@ -35,7 +35,7 @@ export default function Notebooks({ note, close }) {
title: topic.title
};
})
- .filter(i => i !== null)
+ .filter((i) => i !== null)
};
notebooks.push(data);
}
@@ -43,7 +43,7 @@ export default function Notebooks({ note, close }) {
return notebooks;
}
- const navigateNotebook = id => {
+ const navigateNotebook = (id) => {
let item = db.notebooks.notebook(id)?.data;
if (!item) return;
Notebook.navigate(item, true);
@@ -58,12 +58,12 @@ export default function Notebooks({ note, close }) {
return !note.notebooks || note.notebooks.length === 0 ? null : (
- {getNotebooks(note).map(item => (
+ {getNotebooks(note).map((item) => (
{
@@ -71,10 +71,10 @@ export default function Notebooks({ note, close }) {
close();
}}
customStyle={{
- justifyContent: 'flex-start',
+ justifyContent: "flex-start",
paddingHorizontal: 12,
- flexDirection: 'row',
- alignItems: 'center',
+ flexDirection: "row",
+ alignItems: "center",
flexShrink: 1,
flexGrow: 1,
marginTop: 5,
@@ -92,7 +92,7 @@ export default function Notebooks({ note, close }) {
@@ -103,14 +103,14 @@ export default function Notebooks({ note, close }) {
horizontal={true}
showsHorizontalScrollIndicator={false}
style={{
- flexDirection: 'row',
+ flexDirection: "row",
marginLeft: 8,
borderLeftColor: colors.nav,
borderLeftWidth: 1,
paddingLeft: 8
}}
>
- {item.topics.map(topic => (
+ {item.topics.map((topic) => (
{
diff --git a/apps/mobile/app/components/properties/synced.js b/apps/mobile/app/components/properties/synced.js
index 2ad2af330..5dda6ba3e 100644
--- a/apps/mobile/app/components/properties/synced.js
+++ b/apps/mobile/app/components/properties/synced.js
@@ -1,30 +1,30 @@
-import React from 'react';
-import { View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useUserStore } from '../../stores/use-user-store';
-import { openLinkInBrowser } from '../../utils/functions';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import { Button } from '../ui/button';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
+import React from "react";
+import { View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useUserStore } from "../../stores/use-user-store";
+import { openLinkInBrowser } from "../../utils/functions";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import { Button } from "../ui/button";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
export const Synced = ({ item, close }) => {
- const colors = useThemeStore(state => state.colors);
- const user = useUserStore(state => state.user);
- const lastSynced = useUserStore(state => state.lastSynced);
+ const colors = useThemeStore((state) => state.colors);
+ const user = useUserStore((state) => state.user);
+ const lastSynced = useUserStore((state) => state.lastSynced);
return user && lastSynced >= item.dateModified ? (
{
color={colors.heading}
size={SIZE.xs}
style={{
- flexWrap: 'wrap'
+ flexWrap: "wrap"
}}
>
Encrypted and synced
{
try {
close();
await sleep(300);
- await openLinkInBrowser('https://docs.notesnook.com/how-is-my-data-encrypted/', colors);
+ await openLinkInBrowser(
+ "https://docs.notesnook.com/how-is-my-data-encrypted/",
+ colors
+ );
} catch (e) {}
}}
fontSize={SIZE.xs + 1}
diff --git a/apps/mobile/app/components/properties/tags.js b/apps/mobile/app/components/properties/tags.js
index f5dd4532e..79525a008 100644
--- a/apps/mobile/app/components/properties/tags.js
+++ b/apps/mobile/app/components/properties/tags.js
@@ -1,17 +1,17 @@
-import React, { useState } from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { eSendEvent } from '../../services/event-manager';
-import Navigation from '../../services/navigation';
-import { db } from '../../common/database';
-import { eOpenTagsDialog, refreshNotesPage } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import { Button } from '../ui/button';
-import { TaggedNotes } from '../../screens/notes/tagged';
+import React, { useState } from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { eSendEvent } from "../../services/event-manager";
+import Navigation from "../../services/navigation";
+import { db } from "../../common/database";
+import { eOpenTagsDialog, refreshNotesPage } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import { Button } from "../ui/button";
+import { TaggedNotes } from "../../screens/notes/tagged";
export const Tags = ({ item, close }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return item.id ? (
{
>
{
const TagItem = ({ tag, close }) => {
const onPress = async () => {
let tags = db.tags.all;
- let _tag = tags.find(t => t.title === tag);
+ let _tag = tags.find((t) => t.title === tag);
TaggedNotes.navigate(_tag, true);
await sleep(300);
close();
@@ -75,7 +75,7 @@ const TagItem = ({ tag, close }) => {
return (
{
- const open = topic => {
+ const open = (topic) => {
close();
TopicNotes.navigate(topic, true);
};
- const renderItem = topic => (
+ const renderItem = (topic) => (
{
/>
);
- return item && item.type === 'notebook' && item.topics && item.topics.length > 0 ? (
+ return item &&
+ item.type === "notebook" &&
+ item.topics &&
+ item.topics.length > 0 ? (
{item.topics
diff --git a/apps/mobile/app/components/selection-header/index.js b/apps/mobile/app/components/selection-header/index.js
index 8af6c80af..6a527408a 100644
--- a/apps/mobile/app/components/selection-header/index.js
+++ b/apps/mobile/app/components/selection-header/index.js
@@ -1,29 +1,31 @@
-import React, { useEffect } from 'react';
-import { BackHandler, Platform, View } from 'react-native';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useSelectionStore } from '../../stores/use-selection-store';
-import { eSendEvent, ToastEvent } from '../../services/event-manager';
-import Navigation from '../../services/navigation';
-import { db } from '../../common/database';
-import { eOpenMoveNoteDialog } from '../../utils/events';
-import { deleteItems } from '../../utils/functions';
-import { tabBarRef } from '../../utils/global-refs';
-import layoutmanager from '../../utils/layout-manager';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import { presentDialog } from '../dialog/functions';
-import { IconButton } from '../ui/icon-button';
-import Heading from '../ui/typography/heading';
-import useNavigationStore from '../../stores/use-navigation-store';
+import React, { useEffect } from "react";
+import { BackHandler, Platform, View } from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useSelectionStore } from "../../stores/use-selection-store";
+import { eSendEvent, ToastEvent } from "../../services/event-manager";
+import Navigation from "../../services/navigation";
+import { db } from "../../common/database";
+import { eOpenMoveNoteDialog } from "../../utils/events";
+import { deleteItems } from "../../utils/functions";
+import { tabBarRef } from "../../utils/global-refs";
+import layoutmanager from "../../utils/layout-manager";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import { presentDialog } from "../dialog/functions";
+import { IconButton } from "../ui/icon-button";
+import Heading from "../ui/typography/heading";
+import useNavigationStore from "../../stores/use-navigation-store";
export const SelectionHeader = React.memo(() => {
- const colors = useThemeStore(state => state.colors);
- const selectionMode = useSelectionStore(state => state.selectionMode);
- const selectedItemsList = useSelectionStore(state => state.selectedItemsList);
- const setSelectionMode = useSelectionStore(state => state.setSelectionMode);
- const clearSelection = useSelectionStore(state => state.clearSelection);
- const currentScreen = useNavigationStore(state => state.currentScreen);
+ const colors = useThemeStore((state) => state.colors);
+ const selectionMode = useSelectionStore((state) => state.selectionMode);
+ const selectedItemsList = useSelectionStore(
+ (state) => state.selectedItemsList
+ );
+ const setSelectionMode = useSelectionStore((state) => state.setSelectionMode);
+ const clearSelection = useSelectionStore((state) => state.clearSelection);
+ const currentScreen = useNavigationStore((state) => state.currentScreen);
const screen = currentScreen.name;
const insets = useSafeAreaInsets();
@@ -37,15 +39,15 @@ export const SelectionHeader = React.memo(() => {
const addToFavorite = async () => {
if (selectedItemsList.length > 0) {
- selectedItemsList.forEach(item => {
+ selectedItemsList.forEach((item) => {
db.notes.note(item.id).favorite();
});
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes"
);
clearSelection();
}
@@ -54,58 +56,60 @@ export const SelectionHeader = React.memo(() => {
const restoreItem = async () => {
if (selectedItemsList.length > 0) {
let noteIds = [];
- selectedItemsList.forEach(item => {
+ selectedItemsList.forEach((item) => {
noteIds.push(item.id);
});
await db.trash.restore(...noteIds);
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes',
- 'Trash',
- 'Notebooks',
- 'Tags'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes",
+ "Trash",
+ "Notebooks",
+ "Tags"
);
clearSelection();
ToastEvent.show({
- heading: 'Restore successful',
- type: 'success'
+ heading: "Restore successful",
+ type: "success"
});
}
};
const deleteItem = async () => {
presentDialog({
- title: `Delete ${selectedItemsList.length > 1 ? 'items' : 'item'}`,
+ title: `Delete ${selectedItemsList.length > 1 ? "items" : "item"}`,
paragraph: `Are you sure you want to delete ${
- selectedItemsList.length > 1 ? 'these items permanently?' : 'this item permanently?'
+ selectedItemsList.length > 1
+ ? "these items permanently?"
+ : "this item permanently?"
}`,
- positiveText: 'Delete',
- negativeText: 'Cancel',
+ positiveText: "Delete",
+ negativeText: "Cancel",
positivePress: async () => {
if (selectedItemsList.length > 0) {
let noteIds = [];
- selectedItemsList.forEach(item => {
+ selectedItemsList.forEach((item) => {
noteIds.push(item.id);
});
await db.trash.delete(...noteIds);
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes',
- 'Trash',
- 'Notebooks',
- 'Tags'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes",
+ "Trash",
+ "Notebooks",
+ "Tags"
);
clearSelection();
}
},
- positiveType: 'errorShade'
+ positiveType: "errorShade"
});
};
@@ -117,38 +121,38 @@ export const SelectionHeader = React.memo(() => {
useEffect(() => {
if (selectionMode) {
- BackHandler.addEventListener('hardwareBackPress', onBackPress);
+ BackHandler.addEventListener("hardwareBackPress", onBackPress);
} else {
- BackHandler.removeEventListener('hardwareBackPress', onBackPress);
+ BackHandler.removeEventListener("hardwareBackPress", onBackPress);
}
}, [selectionMode]);
return !selectionMode ? null : (
{
height: 40,
borderRadius: 100,
paddingHorizontal: 16,
- justifyContent: 'center',
- flexDirection: 'row',
- alignItems: 'center'
+ justifyContent: "center",
+ flexDirection: "row",
+ alignItems: "center"
}}
>
- {selectedItemsList.length + ' Selected'}
+ {selectedItemsList.length + " Selected"}
{/* {
size={SIZE.xl}
/> */}
- {screen === 'Trash' || screen === 'Notebooks' || screen === 'Notebook' ? null : (
+ {screen === "Trash" ||
+ screen === "Notebooks" ||
+ screen === "Notebook" ? null : (
{
//setSelectionMode(false);
@@ -217,23 +223,24 @@ export const SelectionHeader = React.memo(() => {
/>
)}
- {screen === 'TopicNotes' ? (
+ {screen === "TopicNotes" ? (
{
if (selectedItemsList.length > 0) {
- const currentTopic = useNavigationStore.getState().currentScreen;
+ const currentTopic =
+ useNavigationStore.getState().currentScreen;
await db.notebooks
.notebook(currentTopic.notebookId)
.topics.topic(currentTopic.id)
- .delete(...selectedItemsList.map(item => item.id));
+ .delete(...selectedItemsList.map((item) => item.id));
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes',
- 'Notebooks',
- 'Notebook'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes",
+ "Notebooks",
+ "Notebook"
);
clearSelection();
}
@@ -248,7 +255,7 @@ export const SelectionHeader = React.memo(() => {
/>
) : null}
- {screen === 'Favorites' ? (
+ {screen === "Favorites" ? (
{
/>
) : null}
- {screen === 'Trash' ? null : (
+ {screen === "Trash" ? null : (
{
presentDialog({
- title: `Delete ${selectedItemsList.length > 1 ? 'items' : 'item'}`,
- paragraph: `Are you sure you want to delete ${
- selectedItemsList.length > 1 ? 'these items?' : 'this item?'
+ title: `Delete ${
+ selectedItemsList.length > 1 ? "items" : "item"
}`,
- positiveText: 'Delete',
- negativeText: 'Cancel',
+ paragraph: `Are you sure you want to delete ${
+ selectedItemsList.length > 1 ? "these items?" : "this item?"
+ }`,
+ positiveText: "Delete",
+ negativeText: "Cancel",
positivePress: () => {
deleteItems();
},
- positiveType: 'errorShade'
+ positiveType: "errorShade"
});
return;
@@ -287,7 +296,7 @@ export const SelectionHeader = React.memo(() => {
/>
)}
- {screen === 'Trash' ? (
+ {screen === "Trash" ? (
<>
{
);
});
-SelectionHeader.displayName = 'SelectionHeader';
+SelectionHeader.displayName = "SelectionHeader";
export default SelectionHeader;
diff --git a/apps/mobile/app/components/sheet-provider/index.js b/apps/mobile/app/components/sheet-provider/index.js
index dc9107b54..b94c24d07 100644
--- a/apps/mobile/app/components/sheet-provider/index.js
+++ b/apps/mobile/app/components/sheet-provider/index.js
@@ -1,19 +1,22 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { ActivityIndicator, View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { editorState } from '../../screens/editor/tiptap/utils';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { eCloseProgressDialog, eOpenProgressDialog } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import { Button } from '../ui/button';
-import SheetWrapper from '../ui/sheet';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
+import React, { useEffect, useRef, useState } from "react";
+import { ActivityIndicator, View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { editorState } from "../../screens/editor/tiptap/utils";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { eCloseProgressDialog, eOpenProgressDialog } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import { Button } from "../ui/button";
+import SheetWrapper from "../ui/sheet";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
-const SheetProvider = ({ context = 'global' }) => {
- const colors = useThemeStore(state => state.colors);
+const SheetProvider = ({ context = "global" }) => {
+ const colors = useThemeStore((state) => state.colors);
const [visible, setVisible] = useState(false);
const [dialogData, setDialogData] = useState(null);
const actionSheetRef = useRef();
@@ -30,8 +33,8 @@ const SheetProvider = ({ context = 'global' }) => {
};
}, [visible]);
- const open = async data => {
- if (!data.context) data.context = 'global';
+ const open = async (data) => {
+ if (!data.context) data.context = "global";
if (data.context !== context) return;
if (visible || dialogData) {
setDialogData(null);
@@ -65,8 +68,8 @@ const SheetProvider = ({ context = 'global' }) => {
})();
}, [visible, dialogData]);
- const close = ctx => {
- if (!ctx) ctx = 'global';
+ const close = (ctx) => {
+ if (!ctx) ctx = "global";
if (ctx !== context) return;
actionSheetRef.current?.setModalVisible(false);
};
@@ -75,7 +78,9 @@ const SheetProvider = ({ context = 'global' }) => {
{
dialogData.onClose && dialogData.onClose();
setVisible(false);
@@ -84,10 +89,13 @@ const SheetProvider = ({ context = 'global' }) => {
>
{
{dialogData?.title ? {dialogData?.title} : null}
{dialogData?.paragraph ? (
- {dialogData?.paragraph}
+
+ {dialogData?.paragraph}
+
) : null}
- {typeof dialogData.component === 'function'
+ {typeof dialogData.component === "function"
? dialogData.component(actionSheetRef, close)
: dialogData.component}
@@ -129,18 +139,18 @@ const SheetProvider = ({ context = 'global' }) => {
}}
>
{dialogData.valueArray &&
- dialogData.valueArray.map(v => (
+ dialogData.valueArray.map((v) => (
))}
@@ -156,7 +166,7 @@ const SheetProvider = ({ context = 'global' }) => {
onPress={dialogData.action}
key={dialogData.actionText}
title={dialogData.actionText}
- accentColor={dialogData.iconColor || 'accent'}
+ accentColor={dialogData.iconColor || "accent"}
accentText="light"
type="accent"
height={50}
@@ -172,7 +182,7 @@ const SheetProvider = ({ context = 'global' }) => {
key={item.accentText}
title={item.actionText}
icon={item.icon && item.icon}
- type={item.type || 'accent'}
+ type={item.type || "accent"}
height={50}
style={{
marginBottom: 10
@@ -185,15 +195,19 @@ const SheetProvider = ({ context = 'global' }) => {
{dialogData?.learnMore ? (
- {' '}
+ {" "}
{dialogData.learnMore}
) : null}
diff --git a/apps/mobile/app/components/sheets/add-notebook/index.js b/apps/mobile/app/components/sheets/add-notebook/index.js
index 734f6b84d..2651e970a 100644
--- a/apps/mobile/app/components/sheets/add-notebook/index.js
+++ b/apps/mobile/app/components/sheets/add-notebook/index.js
@@ -1,23 +1,36 @@
-import React, { createRef } from 'react';
-import { Keyboard, StyleSheet, TextInput, TouchableOpacity, View } from 'react-native';
-import { FlatList } from 'react-native-gesture-handler';
-import { notesnook } from '../../../../e2e/test.ids';
-import { useMenuStore } from '../../../stores/use-menu-store';
-import { DDS } from '../../../services/device-detection';
-import { eSubscribeEvent, eUnSubscribeEvent, ToastEvent } from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import { db } from '../../../common/database';
-import { eCloseAddNotebookDialog, eOpenAddNotebookDialog } from '../../../utils/events';
-import { ph, pv, SIZE } from '../../../utils/size';
-import { sleep } from '../../../utils/time';
-import { IconButton } from '../../ui/icon-button';
-import { Button } from '../../ui/button';
-import DialogHeader from '../../dialog/dialog-header';
-import Input from '../../ui/input';
-import { MoveNotes } from '../move-notes/movenote';
-import Seperator from '../../ui/seperator';
-import SheetWrapper from '../../ui/sheet';
-import { Toast } from '../../toast';
+import React, { createRef } from "react";
+import {
+ Keyboard,
+ StyleSheet,
+ TextInput,
+ TouchableOpacity,
+ View
+} from "react-native";
+import { FlatList } from "react-native-gesture-handler";
+import { notesnook } from "../../../../e2e/test.ids";
+import { useMenuStore } from "../../../stores/use-menu-store";
+import { DDS } from "../../../services/device-detection";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent,
+ ToastEvent
+} from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import { db } from "../../../common/database";
+import {
+ eCloseAddNotebookDialog,
+ eOpenAddNotebookDialog
+} from "../../../utils/events";
+import { ph, pv, SIZE } from "../../../utils/size";
+import { sleep } from "../../../utils/time";
+import { IconButton } from "../../ui/icon-button";
+import { Button } from "../../ui/button";
+import DialogHeader from "../../dialog/dialog-header";
+import Input from "../../ui/input";
+import { MoveNotes } from "../move-notes/movenote";
+import Seperator from "../../ui/seperator";
+import SheetWrapper from "../../ui/sheet";
+import { Toast } from "../../toast";
let refs = [];
@@ -64,7 +77,7 @@ export class AddNotebookSheet extends React.Component {
eUnSubscribeEvent(eCloseAddNotebookDialog, this.close);
}
- open = notebook => {
+ open = (notebook) => {
refs = [];
if (notebook) {
@@ -87,7 +100,7 @@ export class AddNotebookSheet extends React.Component {
notebook: null
});
}
- sleep(100).then(r => {
+ sleep(100).then((r) => {
this.actionSheetRef.current?.show();
});
};
@@ -104,7 +117,7 @@ export class AddNotebookSheet extends React.Component {
this.id = null;
};
- onDelete = index => {
+ onDelete = (index) => {
let { topics } = this.state;
let prevTopics = topics;
refs = [];
@@ -139,9 +152,9 @@ export class AddNotebookSheet extends React.Component {
if (!this.title || this.title?.trim().length === 0) {
ToastEvent.show({
- heading: 'Notebook title is required',
- type: 'error',
- context: 'local'
+ heading: "Notebook title is required",
+ type: "error",
+ context: "local"
});
this.setState({
loading: false
@@ -166,7 +179,9 @@ export class AddNotebookSheet extends React.Component {
let newNotebookId = null;
if (notebook) {
if (this.topicsToDelete?.length > 0) {
- await db.notebooks.notebook(toEdit.id).topics.delete(...this.topicsToDelete);
+ await db.notebooks
+ .notebook(toEdit.id)
+ .topics.delete(...this.topicsToDelete);
toEdit = db.notebooks.notebook(toEdit.id).data;
}
@@ -199,12 +214,12 @@ export class AddNotebookSheet extends React.Component {
}
useMenuStore.getState().setMenuPins();
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes',
- 'Notebooks',
- 'Notebook'
+ "Notes",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes",
+ "Notebooks",
+ "Notebook"
);
this.setState({
@@ -221,7 +236,8 @@ export class AddNotebookSheet extends React.Component {
this.hiddenInput.current?.focus();
let willFocus = true;
let { topics } = this.state;
- if (!this.currentInputValue || this.currentInputValue?.trim().length === 0) return;
+ if (!this.currentInputValue || this.currentInputValue?.trim().length === 0)
+ return;
let prevTopics = [...topics];
if (this.prevItem === null) {
@@ -259,7 +275,7 @@ export class AddNotebookSheet extends React.Component {
}
}
this.topicInputRef.current?.setNativeProps({
- text: ''
+ text: ""
});
willFocus && this.topicInputRef.current?.focus();
};
@@ -292,7 +308,7 @@ export class AddNotebookSheet extends React.Component {
>
(this.titleRef = ref)}
+ fwdRef={(ref) => (this.titleRef = ref)}
testID={notesnook.ids.dialogs.notebook.inputs.title}
- onChangeText={value => {
+ onChangeText={(value) => {
this.title = value;
}}
placeholder="Enter a title"
@@ -333,9 +353,9 @@ export class AddNotebookSheet extends React.Component {
/>
(this.descriptionRef = ref)}
+ fwdRef={(ref) => (this.descriptionRef = ref)}
testID={notesnook.ids.dialogs.notebook.inputs.description}
- onChangeText={value => {
+ onChangeText={(value) => {
this.description = value;
}}
placeholder="Describe your notebook."
@@ -350,7 +370,7 @@ export class AddNotebookSheet extends React.Component {
{
+ onChangeText={(value) => {
this.currentInputValue = value;
if (this.prevItem !== null) {
refs[this.prevIndex].setNativeProps({
@@ -368,8 +388,8 @@ export class AddNotebookSheet extends React.Component {
}}
blurOnSubmit={false}
button={{
- testID: 'topic-add-button',
- icon: this.state.editTopic ? 'check' : 'plus',
+ testID: "topic-add-button",
+ icon: this.state.editTopic ? "check" : "plus",
onPress: this.onSubmit,
color: topicInputFocused ? colors.accent : colors.icon
}}
@@ -378,7 +398,7 @@ export class AddNotebookSheet extends React.Component {
(this.listRef = ref)}
+ ref={(ref) => (this.listRef = ref)}
nestedScrollEnabled
keyExtractor={(item, index) => item + index.toString()}
onMomentumScrollEnd={() => {
@@ -413,7 +433,11 @@ export class AddNotebookSheet extends React.Component {
width="100%"
height={50}
fontSize={SIZE.md}
- title={notebook && notebook.dateCreated ? 'Save changes' : 'Create notebook'}
+ title={
+ notebook && notebook.dateCreated
+ ? "Save changes"
+ : "Create notebook"
+ }
type="accent"
onPress={this.addNewNotebook}
/>
@@ -434,14 +458,14 @@ export class AddNotebookSheet extends React.Component {
}
const TopicItem = ({ item, index, colors, onPress, onDelete }) => {
- const topicRef = ref => (refs[index] = ref);
+ const topicRef = (ref) => (refs[index] = ref);
return (
{
>
{
@@ -475,11 +499,11 @@ const TopicItem = ({ item, index, colors, onPress, onDelete }) => {
{
const styles = StyleSheet.create({
wrapper: {
- width: '100%',
- height: '100%',
- backgroundColor: 'rgba(0,0,0,0.3)',
- justifyContent: 'center',
- alignItems: 'center'
+ width: "100%",
+ height: "100%",
+ backgroundColor: "rgba(0,0,0,0.3)",
+ justifyContent: "center",
+ alignItems: "center"
},
overlay: {
- width: '100%',
- height: '100%',
- position: 'absolute'
+ width: "100%",
+ height: "100%",
+ position: "absolute"
},
headingContainer: {
- flexDirection: 'row',
- justifyContent: 'center',
- alignItems: 'center'
+ flexDirection: "row",
+ justifyContent: "center",
+ alignItems: "center"
},
headingText: {
marginLeft: 5,
@@ -537,25 +561,25 @@ const styles = StyleSheet.create({
marginBottom: 5
},
addBtn: {
- width: '12%',
+ width: "12%",
minHeight: 45,
- justifyContent: 'center',
- alignItems: 'center',
- position: 'absolute',
+ justifyContent: "center",
+ alignItems: "center",
+ position: "absolute",
right: 0
},
buttonContainer: {
- justifyContent: 'space-between',
- alignItems: 'center',
- flexDirection: 'row',
- width: '100%',
+ justifyContent: "space-between",
+ alignItems: "center",
+ flexDirection: "row",
+ width: "100%",
marginTop: 20
},
topicContainer: {
- flexDirection: 'row',
- justifyContent: 'space-between',
- alignItems: 'center',
+ flexDirection: "row",
+ justifyContent: "space-between",
+ alignItems: "center",
marginTop: 10
},
topicInput: {
@@ -565,16 +589,16 @@ const styles = StyleSheet.create({
paddingHorizontal: ph,
paddingRight: 40,
paddingVertical: 10,
- width: '100%',
- maxWidth: '100%'
+ width: "100%",
+ maxWidth: "100%"
},
topicBtn: {
borderRadius: 5,
width: 40,
height: 40,
- justifyContent: 'center',
- alignItems: 'center',
- position: 'absolute',
+ justifyContent: "center",
+ alignItems: "center",
+ position: "absolute",
right: 0
}
});
diff --git a/apps/mobile/app/components/sheets/add-to/index.js b/apps/mobile/app/components/sheets/add-to/index.js
index 9cb2b3652..fb1f66b9a 100644
--- a/apps/mobile/app/components/sheets/add-to/index.js
+++ b/apps/mobile/app/components/sheets/add-to/index.js
@@ -1,28 +1,32 @@
-import React, { createRef, useEffect, useState } from 'react';
-import { Keyboard, TouchableOpacity, View } from 'react-native';
-import { FlatList } from 'react-native-gesture-handler';
-import { notesnook } from '../../../../e2e/test.ids';
-import { eSubscribeEvent, eUnSubscribeEvent, ToastEvent } from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import SearchService from '../../../services/search';
-import { useSelectionStore } from '../../../stores/use-selection-store';
-import { useNotebookStore } from '../../../stores/use-notebook-store';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { getTotalNotes } from '../../../utils';
-import { db } from '../../../common/database';
-import { eOpenMoveNoteDialog } from '../../../utils/events';
-import layoutmanager from '../../../utils/layout-manager';
-import { SIZE } from '../../../utils/size';
-import { Dialog } from '../../dialog';
-import DialogHeader from '../../dialog/dialog-header';
-import { presentDialog } from '../../dialog/functions';
-import { Button } from '../../ui/button';
-import { IconButton } from '../../ui/icon-button';
-import Input from '../../ui/input';
-import { PressableButton } from '../../ui/pressable';
-import SheetWrapper from '../../ui/sheet';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
+import React, { createRef, useEffect, useState } from "react";
+import { Keyboard, TouchableOpacity, View } from "react-native";
+import { FlatList } from "react-native-gesture-handler";
+import { notesnook } from "../../../../e2e/test.ids";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent,
+ ToastEvent
+} from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import SearchService from "../../../services/search";
+import { useSelectionStore } from "../../../stores/use-selection-store";
+import { useNotebookStore } from "../../../stores/use-notebook-store";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { getTotalNotes } from "../../../utils";
+import { db } from "../../../common/database";
+import { eOpenMoveNoteDialog } from "../../../utils/events";
+import layoutmanager from "../../../utils/layout-manager";
+import { SIZE } from "../../../utils/size";
+import { Dialog } from "../../dialog";
+import DialogHeader from "../../dialog/dialog-header";
+import { presentDialog } from "../../dialog/functions";
+import { Button } from "../../ui/button";
+import { IconButton } from "../../ui/icon-button";
+import Input from "../../ui/input";
+import { PressableButton } from "../../ui/pressable";
+import SheetWrapper from "../../ui/sheet";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
let newNotebookTitle = null;
const notebookInput = createRef();
@@ -52,13 +56,13 @@ const AddToNotebookSheet = () => {
newNotebookTitle = null;
setNote(null);
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes',
- 'Notebooks',
- 'Notebook'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes",
+ "Notebooks",
+ "Notebook"
);
};
@@ -72,21 +76,25 @@ const AddToNotebookSheet = () => {
export default AddToNotebookSheet;
const MoveNoteComponent = ({ note }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
- const notebooks = useNotebookStore(state => state.notebooks.filter(n => n?.type === 'notebook'));
+ const notebooks = useNotebookStore((state) =>
+ state.notebooks.filter((n) => n?.type === "notebook")
+ );
- const selectedItemsList = useSelectionStore(state => state.selectedItemsList);
- const setNotebooks = useNotebookStore(state => state.setNotebooks);
- const [expanded, setExpanded] = useState('');
+ const selectedItemsList = useSelectionStore(
+ (state) => state.selectedItemsList
+ );
+ const setNotebooks = useNotebookStore((state) => state.setNotebooks);
+ const [expanded, setExpanded] = useState("");
const [notebookInputFocused, setNotebookInputFocused] = useState(false);
const [noteExists, setNoteExists] = useState([]);
const addNewNotebook = async () => {
if (!newNotebookTitle || newNotebookTitle.trim().length === 0)
return ToastEvent.show({
- heading: 'Notebook title is required',
- type: 'error',
- context: 'local'
+ heading: "Notebook title is required",
+ type: "error",
+ context: "local"
});
let id = await db.notebooks.add({
@@ -95,7 +103,7 @@ const MoveNoteComponent = ({ note }) => {
topics: [],
id: null
});
- console.log('added notebook id', id);
+ console.log("added notebook id", id);
setExpanded(id);
openAddTopicDialog(db.notebooks.notebook(id).data);
notebookInput.current?.clear();
@@ -107,9 +115,9 @@ const MoveNoteComponent = ({ note }) => {
const addNewTopic = async (value, item) => {
if (!value || value.trim().length === 0) {
ToastEvent.show({
- heading: 'Topic title is required',
- type: 'error',
- context: 'local'
+ heading: "Topic title is required",
+ type: "error",
+ context: "local"
});
return false;
}
@@ -121,7 +129,10 @@ const MoveNoteComponent = ({ note }) => {
};
const handlePress = async (item, index) => {
- let noteIds = selectedItemsList.length > 0 ? selectedItemsList.map(n => n.id) : [note?.id];
+ let noteIds =
+ selectedItemsList.length > 0
+ ? selectedItemsList.map((n) => n.id)
+ : [note?.id];
if (getCount(item)) {
await db.notebooks
@@ -139,11 +150,11 @@ const MoveNoteComponent = ({ note }) => {
}
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes"
);
setNotebooks();
@@ -158,17 +169,20 @@ const MoveNoteComponent = ({ note }) => {
const updateNoteExists = () => {
if (!note?.id && selectedItemsList?.length === 0) return;
- let notes = selectedItemsList.length > 0 ? selectedItemsList.map(n => n.id) : [note?.id];
+ let notes =
+ selectedItemsList.length > 0
+ ? selectedItemsList.map((n) => n.id)
+ : [note?.id];
let ids = [];
let notebooks = db.notebooks.all;
for (let i = 0; i < notebooks.length; i++) {
if (notebooks[i].topics) {
for (let t = 0; t < notebooks[i].topics.length; t++) {
let topic = notebooks[i].topics[t];
- if (topic.type !== 'topic') continue;
+ if (topic.type !== "topic") continue;
for (let id of notes) {
if (topic.notes.indexOf(id) > -1) {
- console.log('found', ids.indexOf(notebooks[i].id));
+ console.log("found", ids.indexOf(notebooks[i].id));
if (ids.indexOf(notebooks[i].id) === -1) {
ids.push(notebooks[i].id);
}
@@ -178,27 +192,30 @@ const MoveNoteComponent = ({ note }) => {
}
}
}
- console.log('ids: ', ids);
+ console.log("ids: ", ids);
setNoteExists(ids);
};
- const openAddTopicDialog = item => {
+ const openAddTopicDialog = (item) => {
presentDialog({
- context: 'move_note',
+ context: "move_note",
input: true,
- inputPlaceholder: 'Enter title',
- title: 'New topic',
- paragraph: 'Add a new topic in ' + item.title,
- positiveText: 'Add',
- positivePress: value => {
+ inputPlaceholder: "Enter title",
+ title: "New topic",
+ paragraph: "Add a new topic in " + item.title,
+ positiveText: "Add",
+ positivePress: (value) => {
return addNewTopic(value, item);
}
});
};
- const getCount = topic => {
+ const getCount = (topic) => {
if (!topic) return;
- let notes = selectedItemsList.length > 0 ? selectedItemsList.map(n => n.id) : [note?.id];
+ let notes =
+ selectedItemsList.length > 0
+ ? selectedItemsList.map((n) => n.id)
+ : [note?.id];
let count = 0;
for (let id of notes) {
if (topic.notes.indexOf(id) > -1) {
@@ -216,9 +233,9 @@ const MoveNoteComponent = ({ note }) => {
{
Keyboard.dismiss();
@@ -227,8 +244,8 @@ const MoveNoteComponent = ({ note }) => {
{
ListHeaderComponent={
{
+ onChangeText={(value) => {
newNotebookTitle = value;
}}
testID={notesnook.ids.dialogs.addTo.addNotebook}
@@ -273,7 +290,7 @@ const MoveNoteComponent = ({ note }) => {
setNotebookInputFocused(false);
}}
button={{
- icon: 'check',
+ icon: "check",
color: notebookInputFocused ? colors.accent : colors.icon,
onPress: addNewNotebook
}}
@@ -289,9 +306,9 @@ const MoveNoteComponent = ({ note }) => {
@@ -309,40 +326,42 @@ const MoveNoteComponent = ({ note }) => {
type="grayBg"
customStyle={{
height: 50,
- width: '100%',
+ width: "100%",
borderRadius: 5,
- alignItems: 'flex-start'
+ alignItems: "flex-start"
}}
>
-1 ? colors.accent : null}
+ color={
+ noteExists.indexOf(item.id) > -1 ? colors.accent : null
+ }
size={SIZE.md}
>
{item.title}
{item.topics?.length > 0 ? (
- {getTotalNotes(item) + ' notes' + ' & '}
+ {getTotalNotes(item) + " notes" + " & "}
{item.topics.length === 1
- ? item.topics.length + ' topic'
- : item.topics.length + ' topics'}
+ ? item.topics.length + " topic"
+ : item.topics.length + " topics"}
) : null}
{
@@ -361,15 +380,15 @@ const MoveNoteComponent = ({ note }) => {
{expanded === item.id ? (
t.type === 'topic')}
+ data={item.topics?.filter((t) => t.type === "topic")}
keyboardShouldPersistTaps="always"
keyboardDismissMode="none"
onMomentumScrollEnd={() => {
actionSheetRef.current?.handleChildScrollEnd();
}}
style={{
- width: '100%',
- alignSelf: 'flex-end',
+ width: "100%",
+ alignSelf: "flex-end",
maxHeight: 500
}}
renderItem={({ item, index }) => (
@@ -380,19 +399,21 @@ const MoveNoteComponent = ({ note }) => {
minHeight: 50,
borderTopWidth: index === 0 ? 0 : 1,
borderTopColor: index === 0 ? null : colors.nav,
- width: '100%',
+ width: "100%",
borderRadius: 0,
- alignItems: 'center',
- flexDirection: 'row',
+ alignItems: "center",
+ flexDirection: "row",
paddingHorizontal: 12,
- justifyContent: 'space-between',
+ justifyContent: "space-between",
paddingVertical: 12
}}
>
- {item.title}
+
+ {item.title}
+
- {item.notes.length + ' notes'}
+ {item.notes.length + " notes"}
{getCount(item) ? (
{
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [visible, setVisible] = useState(false);
const actionSheetRef = useRef();
@@ -40,12 +43,12 @@ const ExportNotesSheet = () => {
};
}, []);
- const open = data => {
+ const open = (data) => {
setVisible(true);
setNotes(data);
};
- const close = data => {
+ const close = (data) => {
setComplete(false);
setExporting(false);
setVisible(false);
@@ -67,7 +70,9 @@ const ExportNotesSheet = () => {
}
setDoneText(
`Note exported successfully! You can find the exported note in ${
- Platform.OS === 'ios' ? 'Files Manager/Notesnook' : `Storage/Notesnook/exported/${name}`
+ Platform.OS === "ios"
+ ? "Files Manager/Notesnook"
+ : `Storage/Notesnook/exported/${name}`
}.`
);
@@ -84,39 +89,39 @@ const ExportNotesSheet = () => {
const actions = [
{
- title: 'PDF',
+ title: "PDF",
func: async () => {
- await save(Exporter.saveToPDF, 'PDF');
+ await save(Exporter.saveToPDF, "PDF");
},
- icon: 'file-pdf-box',
- desc: 'Can be opened in a pdf reader like Adobe or Foxit Reader',
+ icon: "file-pdf-box",
+ desc: "Can be opened in a pdf reader like Adobe or Foxit Reader",
id: notesnook.ids.dialogs.export.pdf
},
{
- title: 'Markdown',
+ title: "Markdown",
func: async () => {
- await save(Exporter.saveToMarkdown, 'Markdown');
+ await save(Exporter.saveToMarkdown, "Markdown");
},
- icon: 'language-markdown',
- desc: 'Can be opened in any text or markdown editor',
+ icon: "language-markdown",
+ desc: "Can be opened in any text or markdown editor",
id: notesnook.ids.dialogs.export.md
},
{
- title: 'Plain Text',
+ title: "Plain Text",
func: async () => {
- await save(Exporter.saveToText, 'Text');
+ await save(Exporter.saveToText, "Text");
},
- icon: 'card-text',
- desc: 'Can be opened in any text editor',
+ icon: "card-text",
+ desc: "Can be opened in any text editor",
id: notesnook.ids.dialogs.export.text
},
{
- title: 'HTML',
+ title: "HTML",
func: async () => {
- await save(Exporter.saveToHTML, 'Html');
+ await save(Exporter.saveToHTML, "Html");
},
- icon: 'language-html5',
- desc: 'Can be opened in any web browser',
+ icon: "language-html5",
+ desc: "Can be opened in any web browser",
id: notesnook.ids.dialogs.export.html
}
];
@@ -132,24 +137,26 @@ const ExportNotesSheet = () => {
- {actions.map(item => (
+ {actions.map((item) => (
{
borderRadius: 5,
height: 60,
width: 60,
- justifyContent: 'center',
- alignItems: 'center'
+ justifyContent: "center",
+ alignItems: "center"
}}
>
-
+
{
{item.title}
-
+
{item.desc}
@@ -184,7 +199,7 @@ const ExportNotesSheet = () => {
{
FileViewer.open(result.filePath, {
showOpenWithDialog: true,
showAppsSuggestions: true
- }).catch(e => {
+ }).catch((e) => {
ToastEvent.show({
- heading: 'Cannot open',
+ heading: "Cannot open",
message: `No application found to open ${result.name} file.`,
- type: 'success',
- context: 'local'
+ type: "success",
+ context: "local"
});
});
}}
@@ -222,9 +237,9 @@ const ExportNotesSheet = () => {
marginTop: 10
}}
onPress={async () => {
- if (Platform.OS === 'ios') {
+ if (Platform.OS === "ios") {
Share.open({
- url: 'file:/' + result.filePath
+ url: "file:/" + result.filePath
}).catch(console.log);
} else {
FileViewer.open(result.filePath, {
@@ -241,16 +256,18 @@ const ExportNotesSheet = () => {
{complete && (
- {'Note exported as ' + result.fileName}
+ {"Note exported as " + result.fileName}
)}
- {exporting && !complete && }
+ {exporting && !complete && (
+
+ )}
@@ -265,30 +282,30 @@ const styles = StyleSheet.create({
paddingVertical: pv
},
buttonContainer: {
- justifyContent: 'space-between',
- alignItems: 'center'
+ justifyContent: "space-between",
+ alignItems: "center"
},
button: {
paddingVertical: pv,
paddingHorizontal: ph,
marginTop: 10,
borderRadius: 5,
- width: '100%',
- justifyContent: 'center',
- alignItems: 'center',
+ width: "100%",
+ justifyContent: "center",
+ alignItems: "center",
borderWidth: 1,
- flexDirection: 'row'
+ flexDirection: "row"
},
buttonText: {
//fontFamily: "sans-serif",
- color: 'white',
+ color: "white",
fontSize: SIZE.sm,
marginLeft: 5
},
overlay: {
- width: '100%',
- height: '100%',
- position: 'absolute'
+ width: "100%",
+ height: "100%",
+ position: "absolute"
}
});
diff --git a/apps/mobile/app/components/sheets/export-notes/share.js b/apps/mobile/app/components/sheets/export-notes/share.js
index 0e6d3fd30..8badbeeb2 100644
--- a/apps/mobile/app/components/sheets/export-notes/share.js
+++ b/apps/mobile/app/components/sheets/export-notes/share.js
@@ -1,10 +1,10 @@
-import React from 'react';
-import { View } from 'react-native';
-import FileViewer from 'react-native-file-viewer';
-import Share from 'react-native-share';
-import { ToastEvent } from '../../../services/event-manager';
-import { SIZE } from '../../../utils/size';
-import { Button } from '../../ui/button';
+import React from "react";
+import { View } from "react-native";
+import FileViewer from "react-native-file-viewer";
+import Share from "react-native-share";
+import { ToastEvent } from "../../../services/event-manager";
+import { SIZE } from "../../../utils/size";
+import { Button } from "../../ui/button";
export const ShareComponent = ({ uri, name, padding }) => {
return (
@@ -22,12 +22,12 @@ export const ShareComponent = ({ uri, name, padding }) => {
FileViewer.open(uri, {
showOpenWithDialog: true,
showAppsSuggestions: true
- }).catch(e => {
+ }).catch((e) => {
ToastEvent.show({
- heading: 'Cannot open',
+ heading: "Cannot open",
message: `No application found to open ${name} file.`,
- type: 'success',
- context: 'local'
+ type: "success",
+ context: "local"
});
});
}}
diff --git a/apps/mobile/app/components/sheets/github/issue.js b/apps/mobile/app/components/sheets/github/issue.js
index effb26964..b2d296a55 100644
--- a/apps/mobile/app/components/sheets/github/issue.js
+++ b/apps/mobile/app/components/sheets/github/issue.js
@@ -1,27 +1,27 @@
-import Clipboard from '@react-native-clipboard/clipboard';
-import React, { useRef, useState } from 'react';
-import { Linking, Platform, Text, TextInput, View } from 'react-native';
-import { APP_VERSION } from '../../../version';
-import { eSendEvent, ToastEvent } from '../../../services/event-manager';
-import PremiumService from '../../../services/premium';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { useUserStore } from '../../../stores/use-user-store';
-import { db } from '../../../common/database';
-import { eCloseProgressDialog } from '../../../utils/events';
-import { openLinkInBrowser } from '../../../utils/functions';
-import { SIZE } from '../../../utils/size';
-import { sleep } from '../../../utils/time';
-import DialogHeader from '../../dialog/dialog-header';
-import { presentDialog } from '../../dialog/functions';
-import { Button } from '../../ui/button';
-import Seperator from '../../ui/seperator';
-import Paragraph from '../../ui/typography/paragraph';
+import Clipboard from "@react-native-clipboard/clipboard";
+import React, { useRef, useState } from "react";
+import { Linking, Platform, Text, TextInput, View } from "react-native";
+import { APP_VERSION } from "../../../version";
+import { eSendEvent, ToastEvent } from "../../../services/event-manager";
+import PremiumService from "../../../services/premium";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { useUserStore } from "../../../stores/use-user-store";
+import { db } from "../../../common/database";
+import { eCloseProgressDialog } from "../../../utils/events";
+import { openLinkInBrowser } from "../../../utils/functions";
+import { SIZE } from "../../../utils/size";
+import { sleep } from "../../../utils/time";
+import DialogHeader from "../../dialog/dialog-header";
+import { presentDialog } from "../../dialog/functions";
+import { Button } from "../../ui/button";
+import Seperator from "../../ui/seperator";
+import Paragraph from "../../ui/typography/paragraph";
export const Issue = ({ defaultTitle, defaultBody, issueTitle }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const body = useRef(defaultBody);
const title = useRef(defaultTitle);
- const user = useUserStore(state => state.user);
+ const user = useUserStore((state) => state.user);
const [loading, setLoading] = useState(false);
const bodyRef = useRef();
const initialLayout = useRef(false);
@@ -29,7 +29,8 @@ export const Issue = ({ defaultTitle, defaultBody, issueTitle }) => {
const onPress = async () => {
if (loading) return;
if (!title.current || !body.current) return;
- if (title.current?.trim() === '' || body.current?.trim().length === 0) return;
+ if (title.current?.trim() === "" || body.current?.trim().length === 0)
+ return;
try {
setLoading(true);
@@ -42,24 +43,24 @@ export const Issue = ({ defaultTitle, defaultBody, issueTitle }) => {
**Device information:**
App version: ${APP_VERSION}
Platform: ${Platform.OS}
-Model: ${Platform.constants.Brand || ''}-${Platform.constants.Model || ''}-${
- Platform.constants.Version || ''
+Model: ${Platform.constants.Brand || ""}-${Platform.constants.Model || ""}-${
+ Platform.constants.Version || ""
}
Pro: ${PremiumService.get()}
-Logged in: ${user ? 'yes' : 'no'}`,
+Logged in: ${user ? "yes" : "no"}`,
userId: user?.id
});
setLoading(false);
eSendEvent(eCloseProgressDialog);
await sleep(300);
presentDialog({
- title: 'Issue reported',
+ title: "Issue reported",
paragraph: (
- You can track your issue at{' '}
+ You can track your issue at{" "}
{
@@ -67,28 +68,28 @@ Logged in: ${user ? 'yes' : 'no'}`,
}}
>
{issue_url}.
- {' '}
- Please note that we will respond to your issue on the given link. We recommend that you
- save it.
+ {" "}
+ Please note that we will respond to your issue on the given link. We
+ recommend that you save it.
),
- positiveText: 'Copy link',
+ positiveText: "Copy link",
positivePress: () => {
Clipboard.setString(issue_url);
ToastEvent.show({
- heading: 'Issue url copied!',
- type: 'success',
- context: 'global'
+ heading: "Issue url copied!",
+ type: "success",
+ context: "global"
});
},
- negativeText: 'Close'
+ negativeText: "Close"
});
} catch (e) {
setLoading(false);
ToastEvent.show({
- heading: 'An error occured',
+ heading: "An error occured",
message: e.message,
- type: 'error'
+ type: "error"
});
}
};
@@ -97,15 +98,15 @@ Logged in: ${user ? 'yes' : 'no'}`,
@@ -113,14 +114,14 @@ Logged in: ${user ? 'yes' : 'no'}`,
(title.current = v)}
+ onChangeText={(v) => (title.current = v)}
defaultValue={title.current}
style={{
borderWidth: 1,
borderColor: colors.nav,
borderRadius: 5,
padding: 12,
- fontFamily: 'OpenSans-Regular',
+ fontFamily: "OpenSans-Regular",
marginBottom: 10,
fontSize: SIZE.md,
color: colors.heading
@@ -138,7 +139,7 @@ For example:
multiline
numberOfLines={5}
textAlignVertical="top"
- onChangeText={v => (body.current = v)}
+ onChangeText={(v) => (body.current = v)}
onLayout={() => {
if (initialLayout.current) return;
initialLayout.current = true;
@@ -157,7 +158,7 @@ For example:
borderColor: colors.nav,
borderRadius: 5,
padding: 12,
- fontFamily: 'OpenSans-Regular',
+ fontFamily: "OpenSans-Regular",
maxHeight: 200,
fontSize: SIZE.sm,
marginBottom: 2.5,
@@ -173,7 +174,7 @@ For example:
- The information above will be publically available at{' '}
+ The information above will be publically available at{" "}
{
- Linking.openURL('https://github.com/streetwriters/notesnook');
+ Linking.openURL("https://github.com/streetwriters/notesnook");
}}
style={{
- textDecorationLine: 'underline',
+ textDecorationLine: "underline",
color: colors.accent
}}
>
github.com/streetwriters/notesnook.
- {' '}
- If you want to ask something in general or need some assistance, we would suggest that you{' '}
+ {" "}
+ If you want to ask something in general or need some assistance, we
+ would suggest that you{" "}
{
try {
- await openLinkInBrowser('https://discord.gg/zQBK97EE22', colors);
+ await openLinkInBrowser("https://discord.gg/zQBK97EE22", colors);
} catch (e) {}
}}
>
diff --git a/apps/mobile/app/components/sheets/manage-tags/index.js b/apps/mobile/app/components/sheets/manage-tags/index.js
index c191d001d..b47d60426 100644
--- a/apps/mobile/app/components/sheets/manage-tags/index.js
+++ b/apps/mobile/app/components/sheets/manage-tags/index.js
@@ -1,24 +1,28 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { ScrollView, View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { useTagStore } from '../../../stores/use-tag-store';
-import { eSubscribeEvent, eUnSubscribeEvent, ToastEvent } from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import { db } from '../../../common/database';
-import { eCloseTagsDialog, eOpenTagsDialog } from '../../../utils/events';
-import { SIZE } from '../../../utils/size';
-import { sleep } from '../../../utils/time';
-import Input from '../../ui/input';
-import { PressableButton } from '../../ui/pressable';
-import SheetWrapper from '../../ui/sheet';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
+import React, { useEffect, useRef, useState } from "react";
+import { ScrollView, View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { useTagStore } from "../../../stores/use-tag-store";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent,
+ ToastEvent
+} from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import { db } from "../../../common/database";
+import { eCloseTagsDialog, eOpenTagsDialog } from "../../../utils/events";
+import { SIZE } from "../../../utils/size";
+import { sleep } from "../../../utils/time";
+import Input from "../../ui/input";
+import { PressableButton } from "../../ui/pressable";
+import SheetWrapper from "../../ui/sheet";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
const ManageTagsSheet = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [visible, setVisible] = useState(false);
const [note, setNote] = useState(null);
- const allTags = useTagStore(state => state.tags);
+ const allTags = useTagStore((state) => state.tags);
const [tags, setTags] = useState([]);
const [query, setQuery] = useState(null);
const inputRef = useRef();
@@ -35,17 +39,17 @@ const ManageTagsSheet = () => {
useEffect(() => {
if (visible) {
- console.log('sorting tags');
+ console.log("sorting tags");
sortTags();
}
}, [allTags, note, query, visible]);
const sortTags = () => {
let _tags = [...allTags];
- _tags = _tags.filter(t => t.type === 'tag');
+ _tags = _tags.filter((t) => t.type === "tag");
_tags = _tags.sort((a, b) => a.title.localeCompare(b.title));
if (query) {
- _tags = _tags.filter(t => t.title.startsWith(query));
+ _tags = _tags.filter((t) => t.title.startsWith(query));
}
if (!note || !note.tags) {
@@ -54,7 +58,7 @@ const ManageTagsSheet = () => {
}
let noteTags = [];
for (let tag of note.tags) {
- let index = _tags.findIndex(t => t.title === tag);
+ let index = _tags.findIndex((t) => t.title === tag);
if (index !== -1) {
noteTags.push(_tags[index]);
_tags.splice(index, 1);
@@ -65,7 +69,7 @@ const ManageTagsSheet = () => {
setTags(combinedTags);
};
- const open = item => {
+ const open = (item) => {
setNote(item);
useTagStore.getState().setTags();
sortTags();
@@ -85,11 +89,11 @@ const ManageTagsSheet = () => {
const onSubmit = async () => {
let _query = query;
- if (!_query || _query === '' || _query.trimStart().length == 0) {
+ if (!_query || _query === "" || _query.trimStart().length == 0) {
ToastEvent.show({
- heading: 'Tag field is empty',
- type: 'error',
- context: 'local'
+ heading: "Tag field is empty",
+ type: "error",
+ context: "local"
});
return;
}
@@ -98,7 +102,7 @@ const ManageTagsSheet = () => {
setNote({ ...note, tags: note.tags ? [...note.tags, tag] : [tag] });
setQuery(null);
inputRef.current?.setNativeProps({
- text: ''
+ text: ""
});
try {
await db.notes.note(note.id).tag(tag);
@@ -106,21 +110,21 @@ const ManageTagsSheet = () => {
setNote(db.notes.note(note.id).data);
} catch (e) {
ToastEvent.show({
- heading: 'Cannot add tag',
- type: 'error',
+ heading: "Cannot add tag",
+ type: "error",
message: e.message,
- context: 'local'
+ context: "local"
});
}
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes',
- 'Notebooks',
- 'Notebook'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes",
+ "Notebooks",
+ "Notebook"
);
};
@@ -139,22 +143,22 @@ const ManageTagsSheet = () => {
>
{
+ onChangeText={(v) => {
setQuery(db.tags.sanitize(v));
}}
onSubmit={onSubmit}
@@ -174,18 +178,18 @@ const ManageTagsSheet = () => {
>
{query && query !== tags[0]?.title ? (
- Add {`"` + '#' + query + `"`}
+ Add {`"` + "#" + query + `"`}
@@ -193,10 +197,10 @@ const ManageTagsSheet = () => {
{!allTags || allTags.length === 0 ? (
@@ -208,8 +212,13 @@ const ManageTagsSheet = () => {
) : null}
- {tags.map(item => (
-
+ {tags.map((item) => (
+
))}
@@ -220,13 +229,15 @@ const ManageTagsSheet = () => {
export default ManageTagsSheet;
const TagItem = ({ tag, note, setNote }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const onPress = async () => {
let prevNote = { ...note };
try {
if (prevNote.tags.indexOf(tag.title) !== -1) {
- await db.notes.note(note.id).untag(prevNote.tags[prevNote.tags.indexOf(tag.title)]);
+ await db.notes
+ .note(note.id)
+ .untag(prevNote.tags[prevNote.tags.indexOf(tag.title)]);
} else {
await db.notes.note(note.id).tag(tag.title);
}
@@ -235,11 +246,11 @@ const TagItem = ({ tag, note, setNote }) => {
} catch (e) {}
setTimeout(() => {
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes"
);
}, 1);
};
@@ -247,26 +258,38 @@ const TagItem = ({ tag, note, setNote }) => {
return (
t === tag.title) !== -1 ? 'shade' : 'grayBg'}
+ type={
+ note && note.tags.findIndex((t) => t === tag.title) !== -1
+ ? "shade"
+ : "grayBg"
+ }
>
t === tag.title) !== -1 ? colors.accent : colors.pri
+ note && note?.tags.findIndex((t) => t === tag.title) !== -1
+ ? colors.accent
+ : colors.pri
}
>
- {'#' + tag.title}
+ {"#" + tag.title}
t === tag.title) !== -1 ? 'minus' : 'plus'}
+ name={
+ note && note?.tags.findIndex((t) => t === tag.title) !== -1
+ ? "minus"
+ : "plus"
+ }
color={
- note && note?.tags.findIndex(t => t === tag.title) !== -1 ? colors.accent : colors.accent
+ note && note?.tags.findIndex((t) => t === tag.title) !== -1
+ ? colors.accent
+ : colors.accent
}
size={SIZE.lg}
/>
diff --git a/apps/mobile/app/components/sheets/migrate/index.tsx b/apps/mobile/app/components/sheets/migrate/index.tsx
index 6f1ab1b9e..96281be33 100644
--- a/apps/mobile/app/components/sheets/migrate/index.tsx
+++ b/apps/mobile/app/components/sheets/migrate/index.tsx
@@ -1,22 +1,25 @@
-import React, { useState } from 'react';
-import { View } from 'react-native';
-import BackupService from '../../../services/backup';
-import { eSendEvent, ToastEvent } from '../../../services/event-manager';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { db } from '../../../common/database';
-import { eCloseProgressDialog, eCloseSimpleDialog } from '../../../utils/events';
-import { sleep } from '../../../utils/time';
-import { Dialog } from '../../dialog';
-import DialogHeader from '../../dialog/dialog-header';
-import { Button } from '../../ui/button';
-import { Notice } from '../../ui/notice';
-import Seperator from '../../ui/seperator';
-import { ProgressBarComponent } from '../../ui/svg/lazy';
-import Paragraph from '../../ui/typography/paragraph';
-import { presentDialog } from '../../dialog/functions';
+import React, { useState } from "react";
+import { View } from "react-native";
+import BackupService from "../../../services/backup";
+import { eSendEvent, ToastEvent } from "../../../services/event-manager";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { db } from "../../../common/database";
+import {
+ eCloseProgressDialog,
+ eCloseSimpleDialog
+} from "../../../utils/events";
+import { sleep } from "../../../utils/time";
+import { Dialog } from "../../dialog";
+import DialogHeader from "../../dialog/dialog-header";
+import { Button } from "../../ui/button";
+import { Notice } from "../../ui/notice";
+import Seperator from "../../ui/seperator";
+import { ProgressBarComponent } from "../../ui/svg/lazy";
+import Paragraph from "../../ui/typography/paragraph";
+import { presentDialog } from "../../dialog/functions";
export default function Migrate() {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [loading, setLoading] = useState(false);
return (
@@ -29,7 +32,7 @@ export default function Migrate() {
@@ -51,8 +54,8 @@ If you face any other issues or are unsure about what to do, feel free to reach
style={{
width: 200,
height: 100,
- alignSelf: 'center',
- justifyContent: 'center'
+ alignSelf: "center",
+ justifyContent: "center"
}}
>
Migration in progress... please wait
@@ -83,12 +86,13 @@ If you face any other issues or are unsure about what to do, feel free to reach
width={250}
onPress={async () => {
setLoading(true);
- const backupSaved = await BackupService.run(false, 'local');
+ const backupSaved = await BackupService.run(false, "local");
if (!backupSaved) {
ToastEvent.show({
- heading: 'Migration failed',
- message: 'You must download a backup of your data before migrating.',
- context: 'local'
+ heading: "Migration failed",
+ message:
+ "You must download a backup of your data before migrating.",
+ context: "local"
});
setLoading(false);
}
@@ -97,11 +101,11 @@ If you face any other issues or are unsure about what to do, feel free to reach
setLoading(false);
await sleep(500);
presentDialog({
- title: 'Migration successful',
+ title: "Migration successful",
paragraph:
- 'Your data has been migrated. If you face any issues after the migration please reach out to us via email or Discord.',
- context: 'global',
- negativeText: 'Ok'
+ "Your data has been migrated. If you face any issues after the migration please reach out to us via email or Discord.",
+ context: "global",
+ negativeText: "Ok"
});
}}
style={{
diff --git a/apps/mobile/app/components/sheets/move-notes/movenote.tsx b/apps/mobile/app/components/sheets/move-notes/movenote.tsx
index 104b1a731..c206b7767 100644
--- a/apps/mobile/app/components/sheets/move-notes/movenote.tsx
+++ b/apps/mobile/app/components/sheets/move-notes/movenote.tsx
@@ -1,23 +1,27 @@
-import React, { RefObject, useState } from 'react';
-import { Platform, View } from 'react-native';
-import ActionSheet from 'react-native-actions-sheet';
-import { FlatList } from 'react-native-gesture-handler';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { eSendEvent, presentSheet, ToastEvent } from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import { db } from '../../../common/database';
-import { eCloseProgressDialog } from '../../../utils/events';
-import { SIZE } from '../../../utils/size';
-import { IconButton } from '../../ui/icon-button';
-import { Button } from '../../ui/button';
-import { Dialog } from '../../dialog';
-import DialogHeader from '../../dialog/dialog-header';
-import { presentDialog } from '../../dialog/functions';
-import { PressableButton } from '../../ui/pressable';
-import Seperator from '../../ui/seperator';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
-import SearchService from '../../../services/search';
+import React, { RefObject, useState } from "react";
+import { Platform, View } from "react-native";
+import ActionSheet from "react-native-actions-sheet";
+import { FlatList } from "react-native-gesture-handler";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import {
+ eSendEvent,
+ presentSheet,
+ ToastEvent
+} from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import { db } from "../../../common/database";
+import { eCloseProgressDialog } from "../../../utils/events";
+import { SIZE } from "../../../utils/size";
+import { IconButton } from "../../ui/icon-button";
+import { Button } from "../../ui/button";
+import { Dialog } from "../../dialog";
+import DialogHeader from "../../dialog/dialog-header";
+import { presentDialog } from "../../dialog/functions";
+import { PressableButton } from "../../ui/pressable";
+import Seperator from "../../ui/seperator";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
+import SearchService from "../../../services/search";
export const MoveNotes = ({
notebook,
@@ -28,7 +32,7 @@ export const MoveNotes = ({
selectedTopic?: any;
fwdRef: RefObject;
}) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [currentNotebook, setCurrentNotebook] = useState(notebook);
let notes = db.notes?.all;
@@ -36,18 +40,18 @@ export const MoveNotes = ({
const [selectedNoteIds, setSelectedNoteIds] = useState([]);
const [topic, setTopic] = useState(selectedTopic);
//@ts-ignore
- notes = notes.filter(note => topic?.notes.indexOf(note.id) === -1);
+ notes = notes.filter((note) => topic?.notes.indexOf(note.id) === -1);
const select = (id: string) => {
let index = selectedNoteIds.indexOf(id);
if (index > -1) {
- setSelectedNoteIds(selectedNoteIds => {
+ setSelectedNoteIds((selectedNoteIds) => {
let next = [...selectedNoteIds];
next.splice(index, 1);
return next;
});
} else {
- setSelectedNoteIds(selectedNoteIds => {
+ setSelectedNoteIds((selectedNoteIds) => {
let next = [...selectedNoteIds];
next.push(id);
return next;
@@ -58,13 +62,13 @@ export const MoveNotes = ({
const openAddTopicDialog = () => {
presentDialog({
//@ts-ignore
- context: 'local',
+ context: "local",
input: true,
- inputPlaceholder: 'Enter title',
- title: 'New topic',
- paragraph: 'Add a new topic in ' + currentNotebook.title,
- positiveText: 'Add',
- positivePress: value => {
+ inputPlaceholder: "Enter title",
+ title: "New topic",
+ paragraph: "Add a new topic in " + currentNotebook.title,
+ positiveText: "Add",
+ positivePress: (value) => {
return addNewTopic(value);
}
});
@@ -74,9 +78,9 @@ export const MoveNotes = ({
if (!value || value.trim().length === 0) {
//@ts-ignore
ToastEvent.show({
- heading: 'Topic title is required',
- type: 'error',
- context: 'local'
+ heading: "Topic title is required",
+ type: "error",
+ context: "local"
});
return false;
}
@@ -84,13 +88,13 @@ export const MoveNotes = ({
setCurrentNotebook(db.notebooks?.notebook(currentNotebook.id).data);
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes',
- 'Notebook',
- 'Notebooks'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes",
+ "Notebook",
+ "Notebooks"
);
return true;
};
@@ -100,18 +104,18 @@ export const MoveNotes = ({
{
- if (item.type == 'topic') {
+ if (item.type == "topic") {
setTopic(topic ? null : item);
} else {
select(item.id);
}
}}
- type={'transparent'}
+ type={"transparent"}
customStyle={{
paddingVertical: 12,
- justifyContent: 'space-between',
+ justifyContent: "space-between",
paddingHorizontal: 12,
- flexDirection: 'row'
+ flexDirection: "row"
}}
>
-
+
{item.title}
- {item.type == 'note' && item.headline ? (
+ {item.type == "note" && item.headline ? (
{item.headline}
) : null}
- {item.type === 'topic' ? (
+ {item.type === "topic" ? (
@@ -174,30 +181,32 @@ export const MoveNotes = ({
}}
customStyle={{
paddingVertical: 12,
- justifyContent: 'space-between',
+ justifyContent: "space-between",
paddingHorizontal: 12,
marginBottom: 10,
- alignItems: 'flex-start'
+ alignItems: "flex-start"
}}
type="grayBg"
>
- Adding notes to {currentNotebook.title}
+
+ Adding notes to {currentNotebook.title}
+
@@ -219,7 +228,7 @@ export const MoveNotes = ({
paragraph={
topic
? `Select notes you would like to move to ${topic.title}.`
- : 'Select the topic in which you would like to move notes.'
+ : "Select the topic in which you would like to move notes."
}
/>
@@ -235,12 +244,12 @@ export const MoveNotes = ({
- {topic ? 'No notes to show' : 'No topics in this notebook'}
+ {topic ? "No notes to show" : "No topics in this notebook"}
{!topic && (
@@ -273,13 +282,13 @@ export const MoveNotes = ({
...selectedNoteIds
);
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes',
- 'Notebook',
- 'Notebooks'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes",
+ "Notebook",
+ "Notebooks"
);
SearchService.updateAndSearch();
eSendEvent(eCloseProgressDialog);
diff --git a/apps/mobile/app/components/sheets/new-feature/index.tsx b/apps/mobile/app/components/sheets/new-feature/index.tsx
index 0263e3627..77cae5d10 100644
--- a/apps/mobile/app/components/sheets/new-feature/index.tsx
+++ b/apps/mobile/app/components/sheets/new-feature/index.tsx
@@ -1,29 +1,29 @@
-import React from 'react';
-import { Platform, View } from 'react-native';
-import { APP_VERSION } from '../../../version';
-import { eSendEvent, presentSheet } from '../../../services/event-manager';
-import SettingsService from '../../../services/settings';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { eCloseProgressDialog } from '../../../utils/events';
-import { SIZE } from '../../../utils/size';
-import { Button } from '../../ui/button';
-import Seperator from '../../ui/seperator';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
-import { features } from '../../../features';
+import React from "react";
+import { Platform, View } from "react-native";
+import { APP_VERSION } from "../../../version";
+import { eSendEvent, presentSheet } from "../../../services/event-manager";
+import SettingsService from "../../../services/settings";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { eCloseProgressDialog } from "../../../utils/events";
+import { SIZE } from "../../../utils/size";
+import { Button } from "../../ui/button";
+import Seperator from "../../ui/seperator";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
+import { features } from "../../../features";
export type FeatureType = {
title: string;
body: string;
- platform?: 'ios' | 'android';
+ platform?: "ios" | "android";
};
const NewFeature = ({ features }: { features: FeatureType[] }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
{
- {features.map(item => (
+ {features.map((item) => (
@@ -79,7 +79,7 @@ NewFeature.present = () => {
version: APP_VERSION
});
let _features = features?.filter(
- feature => !feature.platform || feature.platform === Platform.OS
+ (feature) => !feature.platform || feature.platform === Platform.OS
);
if (_features.length === 0) return;
presentSheet({
diff --git a/apps/mobile/app/components/sheets/progress/index.tsx b/apps/mobile/app/components/sheets/progress/index.tsx
index 730e2faba..754cdd934 100644
--- a/apps/mobile/app/components/sheets/progress/index.tsx
+++ b/apps/mobile/app/components/sheets/progress/index.tsx
@@ -1,23 +1,23 @@
-import React, { useEffect, useState } from 'react';
-import { View } from 'react-native';
-import { presentSheet } from '../../../services/event-manager';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import useSyncProgress from '../../../hooks/use-sync-progress';
-import { SIZE } from '../../../utils/size';
-import Seperator from '../../ui/seperator';
-import { ProgressBarComponent } from '../../ui/svg/lazy';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
+import React, { useEffect, useState } from "react";
+import { View } from "react-native";
+import { presentSheet } from "../../../services/event-manager";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import useSyncProgress from "../../../hooks/use-sync-progress";
+import { SIZE } from "../../../utils/size";
+import Seperator from "../../ui/seperator";
+import { ProgressBarComponent } from "../../ui/svg/lazy";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
export const Progress = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const { progress } = useSyncProgress();
const [currentProgress, setCurrentProgress] = useState(0.1);
useEffect(() => {
let nextProgress = progress ? progress?.current / progress?.total : 0.1;
- setCurrentProgress(currentProgress => {
+ setCurrentProgress((currentProgress) => {
if (currentProgress > nextProgress) return currentProgress;
return progress ? progress?.current / progress?.total : 0.1;
});
@@ -26,9 +26,9 @@ export const Progress = () => {
return (
{
{progress ? (
- {progress.type?.slice(0, 1).toUpperCase() + progress.type?.slice(1)}ing{' '}
- {progress?.current}/{progress?.total}
+ {progress.type?.slice(0, 1).toUpperCase() + progress.type?.slice(1)}
+ ing {progress?.current}/{progress?.total}
) : null}
@@ -67,6 +67,6 @@ Progress.present = () => {
presentSheet({
component: ,
disableClosing: true,
- context: 'sync_progress'
+ context: "sync_progress"
});
};
diff --git a/apps/mobile/app/components/sheets/publish-note/index.js b/apps/mobile/app/components/sheets/publish-note/index.js
index 3e3a8c1b5..d1eec4084 100644
--- a/apps/mobile/app/components/sheets/publish-note/index.js
+++ b/apps/mobile/app/components/sheets/publish-note/index.js
@@ -1,37 +1,45 @@
-import Clipboard from '@react-native-clipboard/clipboard';
-import React, { useEffect, useRef, useState } from 'react';
-import { ActivityIndicator, TouchableOpacity, View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { useAttachmentStore } from '../../../stores/use-attachment-store';
-import { eSubscribeEvent, eUnSubscribeEvent, ToastEvent } from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import { db } from '../../../common/database';
-import { eClosePublishNoteDialog, eOpenPublishNoteDialog } from '../../../utils/events';
-import { openLinkInBrowser } from '../../../utils/functions';
-import { SIZE } from '../../../utils/size';
-import DialogHeader from '../../dialog/dialog-header';
-import { Button } from '../../ui/button';
-import { IconButton } from '../../ui/icon-button';
-import Input from '../../ui/input';
-import Seperator from '../../ui/seperator';
-import SheetWrapper from '../../ui/sheet';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
-import SearchService from '../../../services/search';
+import Clipboard from "@react-native-clipboard/clipboard";
+import React, { useEffect, useRef, useState } from "react";
+import { ActivityIndicator, TouchableOpacity, View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { useAttachmentStore } from "../../../stores/use-attachment-store";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent,
+ ToastEvent
+} from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import { db } from "../../../common/database";
+import {
+ eClosePublishNoteDialog,
+ eOpenPublishNoteDialog
+} from "../../../utils/events";
+import { openLinkInBrowser } from "../../../utils/functions";
+import { SIZE } from "../../../utils/size";
+import DialogHeader from "../../dialog/dialog-header";
+import { Button } from "../../ui/button";
+import { IconButton } from "../../ui/icon-button";
+import Input from "../../ui/input";
+import Seperator from "../../ui/seperator";
+import SheetWrapper from "../../ui/sheet";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
+import SearchService from "../../../services/search";
let passwordValue = null;
const PublishNoteSheet = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [visible, setVisible] = useState(false);
const actionSheetRef = useRef();
- const loading = useAttachmentStore(state => state.loading);
+ const loading = useAttachmentStore((state) => state.loading);
const [selfDestruct, setSelfDestruct] = useState(false);
const [isLocked, setIsLocked] = useState(false);
const [note, setNote] = useState(null);
const [publishing, setPublishing] = useState(false);
const publishUrl =
- note && `https://monograph.notesnook.com/${db?.monographs.monograph(note?.id)}`;
+ note &&
+ `https://monograph.notesnook.com/${db?.monographs.monograph(note?.id)}`;
const isPublished = note && db?.monographs.isPublished(note?.id);
const pwdInput = useRef();
@@ -44,7 +52,7 @@ const PublishNoteSheet = () => {
};
}, []);
- const open = item => {
+ const open = (item) => {
setNote(item);
setPublishing(false);
setSelfDestruct(false);
@@ -77,19 +85,19 @@ const PublishNoteSheet = () => {
});
setNote(db.notes.note(note.id)?.data);
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes"
);
}
} catch (e) {
ToastEvent.show({
- heading: 'Could not publish note',
+ heading: "Could not publish note",
message: e.message,
- type: 'error',
- context: 'local'
+ type: "error",
+ context: "local"
});
}
@@ -104,19 +112,19 @@ const PublishNoteSheet = () => {
await db.monographs.unpublish(note.id);
setNote(db.notes.note(note.id)?.data);
Navigation.queueRoutesForUpdate(
- 'Notes',
- 'Favorites',
- 'ColoredNotes',
- 'TaggedNotes',
- 'TopicNotes'
+ "Notes",
+ "Favorites",
+ "ColoredNotes",
+ "TaggedNotes",
+ "TopicNotes"
);
}
} catch (e) {
ToastEvent.show({
- heading: 'Could not unpublish note',
+ heading: "Could not unpublish note",
message: e.message,
- type: 'error',
- context: 'local'
+ type: "error",
+ context: "local"
});
}
actionSheetRef.current?.hide();
@@ -136,35 +144,38 @@ const PublishNoteSheet = () => {
>
{publishing ? (
Please wait...
- {loading && `\nDownloading attachments (${loading?.current / loading?.total})`}
+ {loading &&
+ `\nDownloading attachments (${
+ loading?.current / loading?.total
+ })`}
) : (
@@ -172,8 +183,8 @@ const PublishNoteSheet = () => {
{isPublished && (
{
>
@@ -202,7 +213,8 @@ const PublishNoteSheet = () => {
color: colors.pri
}}
>
- Open in browser
+ Open in
+ browser
@@ -210,9 +222,9 @@ const PublishNoteSheet = () => {
onPress={() => {
Clipboard.setString(publishUrl);
ToastEvent.show({
- heading: 'Note publish url copied',
- type: 'success',
- context: 'local'
+ heading: "Note publish url copied",
+ type: "success",
+ context: "local"
});
}}
color={colors.accent}
@@ -230,8 +242,8 @@ const PublishNoteSheet = () => {
}}
activeOpacity={0.9}
style={{
- flexDirection: 'row',
- alignItems: 'center',
+ flexDirection: "row",
+ alignItems: "center",
marginBottom: 10
}}
>
@@ -242,18 +254,23 @@ const PublishNoteSheet = () => {
}}
color={isLocked ? colors.accent : colors.icon}
size={SIZE.lg}
- name={isLocked ? 'check-circle-outline' : 'checkbox-blank-circle-outline'}
+ name={
+ isLocked
+ ? "check-circle-outline"
+ : "checkbox-blank-circle-outline"
+ }
/>
Password protection
- Published note can only be viewed by someone with the password.
+ Published note can only be viewed by someone with the
+ password.
@@ -264,8 +281,8 @@ const PublishNoteSheet = () => {
}}
activeOpacity={0.9}
style={{
- flexDirection: 'row',
- alignItems: 'center'
+ flexDirection: "row",
+ alignItems: "center"
}}
>
{
}}
color={selfDestruct ? colors.accent : colors.icon}
size={SIZE.lg}
- name={selfDestruct ? 'check-circle-outline' : 'checkbox-blank-circle-outline'}
+ name={
+ selfDestruct
+ ? "check-circle-outline"
+ : "checkbox-blank-circle-outline"
+ }
/>
Self destruct
- Published note link will be automatically deleted once it is viewed by someone.
+ Published note link will be automatically deleted once it is
+ viewed by someone.
@@ -301,7 +323,7 @@ const PublishNoteSheet = () => {
<>
(passwordValue = value)}
+ onChangeText={(value) => (passwordValue = value)}
blurOnSubmit
secureTextEntry
defaultValue={passwordValue}
@@ -320,7 +342,7 @@ const PublishNoteSheet = () => {
}}
height={50}
type="accent"
- title={isPublished ? 'Update published note' : 'Publish note'}
+ title={isPublished ? "Update published note" : "Publish note"}
/>
{isPublished && (
@@ -344,13 +366,16 @@ const PublishNoteSheet = () => {
color={colors.icon}
size={SIZE.xs}
style={{
- textAlign: 'center',
+ textAlign: "center",
marginTop: 5,
- textDecorationLine: 'underline'
+ textDecorationLine: "underline"
}}
onPress={async () => {
try {
- await openLinkInBrowser('https://docs.notesnook.com/monographs/', colors.accent);
+ await openLinkInBrowser(
+ "https://docs.notesnook.com/monographs/",
+ colors.accent
+ );
} catch (e) {}
}}
>
diff --git a/apps/mobile/app/components/sheets/rate-app/index.js b/apps/mobile/app/components/sheets/rate-app/index.js
index c23a190a5..c512bb0d4 100644
--- a/apps/mobile/app/components/sheets/rate-app/index.js
+++ b/apps/mobile/app/components/sheets/rate-app/index.js
@@ -1,16 +1,19 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { Linking, View } from 'react-native';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../../services/event-manager';
-import { clearMessage } from '../../../services/message';
-import SettingsService from '../../../services/settings';
-import { STORE_LINK } from '../../../utils/constants';
-import { eCloseRateDialog, eOpenRateDialog } from '../../../utils/events';
-import { SIZE } from '../../../utils/size';
-import { Button } from '../../ui/button';
-import Seperator from '../../ui/seperator';
-import SheetWrapper from '../../ui/sheet';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
+import React, { useEffect, useRef, useState } from "react";
+import { Linking, View } from "react-native";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../../services/event-manager";
+import { clearMessage } from "../../../services/message";
+import SettingsService from "../../../services/settings";
+import { STORE_LINK } from "../../../utils/constants";
+import { eCloseRateDialog, eOpenRateDialog } from "../../../utils/events";
+import { SIZE } from "../../../utils/size";
+import { Button } from "../../ui/button";
+import Seperator from "../../ui/seperator";
+import SheetWrapper from "../../ui/sheet";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
const RateAppSheet = () => {
const [visible, setVisible] = useState(false);
@@ -59,15 +62,15 @@ const RateAppSheet = () => {
Do you enjoy using Notesnook?
- It took us a year to bring Notesnook to life. Share your experience and suggestions to
- help us improve it.
+ It took us a year to bring Notesnook to life. Share your experience
+ and suggestions to help us improve it.
@@ -81,12 +84,12 @@ const RateAppSheet = () => {
/>
{
+ open = (signup) => {
if (signup) {
this.signup = true;
}
@@ -54,10 +58,10 @@ class RecoveryKeySheet extends React.Component {
close = () => {
if (this.tapCount === 0) {
ToastEvent.show({
- heading: 'Did you save recovery key?',
- message: 'Tap one more time to confirm.',
- type: 'success',
- context: 'local'
+ heading: "Did you save recovery key?",
+ message: "Tap one more time to confirm.",
+ type: "success",
+ context: "local"
});
this.tapCount++;
return;
@@ -89,25 +93,31 @@ class RecoveryKeySheet extends React.Component {
}
saveQRCODE = async () => {
- this.svg.current?.toDataURL(async data => {
+ this.svg.current?.toDataURL(async (data) => {
try {
let path;
- RNFetchBlob = require('rn-fetch-blob').default;
- let fileName = 'nn_' + this.user.email + '_recovery_key_qrcode';
- fileName = sanitizeFilename(fileName, { replacement: '_' });
- fileName = fileName + '.png';
+ RNFetchBlob = require("rn-fetch-blob").default;
+ let fileName = "nn_" + this.user.email + "_recovery_key_qrcode";
+ fileName = sanitizeFilename(fileName, { replacement: "_" });
+ fileName = fileName + ".png";
- if (Platform.OS === 'android') {
- await ScopedStorage.createDocument(fileName, 'image/png', data, 'base64');
+ if (Platform.OS === "android") {
+ await ScopedStorage.createDocument(
+ fileName,
+ "image/png",
+ data,
+ "base64"
+ );
} else {
- path = await Storage.checkAndCreateDir('/');
- await RNFetchBlob.fs.writeFile(path + fileName, data, 'base64');
+ path = await Storage.checkAndCreateDir("/");
+ await RNFetchBlob.fs.writeFile(path + fileName, data, "base64");
}
ToastEvent.show({
- heading: 'Recovery key QR-Code saved',
- message: 'QR-Code image has been saved to Gallery at ' + path + fileName,
- type: 'success',
- context: 'local'
+ heading: "Recovery key QR-Code saved",
+ message:
+ "QR-Code image has been saved to Gallery at " + path + fileName,
+ type: "success",
+ context: "local"
});
} catch (e) {}
});
@@ -116,31 +126,31 @@ class RecoveryKeySheet extends React.Component {
saveToTextFile = async () => {
try {
let path;
- let fileName = 'nn_' + this.user?.email + '_recovery_key';
- fileName = sanitizeFilename(fileName, { replacement: '_' });
- fileName = fileName + '.txt';
+ let fileName = "nn_" + this.user?.email + "_recovery_key";
+ fileName = sanitizeFilename(fileName, { replacement: "_" });
+ fileName = fileName + ".txt";
- RNFetchBlob = require('rn-fetch-blob').default;
- if (Platform.OS === 'android') {
+ RNFetchBlob = require("rn-fetch-blob").default;
+ if (Platform.OS === "android") {
let file = await ScopedStorage.createDocument(
fileName,
- 'text/plain',
+ "text/plain",
this.state.key,
- 'utf8'
+ "utf8"
);
if (!file) return;
path = file.uri;
} else {
- path = await Storage.checkAndCreateDir('/');
- await RNFetchBlob.fs.writeFile(path + fileName, this.state.key, 'utf8');
+ path = await Storage.checkAndCreateDir("/");
+ await RNFetchBlob.fs.writeFile(path + fileName, this.state.key, "utf8");
path = path + fileName;
}
ToastEvent.show({
- heading: 'Recovery key text file saved',
- message: 'Recovery key saved in text file.',
- type: 'success',
- context: 'local'
+ heading: "Recovery key text file saved",
+ message: "Recovery key saved in text file.",
+ type: "success",
+ context: "local"
});
return path;
} catch (e) {
@@ -162,9 +172,9 @@ class RecoveryKeySheet extends React.Component {
let path = await this.saveToTextFile();
if (!path) return;
try {
- if (Platform.OS === 'ios') {
+ if (Platform.OS === "ios") {
Share.open({
- url: 'file:/' + path,
+ url: "file:/" + path,
failOnCancel: false
}).catch(console.log);
} else {
@@ -189,9 +199,9 @@ class RecoveryKeySheet extends React.Component {
>
{this.state.key}
@@ -230,12 +240,12 @@ class RecoveryKeySheet extends React.Component {
{
Clipboard.setString(this.state.key);
ToastEvent.show({
- heading: 'Recovery key copied!',
- type: 'success',
- context: 'local'
+ heading: "Recovery key copied!",
+ type: "success",
+ context: "local"
});
}}
icon="content-copy"
@@ -305,10 +315,10 @@ class RecoveryKeySheet extends React.Component {
size={SIZE.sm}
numberOfLines={2}
style={{
- width: '100%',
- maxWidth: '100%',
+ width: "100%",
+ maxWidth: "100%",
marginBottom: 5,
- textAlign: 'center'
+ textAlign: "center"
}}
>
Tap twice to confirm you have saved the recovery key.
diff --git a/apps/mobile/app/components/sheets/restore-data/index.js b/apps/mobile/app/components/sheets/restore-data/index.js
index c46825658..3ab12e354 100644
--- a/apps/mobile/app/components/sheets/restore-data/index.js
+++ b/apps/mobile/app/components/sheets/restore-data/index.js
@@ -1,26 +1,30 @@
-import React, { createRef, useEffect, useState } from 'react';
-import { ActivityIndicator, Platform, View } from 'react-native';
-import DocumentPicker from 'react-native-document-picker';
-import { FlatList } from 'react-native-gesture-handler';
-import * as ScopedStorage from 'react-native-scoped-storage';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { initialize } from '../../../stores';
-import { eSubscribeEvent, eUnSubscribeEvent, ToastEvent } from '../../../services/event-manager';
-import { db } from '../../../common/database';
-import { MMKV } from '../../../common/database/mmkv';
-import storage from '../../../common/database/storage';
-import { eCloseRestoreDialog, eOpenRestoreDialog } from '../../../utils/events';
-import { SIZE } from '../../../utils/size';
-import { sleep, timeConverter } from '../../../utils/time';
-import { Dialog } from '../../dialog';
-import DialogHeader from '../../dialog/dialog-header';
-import { presentDialog } from '../../dialog/functions';
-import { Toast } from '../../toast';
-import { Button } from '../../ui/button';
-import Seperator from '../../ui/seperator';
-import SheetWrapper from '../../ui/sheet';
-import Paragraph from '../../ui/typography/paragraph';
-import SettingsService from '../../../services/settings';
+import React, { createRef, useEffect, useState } from "react";
+import { ActivityIndicator, Platform, View } from "react-native";
+import DocumentPicker from "react-native-document-picker";
+import { FlatList } from "react-native-gesture-handler";
+import * as ScopedStorage from "react-native-scoped-storage";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { initialize } from "../../../stores";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent,
+ ToastEvent
+} from "../../../services/event-manager";
+import { db } from "../../../common/database";
+import { MMKV } from "../../../common/database/mmkv";
+import storage from "../../../common/database/storage";
+import { eCloseRestoreDialog, eOpenRestoreDialog } from "../../../utils/events";
+import { SIZE } from "../../../utils/size";
+import { sleep, timeConverter } from "../../../utils/time";
+import { Dialog } from "../../dialog";
+import DialogHeader from "../../dialog/dialog-header";
+import { presentDialog } from "../../dialog/functions";
+import { Toast } from "../../toast";
+import { Button } from "../../ui/button";
+import Seperator from "../../ui/seperator";
+import SheetWrapper from "../../ui/sheet";
+import Paragraph from "../../ui/typography/paragraph";
+import SettingsService from "../../../services/settings";
const actionSheetRef = createRef();
let RNFetchBlob;
@@ -55,10 +59,10 @@ const RestoreDataSheet = () => {
const showIsWorking = () => {
ToastEvent.show({
- heading: 'Restoring Backup',
- message: 'Your backup data is being restored. please wait.',
- type: 'error',
- context: 'local'
+ heading: "Restoring Backup",
+ message: "Your backup data is being restored. please wait.",
+ type: "error",
+ context: "local"
});
};
@@ -69,7 +73,11 @@ const RestoreDataSheet = () => {
closeOnTouchBackdrop={!restoring}
onClose={close}
>
-
+
);
@@ -78,7 +86,7 @@ const RestoreDataSheet = () => {
export default RestoreDataSheet;
const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [files, setFiles] = useState([]);
const [loading, setLoading] = useState(true);
const [backupDirectoryAndroid, setBackupDirectoryAndroid] = useState(false);
@@ -93,33 +101,33 @@ const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
}
try {
setRestoring(true);
- let prefix = Platform.OS === 'ios' ? '' : 'file:/';
+ let prefix = Platform.OS === "ios" ? "" : "file:/";
let backup;
- if (Platform.OS === 'android') {
- backup = await ScopedStorage.readFile(item.uri, 'utf8');
+ if (Platform.OS === "android") {
+ backup = await ScopedStorage.readFile(item.uri, "utf8");
} else {
- backup = await RNFetchBlob.fs.readFile(prefix + item.path, 'utf8');
+ backup = await RNFetchBlob.fs.readFile(prefix + item.path, "utf8");
}
backup = JSON.parse(backup);
- console.log('backup encrypted:', backup.data.iv && backup.data.salt);
+ console.log("backup encrypted:", backup.data.iv && backup.data.salt);
if (backup.data.iv && backup.data.salt) {
withPassword(
- async value => {
+ async (value) => {
try {
- console.log('password for backup:', value);
+ console.log("password for backup:", value);
await restoreBackup(backup, value);
close();
setRestoring(false);
return true;
} catch (e) {
backupError(e);
- console.log('return false');
+ console.log("return false");
return false;
}
},
() => {
- console.log('closed');
+ console.log("closed");
setRestoring(false);
}
);
@@ -135,24 +143,24 @@ const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
const withPassword = (onsubmit, onclose = () => {}) => {
presentDialog({
- context: 'local',
- title: 'Encrypted backup',
+ context: "local",
+ title: "Encrypted backup",
input: true,
- inputPlaceholder: 'Password',
- paragraph: 'Please enter password of this backup file to restore it',
- positiveText: 'Restore',
+ inputPlaceholder: "Password",
+ paragraph: "Please enter password of this backup file to restore it",
+ positiveText: "Restore",
secureTextEntry: true,
onClose: onclose,
- negativeText: 'Cancel',
- positivePress: async password => {
+ negativeText: "Cancel",
+ positivePress: async (password) => {
try {
return await onsubmit(password);
} catch (e) {
ToastEvent.show({
- heading: 'Failed to backup data',
+ heading: "Failed to backup data",
message: e.message,
- type: 'error',
- context: 'global'
+ type: "error",
+ context: "global"
});
return false;
}
@@ -163,7 +171,7 @@ const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
const checkBackups = async () => {
try {
let files = [];
- if (Platform.OS === 'android') {
+ if (Platform.OS === "android") {
let backupDirectory = SettingsService.get().backupDirectoryAndroid;
if (backupDirectory) {
setBackupDirectoryAndroid(backupDirectory);
@@ -173,8 +181,8 @@ const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
return;
}
} else {
- RNFetchBlob = require('rn-fetch-blob').default;
- let path = await storage.checkAndCreateDir('/backups/');
+ RNFetchBlob = require("rn-fetch-blob").default;
+ let path = await storage.checkAndCreateDir("/backups/");
files = await RNFetchBlob.fs.lstat(path);
}
files = files.sort(function (a, b) {
@@ -196,25 +204,25 @@ const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
-
+
{timeConverter(item?.lastModified * 1)}
- {(item.filename || item.name).replace('.nnbackup', '')}
+ {(item.filename || item.name).replace(".nnbackup", "")}
{
);
const restoreBackup = async (backup, password) => {
- console.log(password, 'password');
+ console.log(password, "password");
await db.backup.import(backup, password);
setRestoring(false);
initialize();
ToastEvent.show({
- heading: 'Backup restored successfully.',
- type: 'success',
- context: 'global'
+ heading: "Backup restored successfully.",
+ type: "success",
+ context: "global"
});
};
- const backupError = e => {
+ const backupError = (e) => {
ToastEvent.show({
- heading: 'Restore failed',
+ heading: "Restore failed",
message:
e.message ||
- 'The selected backup data file is invalid. You must select a *.nnbackup file to restore.',
- type: 'error',
- context: 'local'
+ "The selected backup data file is invalid. You must select a *.nnbackup file to restore.",
+ type: "error",
+ context: "local"
});
};
const button = {
- title: 'Restore from files',
+ title: "Restore from files",
onPress: () => {
if (restoring) {
return;
}
DocumentPicker.pickSingle()
- .then(r => {
+ .then((r) => {
setRestoring(true);
console.log(r.uri);
fetch(r.uri)
- .then(async r => {
+ .then(async (r) => {
try {
let backup = await r.json();
- console.log('backup encrypted:', backup.data.iv && backup.data.salt);
+ console.log(
+ "backup encrypted:",
+ backup.data.iv && backup.data.salt
+ );
if (backup.data.iv && backup.data.salt) {
withPassword(
- async value => {
+ async (value) => {
try {
await restoreBackup(backup, value);
setRestoring(false);
@@ -285,7 +296,7 @@ const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
}
},
() => {
- console.log('closed');
+ console.log("closed");
setRestoring(false);
}
);
@@ -310,18 +321,20 @@ const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
@@ -337,8 +350,8 @@ const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
loading ? (
@@ -347,23 +360,25 @@ const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
) : (
- {Platform.OS === 'android' && !backupDirectoryAndroid ? (
+ {Platform.OS === "android" && !backupDirectoryAndroid ? (
<>
{
- let folder = await ScopedStorage.openDocumentTree(true);
+ let folder = await ScopedStorage.openDocumentTree(
+ true
+ );
let subfolder;
- if (folder.name !== 'Notesnook backups') {
+ if (folder.name !== "Notesnook backups") {
subfolder = await ScopedStorage.createDirectory(
folder.uri,
- 'Notesnook backups'
+ "Notesnook backups"
);
} else {
subfolder = folder;
@@ -386,14 +401,15 @@ const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
- Select the folder that includes your backup files to list them here.
+ Select the folder that includes your backup files to
+ list them here.
>
) : (
@@ -404,17 +420,19 @@ const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
) : (
- Restoring backup. Please wait.
+
+ Restoring backup. Please wait.
+
)
}
- keyExtractor={item => item.name || item.filename}
+ keyExtractor={(item) => item.name || item.filename}
style={{
paddingHorizontal: 12
}}
diff --git a/apps/mobile/app/components/sheets/sort/index.js b/apps/mobile/app/components/sheets/sort/index.js
index 22aafd748..2bf140c40 100644
--- a/apps/mobile/app/components/sheets/sort/index.js
+++ b/apps/mobile/app/components/sheets/sort/index.js
@@ -1,29 +1,31 @@
-import React, { useState } from 'react';
-import { View } from 'react-native';
-import { eSendEvent } from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { GROUP, SORT } from '../../../utils/constants';
-import { db } from '../../../common/database';
-import { refreshNotesPage } from '../../../utils/events';
-import layoutmanager from '../../../utils/layout-manager';
-import { SIZE } from '../../../utils/size';
-import { Button } from '../../ui/button';
-import Seperator from '../../ui/seperator';
-import Heading from '../../ui/typography/heading';
+import React, { useState } from "react";
+import { View } from "react-native";
+import { eSendEvent } from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { GROUP, SORT } from "../../../utils/constants";
+import { db } from "../../../common/database";
+import { refreshNotesPage } from "../../../utils/events";
+import layoutmanager from "../../../utils/layout-manager";
+import { SIZE } from "../../../utils/size";
+import { Button } from "../../ui/button";
+import Seperator from "../../ui/seperator";
+import Heading from "../../ui/typography/heading";
const Sort = ({ type, screen }) => {
- const colors = useThemeStore(state => state.colors);
- const [groupOptions, setGroupOptions] = useState(db.settings.getGroupOptions(type));
+ const colors = useThemeStore((state) => state.colors);
+ const [groupOptions, setGroupOptions] = useState(
+ db.settings.getGroupOptions(type)
+ );
- const updateGroupOptions = async _groupOptions => {
+ const updateGroupOptions = async (_groupOptions) => {
await db.settings.setGroupOptions(type, _groupOptions);
layoutmanager.withSpringAnimation(600);
setGroupOptions(_groupOptions);
setTimeout(() => {
Navigation.queueRoutesForUpdate(screen);
- eSendEvent('groupOptionsUpdate');
+ eSendEvent("groupOptionsUpdate");
eSendEvent(refreshNotesPage);
}, 1);
};
@@ -31,7 +33,7 @@ const Sort = ({ type, screen }) => {
const setOrderBy = async () => {
let _groupOptions = {
...groupOptions,
- sortDirection: groupOptions.sortDirection === 'asc' ? 'desc' : 'asc'
+ sortDirection: groupOptions.sortDirection === "asc" ? "desc" : "asc"
};
await updateGroupOptions(_groupOptions);
};
@@ -39,23 +41,23 @@ const Sort = ({ type, screen }) => {
return (
Sort by
@@ -63,15 +65,21 @@ const Sort = ({ type, screen }) => {
{
- {groupOptions.groupBy === 'abc' ? (
+ {groupOptions.groupBy === "abc" ? (
) : (
Object.keys(SORT).map((item, index) =>
- item === 'title' && groupOptions.groupBy !== 'none' ? null : (
+ item === "title" && groupOptions.groupBy !== "none" ? null : (
{
let _groupOptions = {
...groupOptions,
- sortBy: type === 'trash' ? 'dateDeleted' : item
+ sortBy: type === "trash" ? "dateDeleted" : item
};
await updateGroupOptions(_groupOptions);
}}
@@ -159,18 +168,21 @@ const Sort = ({ type, screen }) => {
{Object.keys(GROUP).map((item, index) => (
{
let _groupOptions = {
@@ -178,19 +190,19 @@ const Sort = ({ type, screen }) => {
groupBy: GROUP[item]
};
- if (item === 'abc') {
- _groupOptions.sortBy = 'title';
- _groupOptions.sortDirection = 'asc';
+ if (item === "abc") {
+ _groupOptions.sortBy = "title";
+ _groupOptions.sortDirection = "asc";
} else {
- if (groupOptions.sortBy === 'title') {
- _groupOptions.sortBy = 'dateEdited';
- _groupOptions.sortDirection = 'desc';
+ if (groupOptions.sortBy === "title") {
+ _groupOptions.sortBy = "dateEdited";
+ _groupOptions.sortDirection = "desc";
}
}
updateGroupOptions(_groupOptions);
}}
height={40}
- icon={groupOptions.groupBy === GROUP[item] ? 'check' : null}
+ icon={groupOptions.groupBy === GROUP[item] ? "check" : null}
title={item.slice(0, 1).toUpperCase() + item.slice(1, item.length)}
style={{
paddingHorizontal: 8,
diff --git a/apps/mobile/app/components/sheets/update/index.js b/apps/mobile/app/components/sheets/update/index.js
index 83bb81112..28a5942ec 100644
--- a/apps/mobile/app/components/sheets/update/index.js
+++ b/apps/mobile/app/components/sheets/update/index.js
@@ -1,35 +1,35 @@
-import React, { useEffect, useState } from 'react';
-import { ActivityIndicator, Linking, View } from 'react-native';
-import { ScrollView } from 'react-native-gesture-handler';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { STORE_LINK } from '../../../utils/constants';
-import { SIZE } from '../../../utils/size';
-import { Button } from '../../ui/button';
-import { SvgView } from '../../ui/svg';
-import Seperator from '../../ui/seperator';
-import Heading from '../../ui/typography/heading';
-import Paragraph from '../../ui/typography/paragraph';
-import Config from 'react-native-config';
-import deviceInfoModule from 'react-native-device-info';
-import { checkVersion } from 'react-native-check-version';
-import { ProgressBarComponent } from '../../ui/svg/lazy';
+import React, { useEffect, useState } from "react";
+import { ActivityIndicator, Linking, View } from "react-native";
+import { ScrollView } from "react-native-gesture-handler";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { STORE_LINK } from "../../../utils/constants";
+import { SIZE } from "../../../utils/size";
+import { Button } from "../../ui/button";
+import { SvgView } from "../../ui/svg";
+import Seperator from "../../ui/seperator";
+import Heading from "../../ui/typography/heading";
+import Paragraph from "../../ui/typography/paragraph";
+import Config from "react-native-config";
+import deviceInfoModule from "react-native-device-info";
+import { checkVersion } from "react-native-check-version";
+import { ProgressBarComponent } from "../../ui/svg/lazy";
-const UPDATE_SVG = color =>
+const UPDATE_SVG = (color) =>
``;
export const Update = ({ version: appVersion, fwdRef }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [version, setVersion] = useState(appVersion);
let notes = version?.notes
- ? version.notes.replace('Thank you for using Notesnook!', '').split('- ')
- : ['Bug fixes and performance improvements'];
- notes = notes?.map(n => n.replace(/\n/g, ''));
- const isGithubRelease = Config.GITHUB_RELEASE === 'true';
+ ? version.notes.replace("Thank you for using Notesnook!", "").split("- ")
+ : ["Bug fixes and performance improvements"];
+ notes = notes?.map((n) => n.replace(/\n/g, ""));
+ const isGithubRelease = Config.GITHUB_RELEASE === "true";
const getSupportedAbi = () => {
let abi = deviceInfoModule.supportedAbisSync();
- let armv8a = abi.find(a => a === 'arm64-v8a');
- let armv7 = abi.find(a => a === 'armeabi-v7a');
+ let armv8a = abi.find((a) => a === "arm64-v8a");
+ let armv7 = abi.find((a) => a === "armeabi-v7a");
return armv8a || armv7 || abi[0];
};
@@ -49,7 +49,7 @@ export const Update = ({ version: appVersion, fwdRef }) => {
if (!version) {
(async () => {
try {
- console.log('checking for new version');
+ console.log("checking for new version");
let v = await checkVersion();
setVersion(v);
} catch (e) {
@@ -64,11 +64,11 @@ export const Update = ({ version: appVersion, fwdRef }) => {
return (
{!version || !version?.needsUpdate ? (
@@ -76,8 +76,8 @@ export const Update = ({ version: appVersion, fwdRef }) => {
{!version ? (
@@ -108,10 +108,10 @@ export const Update = ({ version: appVersion, fwdRef }) => {
<>
{
Update available
- v{version.version} has been released {isGithubRelease ? 'on Github' : ''}
+ v{version.version} has been released{" "}
+ {isGithubRelease ? "on Github" : ""}
@@ -134,11 +135,11 @@ export const Update = ({ version: appVersion, fwdRef }) => {
fwdRef?.current?.handleChildScrollEnd();
}}
style={{
- width: '100%'
+ width: "100%"
}}
>
Release notes:
- {notes.map(item => (
+ {notes.map((item) => (
{
{
- Linking.openURL(isGithubRelease ? GITHUB_URL : STORE_LINK).catch(console.log);
+ Linking.openURL(isGithubRelease ? GITHUB_URL : STORE_LINK).catch(
+ console.log
+ );
}}
type="accent"
style={{
- width: '100%'
+ width: "100%"
}}
/>
@@ -166,7 +169,7 @@ export const Update = ({ version: appVersion, fwdRef }) => {
size={12}
color={colors.icon}
style={{
- textDecorationLine: 'underline',
+ textDecorationLine: "underline",
marginTop: 10
}}
onPress={() => {
diff --git a/apps/mobile/app/components/side-menu/color-section.js b/apps/mobile/app/components/side-menu/color-section.js
index 74f02d094..7ea14c09a 100644
--- a/apps/mobile/app/components/side-menu/color-section.js
+++ b/apps/mobile/app/components/side-menu/color-section.js
@@ -1,24 +1,24 @@
-import React, { useEffect, useState } from 'react';
-import { View } from 'react-native';
-import Navigation from '../../services/navigation';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { useMenuStore } from '../../stores/use-menu-store';
-import { useNoteStore } from '../../stores/use-notes-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { COLORS_NOTE } from '../../utils/color-scheme';
-import { db } from '../../common/database';
-import { normalize, SIZE } from '../../utils/size';
-import { presentDialog } from '../dialog/functions';
-import { PressableButton } from '../ui/pressable';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import { ColoredNotes } from '../../screens/notes/colored';
+import React, { useEffect, useState } from "react";
+import { View } from "react-native";
+import Navigation from "../../services/navigation";
+import useNavigationStore from "../../stores/use-navigation-store";
+import { useMenuStore } from "../../stores/use-menu-store";
+import { useNoteStore } from "../../stores/use-notes-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { COLORS_NOTE } from "../../utils/color-scheme";
+import { db } from "../../common/database";
+import { normalize, SIZE } from "../../utils/size";
+import { presentDialog } from "../dialog/functions";
+import { PressableButton } from "../ui/pressable";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import { ColoredNotes } from "../../screens/notes/colored";
export const ColorSection = React.memo(
() => {
- const colorNotes = useMenuStore(state => state.colorNotes);
- const loading = useNoteStore(state => state.loading);
- const setColorNotes = useMenuStore(state => state.setColorNotes);
+ const colorNotes = useMenuStore((state) => state.colorNotes);
+ const loading = useNoteStore((state) => state.loading);
+ const setColorNotes = useMenuStore((state) => state.setColorNotes);
useEffect(() => {
if (!loading) {
@@ -28,7 +28,9 @@ export const ColorSection = React.memo(
return colorNotes.map((item, index) => {
let alias = db.colors.alias(item.id);
- return ;
+ return (
+
+ );
});
},
() => true
@@ -36,12 +38,12 @@ export const ColorSection = React.memo(
const ColorItem = React.memo(
({ item, index, alias }) => {
- const colors = useThemeStore(state => state.colors);
- const setColorNotes = useMenuStore(state => state.setColorNotes);
+ const colors = useThemeStore((state) => state.colors);
+ const setColorNotes = useMenuStore((state) => state.setColorNotes);
const [headerTextState, setHeaderTextState] = useState(null);
- alias = db.colors.alias(item.id) || '';
+ alias = db.colors.alias(item.id) || "";
- const onHeaderStateChange = state => {
+ const onHeaderStateChange = (state) => {
setTimeout(() => {
let id = state.currentScreen?.id;
if (id === item.id) {
@@ -61,7 +63,7 @@ const ColorItem = React.memo(
};
}, [headerTextState]);
- const onPress = item => {
+ const onPress = (item) => {
ColoredNotes.navigate(item, false);
setImmediate(() => {
@@ -71,52 +73,54 @@ const ColorItem = React.memo(
const onLongPress = () => {
presentDialog({
- title: 'Rename color',
+ title: "Rename color",
input: true,
- inputPlaceholder: 'Enter name for this color',
+ inputPlaceholder: "Enter name for this color",
defaultValue: alias,
- paragraph: 'You are renaming the color ' + item.title,
- positivePress: async value => {
+ paragraph: "You are renaming the color " + item.title,
+ positivePress: async (value) => {
if (!value || value.trim().length === 0) return;
await db.colors.rename(item.id, value);
setColorNotes();
- console.log('color updated');
+ console.log("color updated");
},
- positiveText: 'Rename'
+ positiveText: "Rename"
});
};
return (
onPress(item)}
customStyle={{
- width: '100%',
- alignSelf: 'center',
+ width: "100%",
+ alignSelf: "center",
borderRadius: 5,
- flexDirection: 'row',
+ flexDirection: "row",
paddingHorizontal: 8,
- justifyContent: 'space-between',
- alignItems: 'center',
+ justifyContent: "space-between",
+ alignItems: "center",
height: normalize(50),
marginBottom: 5
}}
>
diff --git a/apps/mobile/app/components/side-menu/index.js b/apps/mobile/app/components/side-menu/index.js
index 82f0e33c7..438ad00cb 100644
--- a/apps/mobile/app/components/side-menu/index.js
+++ b/apps/mobile/app/components/side-menu/index.js
@@ -1,61 +1,65 @@
-import React, { useCallback } from 'react';
-import { FlatList, View } from 'react-native';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { notesnook } from '../../../e2e/test.ids';
-import Settings from '../../screens/settings';
-import { DDS } from '../../services/device-detection';
-import { eSendEvent } from '../../services/event-manager';
-import { useUserStore } from '../../stores/use-user-store';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { useNoteStore } from '../../stores/use-notes-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import umami from '../../common/analytics';
-import { toggleDarkMode } from '../../utils/color-scheme/utils';
-import { MenuItemsList, SUBSCRIPTION_STATUS } from '../../utils/constants';
-import { eOpenPremiumDialog } from '../../utils/events';
-import { ColorSection } from './color-section';
-import { MenuItem } from './menu-item';
-import { TagsSection } from './pinned-section';
-import { UserStatus } from './user-status';
-import Navigation from '../../services/navigation';
+import React, { useCallback } from "react";
+import { FlatList, View } from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { notesnook } from "../../../e2e/test.ids";
+import Settings from "../../screens/settings";
+import { DDS } from "../../services/device-detection";
+import { eSendEvent } from "../../services/event-manager";
+import { useUserStore } from "../../stores/use-user-store";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { useNoteStore } from "../../stores/use-notes-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import umami from "../../common/analytics";
+import { toggleDarkMode } from "../../utils/color-scheme/utils";
+import { MenuItemsList, SUBSCRIPTION_STATUS } from "../../utils/constants";
+import { eOpenPremiumDialog } from "../../utils/events";
+import { ColorSection } from "./color-section";
+import { MenuItem } from "./menu-item";
+import { TagsSection } from "./pinned-section";
+import { UserStatus } from "./user-status";
+import Navigation from "../../services/navigation";
export const SideMenu = React.memo(
() => {
- const colors = useThemeStore(state => state.colors);
- const deviceMode = useSettingStore(state => state.deviceMode);
+ const colors = useThemeStore((state) => state.colors);
+ const deviceMode = useSettingStore((state) => state.deviceMode);
const insets = useSafeAreaInsets();
- const subscriptionType = useUserStore(state => state.user?.subscription?.type);
- const loading = useNoteStore(state => state.loading);
- const introCompleted = useSettingStore(state => state.settings.introCompleted);
+ const subscriptionType = useUserStore(
+ (state) => state.user?.subscription?.type
+ );
+ const loading = useNoteStore((state) => state.loading);
+ const introCompleted = useSettingStore(
+ (state) => state.settings.introCompleted
+ );
const noTextMode = false;
const BottomItemsList = [
{
- name: colors.night ? 'Day' : 'Night',
- icon: 'theme-light-dark',
+ name: colors.night ? "Day" : "Night",
+ icon: "theme-light-dark",
func: toggleDarkMode,
switch: true,
on: !!colors.night,
close: false
},
{
- name: 'Settings',
- icon: 'cog-outline',
+ name: "Settings",
+ icon: "cog-outline",
close: true,
func: () => {
Navigation.navigate({
- name: 'Settings',
- title: 'Settings'
+ name: "Settings",
+ title: "Settings"
});
}
}
];
const pro = {
- name: 'Notesnook Pro',
- icon: 'crown',
+ name: "Notesnook Pro",
+ icon: "crown",
func: () => {
- umami.pageView('/pro-screen', '/sidemenu');
+ umami.pageView("/pro-screen", "/sidemenu");
eSendEvent(eOpenPremiumDialog);
}
};
@@ -64,7 +68,12 @@ export const SideMenu = React.memo(
() => (
<>
{MenuItemsList.map((item, index) => (
-
+
))}
@@ -76,16 +85,16 @@ export const SideMenu = React.memo(
return !loading && introCompleted ? (
'mainMenuView'}
+ keyExtractor={() => "mainMenuView"}
renderItem={renderItem}
/>
{subscriptionType === SUBSCRIPTION_STATUS.TRIAL ||
subscriptionType === SUBSCRIPTION_STATUS.BASIC ? (
-
+
) : null}
- {BottomItemsList.slice(DDS.isLargeTablet() ? 0 : 1, 3).map((item, index) => (
-
- ))}
+ {BottomItemsList.slice(DDS.isLargeTablet() ? 0 : 1, 3).map(
+ (item, index) => (
+
+ )
+ )}
diff --git a/apps/mobile/app/components/side-menu/menu-item.js b/apps/mobile/app/components/side-menu/menu-item.js
index a5cfc2701..efde9932c 100644
--- a/apps/mobile/app/components/side-menu/menu-item.js
+++ b/apps/mobile/app/components/side-menu/menu-item.js
@@ -1,23 +1,23 @@
-import React, { useEffect, useState } from 'react';
-import { View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import ToggleSwitch from 'toggle-switch-react-native';
-import Navigation from '../../services/navigation';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { normalize, SIZE } from '../../utils/size';
-import { Button } from '../ui/button';
-import { PressableButton } from '../ui/pressable';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
+import React, { useEffect, useState } from "react";
+import { View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import ToggleSwitch from "toggle-switch-react-native";
+import Navigation from "../../services/navigation";
+import useNavigationStore from "../../stores/use-navigation-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { normalize, SIZE } from "../../utils/size";
+import { Button } from "../ui/button";
+import { PressableButton } from "../ui/pressable";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
export const MenuItem = React.memo(
({ item, index, testID, rightBtn }) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [headerTextState, setHeaderTextState] = useState(
useNavigationStore.getState().currentScreen
);
- const screenId = item.name.toLowerCase() + '_navigation';
+ const screenId = item.name.toLowerCase() + "_navigation";
let isFocused = headerTextState?.id === screenId;
const _onPress = () => {
@@ -33,7 +33,7 @@ export const MenuItem = React.memo(
}
};
- const onHeaderStateChange = state => {
+ const onHeaderStateChange = (state) => {
setTimeout(() => {
let id = state.currentScreen?.id;
if (id === screenId) {
@@ -58,33 +58,39 @@ export const MenuItem = React.memo(
testID={testID}
key={item.name + index}
onPress={_onPress}
- type={!isFocused ? 'gray' : 'grayBg'}
+ type={!isFocused ? "gray" : "grayBg"}
customStyle={{
- width: '100%',
- alignSelf: 'center',
+ width: "100%",
+ alignSelf: "center",
borderRadius: 5,
- flexDirection: 'row',
+ flexDirection: "row",
paddingHorizontal: 8,
- justifyContent: 'space-between',
- alignItems: 'center',
+ justifyContent: "space-between",
+ alignItems: "center",
height: normalize(50),
marginBottom: 5
}}
>
{isFocused ? (
diff --git a/apps/mobile/app/components/side-menu/pinned-section.js b/apps/mobile/app/components/side-menu/pinned-section.js
index b1aa3a19a..b5091c055 100644
--- a/apps/mobile/app/components/side-menu/pinned-section.js
+++ b/apps/mobile/app/components/side-menu/pinned-section.js
@@ -1,30 +1,30 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { FlatList, View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import Notebook from '../../screens/notebook';
-import { TaggedNotes } from '../../screens/notes/tagged';
-import { TopicNotes } from '../../screens/notes/topic-notes';
-import Navigation from '../../services/navigation';
-import { useMenuStore } from '../../stores/use-menu-store';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { useNoteStore } from '../../stores/use-notes-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { db } from '../../common/database';
-import { normalize, SIZE } from '../../utils/size';
-import { Properties } from '../properties';
-import { Button } from '../ui/button';
-import { Notice } from '../ui/notice';
-import { PressableButton } from '../ui/pressable';
-import Seperator from '../ui/seperator';
-import SheetWrapper from '../ui/sheet';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
+import React, { useEffect, useRef, useState } from "react";
+import { FlatList, View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import Notebook from "../../screens/notebook";
+import { TaggedNotes } from "../../screens/notes/tagged";
+import { TopicNotes } from "../../screens/notes/topic-notes";
+import Navigation from "../../services/navigation";
+import { useMenuStore } from "../../stores/use-menu-store";
+import useNavigationStore from "../../stores/use-navigation-store";
+import { useNoteStore } from "../../stores/use-notes-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { db } from "../../common/database";
+import { normalize, SIZE } from "../../utils/size";
+import { Properties } from "../properties";
+import { Button } from "../ui/button";
+import { Notice } from "../ui/notice";
+import { PressableButton } from "../ui/pressable";
+import Seperator from "../ui/seperator";
+import SheetWrapper from "../ui/sheet";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
export const TagsSection = React.memo(
() => {
- const menuPins = useMenuStore(state => state.menuPins);
- const loading = useNoteStore(state => state.loading);
- const setMenuPins = useMenuStore(state => state.setMenuPins);
+ const menuPins = useMenuStore((state) => state.menuPins);
+ const loading = useNoteStore((state) => state.loading);
+ const setMenuPins = useMenuStore((state) => state.setMenuPins);
useEffect(() => {
if (!loading) {
@@ -32,10 +32,10 @@ export const TagsSection = React.memo(
}
}, [loading]);
- const onPress = item => {
- if (item.type === 'notebook') {
+ const onPress = (item) => {
+ if (item.type === "notebook") {
Notebook.navigate(item);
- } else if (item.type === 'tag') {
+ } else if (item.type === "tag") {
TaggedNotes.navigate(item);
} else {
TopicNotes.navigate(item);
@@ -46,7 +46,9 @@ export const TagsSection = React.memo(
};
const renderItem = ({ item, index }) => {
let alias = item.alias || item.title;
- return ;
+ return (
+
+ );
};
return (
@@ -81,15 +83,15 @@ export const TagsSection = React.memo(
export const PinItem = React.memo(
({ item, index, onPress, placeholder, alias }) => {
- const colors = useThemeStore(state => state.colors);
- const setMenuPins = useMenuStore(state => state.setMenuPins);
+ const colors = useThemeStore((state) => state.colors);
+ const setMenuPins = useMenuStore((state) => state.setMenuPins);
alias = item?.alias || item?.title;
const [visible, setVisible] = useState(false);
const [headerTextState, setHeaderTextState] = useState(null);
const color = headerTextState?.id === item.id ? colors.accent : colors.pri;
const fwdRef = useRef();
- const onHeaderStateChange = state => {
+ const onHeaderStateChange = (state) => {
setTimeout(() => {
let id = state.currentScreen?.id;
if (id === item.id) {
@@ -112,9 +114,9 @@ export const PinItem = React.memo(
}, [headerTextState]);
const icons = {
- topic: 'bookmark',
- notebook: 'book-outline',
- tag: 'pound'
+ topic: "bookmark",
+ notebook: "book-outline",
+ tag: "pound"
};
return (
@@ -147,28 +149,28 @@ export const PinItem = React.memo(
)}
{
if (placeholder) return;
Properties.present(item);
}}
onPress={() => onPress(item)}
customStyle={{
- width: '100%',
- alignSelf: 'center',
+ width: "100%",
+ alignSelf: "center",
borderRadius: 5,
- flexDirection: 'row',
+ flexDirection: "row",
paddingHorizontal: 8,
- justifyContent: 'space-between',
- alignItems: 'center',
+ justifyContent: "space-between",
+ alignItems: "center",
height: normalize(50),
marginBottom: 5
}}
>
{
- const colors = useThemeStore(state => state.colors);
- const user = useUserStore(state => state.user);
- const syncing = useUserStore(state => state.syncing);
- const lastSynced = useUserStore(state => state.lastSynced);
+ const colors = useThemeStore((state) => state.colors);
+ const user = useUserStore((state) => state.user);
+ const syncing = useUserStore((state) => state.syncing);
+ const lastSynced = useUserStore((state) => state.lastSynced);
const insets = useSafeAreaInsets();
const { progress } = useSyncProgress();
- console.log('SYNC PROGRESS', progress);
+ console.log("SYNC PROGRESS", progress);
return (
{
}}
type="gray"
customStyle={{
- flexDirection: 'row',
- justifyContent: 'flex-start',
+ flexDirection: "row",
+ justifyContent: "flex-start",
padding: 12,
paddingHorizontal: 20,
borderRadius: 0
@@ -68,28 +68,30 @@ export const UserStatus = () => {
>
{!user ? (
- 'You are not logged in'
+ "You are not logged in"
) : !syncing ? (
- lastSynced && lastSynced !== 'Never' ? (
+ lastSynced && lastSynced !== "Never" ? (
<>
- Last synced{' '}
+ Last synced{" "}
>
) : (
- 'never'
+ "never"
)
) : (
- `Syncing your notes${progress ? ` (${progress.current}/${progress.total})` : ''}`
- )}{' '}
+ `Syncing your notes${
+ progress ? ` (${progress.current}/${progress.total})` : ""
+ }`
+ )}{" "}
{
- {!user ? 'Login to sync your notes.' : 'Tap here to sync your notes.'}
+ {!user
+ ? "Login to sync your notes."
+ : "Tap here to sync your notes."}
diff --git a/apps/mobile/app/components/tabs/index.tsx b/apps/mobile/app/components/tabs/index.tsx
index 8021fd5be..1e154220a 100644
--- a/apps/mobile/app/components/tabs/index.tsx
+++ b/apps/mobile/app/components/tabs/index.tsx
@@ -5,9 +5,9 @@ import React, {
useImperativeHandle,
useRef,
useState
-} from 'react';
-import { BackHandler, Platform, ViewProps } from 'react-native';
-import { Gesture, GestureDetector } from 'react-native-gesture-handler';
+} from "react";
+import { BackHandler, Platform, ViewProps } from "react-native";
+import { Gesture, GestureDetector } from "react-native-gesture-handler";
import Animated, {
runOnJS,
useAnimatedReaction,
@@ -16,10 +16,10 @@ import Animated, {
withSpring,
WithSpringConfig,
withTiming
-} from 'react-native-reanimated';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { eSendEvent } from '../../services/event-manager';
-import { eClearEditor } from '../../utils/events';
+} from "react-native-reanimated";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { eSendEvent } from "../../services/event-manager";
+import { eClearEditor } from "../../utils/events";
interface TabProps extends ViewProps {
dimensions: { width: number; height: number };
@@ -45,12 +45,22 @@ export interface TabsRef {
export const FluidTabs = forwardRef(
(
- { children, dimensions, widths, onChangeTab, onScroll, enabled, onDrawerStateChange }: TabProps,
+ {
+ children,
+ dimensions,
+ widths,
+ onChangeTab,
+ onScroll,
+ enabled,
+ onDrawerStateChange
+ }: TabProps,
ref
) => {
- const deviceMode = useSettingStore(state => state.deviceMode);
- const fullscreen = useSettingStore(state => state.fullscreen);
- const introCompleted = useSettingStore(state => state.settings.introCompleted);
+ const deviceMode = useSettingStore((state) => state.deviceMode);
+ const fullscreen = useSettingStore((state) => state.fullscreen);
+ const introCompleted = useSettingStore(
+ (state) => state.settings.introCompleted
+ );
const translateX = useSharedValue(widths ? widths.a : 0);
const startX = useSharedValue(0);
const currentTab = useSharedValue(1);
@@ -64,19 +74,21 @@ export const FluidTabs = forwardRef(
const forcedLock = useSharedValue(false);
const [disabled, setDisabled] = useState(false);
const node = useRef(null);
- const containerWidth = widths ? widths.a + widths.b + widths.c : dimensions.width;
+ const containerWidth = widths
+ ? widths.a + widths.b + widths.c
+ : dimensions.width;
const drawerPosition = 0;
const homePosition = widths.a;
const editorPosition = widths.a + widths.b;
- const isSmallTab = deviceMode === 'smallTablet';
+ const isSmallTab = deviceMode === "smallTablet";
const isLoaded = useRef(false);
const prevWidths = useRef(widths);
- const isIPhone = Platform.OS === 'ios';
+ const isIPhone = Platform.OS === "ios";
useEffect(() => {
if (introCompleted) {
- if (deviceMode === 'tablet' || fullscreen) {
+ if (deviceMode === "tablet" || fullscreen) {
translateX.value = 0;
} else {
if (prevWidths.current?.a !== widths.a) translateX.value = widths.a;
@@ -85,7 +97,7 @@ export const FluidTabs = forwardRef(
prevWidths.current = widths;
}
- const sub = BackHandler.addEventListener('hardwareBackPress', () => {
+ const sub = BackHandler.addEventListener("hardwareBackPress", () => {
if (isDrawerOpen.value) {
translateX.value = withTiming(homePosition);
onDrawerStateChange(false);
@@ -103,7 +115,7 @@ export const FluidTabs = forwardRef(
ref,
(): TabsRef => ({
goToPage: (page: number) => {
- if (deviceMode === 'tablet') {
+ if (deviceMode === "tablet") {
translateX.value = withTiming(0);
return;
}
@@ -119,7 +131,7 @@ export const FluidTabs = forwardRef(
}
},
goToIndex: (index: number) => {
- if (deviceMode === 'tablet') {
+ if (deviceMode === "tablet") {
translateX.value = withTiming(0);
return;
}
@@ -152,7 +164,7 @@ export const FluidTabs = forwardRef(
onDrawerStateChange(true);
},
closeDrawer: () => {
- if (deviceMode === 'tablet') {
+ if (deviceMode === "tablet") {
translateX.value = withTiming(0);
return;
}
@@ -169,7 +181,7 @@ export const FluidTabs = forwardRef(
useAnimatedReaction(
() => currentTab.value,
- result => {
+ (result) => {
if (setDisabled) {
if (result === 2) {
runOnJS(setDisabled)(!isIPhone);
@@ -187,7 +199,7 @@ export const FluidTabs = forwardRef(
useAnimatedReaction(
() => translateX.value,
- value => {
+ (value) => {
runOnJS(onScroll)(value);
},
[]
@@ -204,15 +216,15 @@ export const FluidTabs = forwardRef(
.enabled(enabled && !disabled)
.activeOffsetX([-5, 5])
.failOffsetY([-15, 15])
- .onBegin(event => {
+ .onBegin((event) => {
locked.value = false;
gestureStartValue.value = {
x: event.absoluteX,
y: event.absoluteY
};
})
- .onStart(event => {
- console.log('gesture activated');
+ .onStart((event) => {
+ console.log("gesture activated");
let diffX = gestureStartValue.value.x - event.absoluteX;
let diffY = gestureStartValue.value.y - event.absoluteY;
@@ -228,22 +240,25 @@ export const FluidTabs = forwardRef(
if (vx / vy < 1.5) locked.value = true;
startX.value = translateX.value;
})
- .onChange(event => {
+ .onChange((event) => {
if (locked.value || forcedLock.value) return;
let value = translateX.value + event.changeX * -1;
if (
value < 0 ||
- (currentTab.value === 2 && Platform.OS === 'android') ||
- (currentTab.value === 2 && gestureStartValue.value.x > 25 && Platform.OS === 'ios') ||
+ (currentTab.value === 2 && Platform.OS === "android") ||
+ (currentTab.value === 2 &&
+ gestureStartValue.value.x > 25 &&
+ Platform.OS === "ios") ||
(value >= homePosition && isSmallTab) ||
value > editorPosition
)
return;
translateX.value = value;
})
- .onEnd(event => {
- if (currentTab.value === 2 && Platform.OS === 'android') return;
- let velocityX = event.velocityX < 0 ? event.velocityX * -1 : event.velocityX;
+ .onEnd((event) => {
+ if (currentTab.value === 2 && Platform.OS === "android") return;
+ let velocityX =
+ event.velocityX < 0 ? event.velocityX * -1 : event.velocityX;
let isSwipeLeft = startX.value > translateX.value;
let finalValue = isSwipeLeft
? translateX.value - velocityX / 40.0
@@ -327,7 +342,7 @@ export const FluidTabs = forwardRef(
{
flex: 1,
width: containerWidth,
- flexDirection: 'row'
+ flexDirection: "row"
},
animatedStyles
]}
diff --git a/apps/mobile/app/components/tip/index.tsx b/apps/mobile/app/components/tip/index.tsx
index f2af38e52..e67291240 100644
--- a/apps/mobile/app/components/tip/index.tsx
+++ b/apps/mobile/app/components/tip/index.tsx
@@ -1,14 +1,14 @@
-import React from 'react';
-import { Image, TextStyle, View, ViewStyle } from 'react-native';
-import { eSendEvent, presentSheet } from '../../services/event-manager';
-import { TTip } from '../../services/tip-manager';
-import { ThemeStore, useThemeStore } from '../../stores/use-theme-store';
-import { MMKV } from '../../common/database/mmkv';
-import { eCloseProgressDialog } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { Button } from '../ui/button';
-import Seperator from '../ui/seperator';
-import Paragraph from '../ui/typography/paragraph';
+import React from "react";
+import { Image, TextStyle, View, ViewStyle } from "react-native";
+import { eSendEvent, presentSheet } from "../../services/event-manager";
+import { TTip } from "../../services/tip-manager";
+import { ThemeStore, useThemeStore } from "../../stores/use-theme-store";
+import { MMKV } from "../../common/database/mmkv";
+import { eCloseProgressDialog } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { Button } from "../ui/button";
+import Seperator from "../ui/seperator";
+import Paragraph from "../ui/typography/paragraph";
export const Tip = ({
tip,
@@ -23,9 +23,9 @@ export const Tip = ({
textStyle?: TextStyle;
neverShowAgain: boolean;
noImage?: boolean;
- color?: keyof ThemeStore['colors'];
+ color?: keyof ThemeStore["colors"];
}) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return tip ? (
{
- MMKV.setItem('neverShowSheetTips', 'true');
+ MMKV.setItem("neverShowSheetTips", "true");
eSendEvent(eCloseProgressDialog);
}}
//@ts-ignore
@@ -83,7 +83,7 @@ export const Tip = ({
width: null,
height: 25,
paddingHorizontal: 4,
- alignSelf: 'flex-start',
+ alignSelf: "flex-start",
borderRadius: 100,
borderWidth: 1,
borderColor: colors.icon
@@ -100,16 +100,16 @@ export const Tip = ({
@@ -140,7 +140,7 @@ export const Tip = ({
Tip.present = async (tip: TTip) => {
if (!tip) return;
- let dontShow = MMKV.getString('neverShowSheetTips');
+ let dontShow = MMKV.getString("neverShowSheetTips");
if (dontShow) return;
presentSheet({
component: (
@@ -148,7 +148,7 @@ Tip.present = async (tip: TTip) => {
tip={tip}
neverShowAgain={true}
style={{
- backgroundColor: 'transparent',
+ backgroundColor: "transparent",
paddingHorizontal: 12
}}
/>
diff --git a/apps/mobile/app/components/toast/index.js b/apps/mobile/app/components/toast/index.js
index 9e8e2f7ec..e1984be5e 100644
--- a/apps/mobile/app/components/toast/index.js
+++ b/apps/mobile/app/components/toast/index.js
@@ -1,33 +1,36 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { Keyboard, View } from 'react-native';
-import Animated, { FadeInUp, FadeOutUp } from 'react-native-reanimated';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { notesnook } from '../../../e2e/test.ids';
-import { DDS } from '../../services/device-detection';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { getElevation } from '../../utils';
-import { eHideToast, eShowToast } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { Button } from '../ui/button';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
+import React, { useEffect, useRef, useState } from "react";
+import { Keyboard, View } from "react-native";
+import Animated, { FadeInUp, FadeOutUp } from "react-native-reanimated";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { notesnook } from "../../../e2e/test.ids";
+import { DDS } from "../../services/device-detection";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { getElevation } from "../../utils";
+import { eHideToast, eShowToast } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { Button } from "../ui/button";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
let toastMessages = [];
-export const Toast = ({ context = 'global' }) => {
- const colors = useThemeStore(state => state.colors);
+export const Toast = ({ context = "global" }) => {
+ const colors = useThemeStore((state) => state.colors);
const [keyboard, setKeyboard] = useState(false);
const [data, setData] = useState({});
const insets = useSafeAreaInsets();
const hideTimeout = useRef();
const [visible, setVisible] = useState(false);
- const showToastFunc = async data => {
- console.log('toast show', data.message, toastMessages.length);
+ const showToastFunc = async (data) => {
+ console.log("toast show", data.message, toastMessages.length);
if (!data) return;
if (data.context !== context) return;
- if (toastMessages.findIndex(m => m.message === data.message) >= 0) {
- console.log('returning from here');
+ if (toastMessages.findIndex((m) => m.message === data.message) >= 0) {
+ console.log("returning from here");
return;
}
toastMessages.push(data);
@@ -43,7 +46,7 @@ export const Toast = ({ context = 'global' }) => {
}, data.duration);
};
- const showNext = data => {
+ const showNext = (data) => {
if (!data) {
hideToastFunc();
return;
@@ -91,8 +94,8 @@ export const Toast = ({ context = 'global' }) => {
useEffect(() => {
toastMessages = [];
- let sub1 = Keyboard.addListener('keyboardDidShow', _onKeyboardShow);
- let sub2 = Keyboard.addListener('keyboardDidHide', _onKeyboardHide);
+ let sub1 = Keyboard.addListener("keyboardDidShow", _onKeyboardShow);
+ let sub2 = Keyboard.addListener("keyboardDidHide", _onKeyboardHide);
eSubscribeEvent(eShowToast, showToastFunc);
eSubscribeEvent(eHideToast, hideToastFunc);
return () => {
@@ -120,12 +123,12 @@ export const Toast = ({ context = 'global' }) => {
}
}}
style={{
- width: DDS.isTab ? 400 : '100%',
- alignItems: 'center',
- alignSelf: 'center',
+ width: DDS.isTab ? 400 : "100%",
+ alignItems: "center",
+ alignSelf: "center",
minHeight: 30,
top: insets.top + 10,
- position: 'absolute',
+ position: "absolute",
zIndex: 999,
elevation: 15
}}
@@ -135,25 +138,25 @@ export const Toast = ({ context = 'global' }) => {
exiting={FadeOutUp}
style={{
...getElevation(5),
- maxWidth: '95%',
+ maxWidth: "95%",
backgroundColor: colors.nav,
- minWidth: data?.func ? '95%' : '50%',
- alignSelf: 'center',
+ minWidth: data?.func ? "95%" : "50%",
+ alignSelf: "center",
borderRadius: 5,
minHeight: 30,
paddingVertical: 10,
paddingLeft: 12,
paddingRight: 5,
- justifyContent: 'space-between',
- flexDirection: 'row',
- alignItems: 'center',
- width: '95%'
+ justifyContent: "space-between",
+ flexDirection: "row",
+ alignItems: "center",
+ width: "95%"
}}
>
{
style={{
height: 30,
borderRadius: 100,
- justifyContent: 'center',
- alignItems: 'center',
+ justifyContent: "center",
+ alignItems: "center",
marginRight: 10
}}
>
@@ -196,7 +201,7 @@ export const Toast = ({ context = 'global' }) => {
{
@@ -213,7 +218,7 @@ export const Toast = ({ context = 'global' }) => {
{
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const textColor = buttonType?.text
? buttonType.text
: //@ts-ignore
colors[
- type === 'accent'
+ type === "accent"
? BUTTON_TYPES[type](accentColor, accentText).text
: BUTTON_TYPES[type].text
];
const Component = bold ? Heading : Paragraph;
return (
-
+
{
+ onLongPress={(event) => {
if (onLongPress) {
onLongPress(event);
return;
@@ -76,16 +85,18 @@ export const AnimatedButton = ({
width: width || null,
paddingHorizontal: 12,
borderRadius: 5,
- alignSelf: 'center',
- justifyContent: 'center',
- alignItems: 'center',
- flexDirection: 'row',
+ alignSelf: "center",
+ justifyContent: "center",
+ alignItems: "center",
+ flexDirection: "row",
//@ts-ignore
...style
}}
>
- {loading ? : null}
- {icon && !loading && iconPosition === 'left' ? (
+ {loading ? (
+
+ ) : null}
+ {icon && !loading && iconPosition === "left" ? (
)}
- {icon && !loading && iconPosition === 'right' ? (
+ {icon && !loading && iconPosition === "right" ? (
{
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const textColor = buttonType?.text
? buttonType.text
: //@ts-ignore
colors[
- type === 'accent'
+ type === "accent"
? BUTTON_TYPES[type](accentColor, accentText).text
: BUTTON_TYPES[type].text
];
@@ -72,7 +72,7 @@ export const Button = ({
{...restProps}
fwdRef={fwdRef}
onPress={onPress}
- onLongPress={event => {
+ onLongPress={(event) => {
if (onLongPress) {
onLongPress(event);
return;
@@ -94,16 +94,18 @@ export const Button = ({
width: width || null,
paddingHorizontal: 12,
borderRadius: 5,
- alignSelf: 'center',
- justifyContent: 'center',
- alignItems: 'center',
- flexDirection: 'row',
+ alignSelf: "center",
+ justifyContent: "center",
+ alignItems: "center",
+ flexDirection: "row",
//@ts-ignore
...style
}}
>
- {loading ? : null}
- {icon && !loading && iconPosition === 'left' ? (
+ {loading ? (
+
+ ) : null}
+ {icon && !loading && iconPosition === "left" ? (
)}
- {icon && !loading && iconPosition === 'right' ? (
+ {icon && !loading && iconPosition === "right" ? (
{
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const _onLongPress = (event: GestureResponderEvent) => {
if (onLongPress) {
@@ -71,8 +71,8 @@ export const IconButton = ({
customStyle={{
width: 40,
height: 40,
- justifyContent: 'center',
- alignItems: 'center',
+ justifyContent: "center",
+ alignItems: "center",
borderRadius: 100,
...customStyle
}}
diff --git a/apps/mobile/app/components/ui/input/index.tsx b/apps/mobile/app/components/ui/input/index.tsx
index abab526d3..78c476950 100644
--- a/apps/mobile/app/components/ui/input/index.tsx
+++ b/apps/mobile/app/components/ui/input/index.tsx
@@ -1,4 +1,4 @@
-import React, { RefObject, useState } from 'react';
+import React, { RefObject, useState } from "react";
import {
TouchableOpacity,
TextInput,
@@ -7,26 +7,33 @@ import {
TextInputSubmitEditingEventData,
ColorValue,
ViewStyle
-} from 'react-native';
-import { View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { useThemeStore } from '../../../stores/use-theme-store';
+} from "react-native";
+import { View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { useThemeStore } from "../../../stores/use-theme-store";
import {
ERRORS_LIST,
validateEmail,
validatePass,
validateUsername
-} from '../../../services/validation';
-import { getElevation } from '../../../utils';
-import { SIZE } from '../../../utils/size';
-import { IconButton } from '../icon-button';
-import Paragraph from '../typography/paragraph';
+} from "../../../services/validation";
+import { getElevation } from "../../../utils";
+import { SIZE } from "../../../utils/size";
+import { IconButton } from "../icon-button";
+import Paragraph from "../typography/paragraph";
interface InputProps extends TextInputProps {
fwdRef?: RefObject;
- validationType?: 'password' | 'email' | 'confirmPassword' | 'username' | 'phonenumber';
+ validationType?:
+ | "password"
+ | "email"
+ | "confirmPassword"
+ | "username"
+ | "phonenumber";
loading?: boolean;
- onSubmit?: (event: NativeSyntheticEvent) => void | undefined;
+ onSubmit?: (
+ event: NativeSyntheticEvent
+ ) => void | undefined;
onErrorCheck?: (error: boolean) => void;
errorMessage?: string;
customColor?: ColorValue;
@@ -46,7 +53,7 @@ interface InputProps extends TextInputProps {
onFocusInput?: () => void;
marginRight?: number;
buttonLeft?: React.ReactNode;
- inputStyle?: TextInputProps['style'];
+ inputStyle?: TextInputProps["style"];
containerStyle?: ViewStyle;
}
@@ -75,7 +82,7 @@ const Input = ({
containerStyle = {},
...restProps
}: InputProps) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [error, setError] = useState(false);
const [focus, setFocus] = useState(false);
const [secureEntry, setSecureEntry] = useState(true);
@@ -88,7 +95,11 @@ const Input = ({
// SPECIAL: true,
});
- const color = error ? colors.red : focus ? customColor || colors.accent : colors.nav;
+ const color = error
+ ? colors.red
+ : focus
+ ? customColor || colors.accent
+ : colors.nav;
const validate = async (value: string) => {
if (!validationType) return;
@@ -103,21 +114,21 @@ const Input = ({
let isError: any = null;
switch (validationType) {
- case 'password':
+ case "password":
isError = validatePass(value);
break;
- case 'email':
+ case "email":
isError = validateEmail(value);
break;
- case 'username':
+ case "username":
isError = validateUsername(value);
break;
- case 'confirmPassword':
+ case "confirmPassword":
isError = customValidator && value === customValidator();
break;
- case 'phonenumber':
+ case "phonenumber":
// eslint-disable-next-line no-case-declarations
- const phone = require('phone').default;
+ const phone = require("phone").default;
// eslint-disable-next-line no-case-declarations
let result = phone(value, {
strictDetection: true,
@@ -132,10 +143,10 @@ const Input = ({
break;
}
- if (validationType === 'password') {
+ if (validationType === "password") {
let hasError = false;
- Object.keys(isError).forEach(e => {
+ Object.keys(isError).forEach((e) => {
if (isError[e] === true) {
hasError = true;
}
@@ -173,9 +184,9 @@ const Input = ({
borderWidth: 1,
borderRadius: 5,
borderColor: color,
- flexDirection: 'row',
- justifyContent: 'space-between',
- alignItems: 'center',
+ flexDirection: "row",
+ justifyContent: "space-between",
+ alignItems: "center",
flexGrow: 1,
height: height || 50,
paddingHorizontal: 12,
@@ -183,7 +194,7 @@ const Input = ({
...containerStyle
};
- const textStyle: TextInputProps['style'] = {
+ const textStyle: TextInputProps["style"] = {
paddingHorizontal: 0,
fontSize: fontSize,
color: onPress && loading ? colors.accent : colors.pri,
@@ -192,7 +203,7 @@ const Input = ({
flexGrow: 1,
height: height || 50,
flexShrink: 1,
- fontFamily: 'OpenSans-Regular',
+ fontFamily: "OpenSans-Regular",
//@ts-ignore
...inputStyle
};
@@ -209,7 +220,12 @@ const Input = ({
marginRight: marginRight
}}
>
-
+
{buttonLeft && buttonLeft}
height ? height : 35,
- alignItems: 'center'
+ alignItems: "center"
}}
>
{secureTextEntry && (
@@ -290,7 +310,7 @@ const Input = ({
{error && showError && errorMessage ? (
- {' '}
+ {" "}
{errorMessage}
@@ -314,7 +338,7 @@ const Input = ({
- {validationType === 'password' && focus && (
+ {validationType === "password" && focus && (
{
//@ts-ignore
- Object.keys(errorList).filter(k => errorList[k] === true).length !== 0
- ? Object.keys(ERRORS_LIST).map(error => (
+ Object.keys(errorList).filter((k) => errorList[k] === true)
+ .length !== 0
+ ? Object.keys(ERRORS_LIST).map((error) => (
diff --git a/apps/mobile/app/components/ui/notice/index.tsx b/apps/mobile/app/components/ui/notice/index.tsx
index b9acc70f3..04a10eb2b 100644
--- a/apps/mobile/app/components/ui/notice/index.tsx
+++ b/apps/mobile/app/components/ui/notice/index.tsx
@@ -1,29 +1,34 @@
-import React from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { SIZE } from '../../../utils/size';
-import { IconButton } from '../icon-button';
-import Paragraph from '../typography/paragraph';
+import React from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { SIZE } from "../../../utils/size";
+import { IconButton } from "../icon-button";
+import Paragraph from "../typography/paragraph";
export interface NoticeProps {
- type?: 'alert' | 'information';
+ type?: "alert" | "information";
text: string;
- size?: 'small' | 'large';
+ size?: "small" | "large";
selectable?: boolean;
}
-export const Notice = ({ type = 'alert', text, size = 'large', selectable }: NoticeProps) => {
- const colors = useThemeStore(state => state.colors);
- const isSmall = size === 'small';
+export const Notice = ({
+ type = "alert",
+ text,
+ size = "large",
+ selectable
+}: NoticeProps) => {
+ const colors = useThemeStore((state) => state.colors);
+ const isSmall = size === "small";
return (
{
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const selectedColor =
customSelectedColor ||
//@ts-ignore
colors[
- type === 'accent'
+ type === "accent"
? BUTTON_TYPES[type](accentColor, accentText).selected
: BUTTON_TYPES[type].selected
];
@@ -60,13 +60,13 @@ export const PressableButton = ({
customColor ||
//@ts-ignore
colors[
- type === 'accent'
+ type === "accent"
? BUTTON_TYPES[type](accentColor, accentText).primary
: BUTTON_TYPES[type].primary
];
const opacity = customOpacity
? customOpacity
- : type === 'accent'
+ : type === "accent"
? 1
: //@ts-ignore
BUTTON_TYPES[type].opacity;
@@ -78,11 +78,11 @@ export const PressableButton = ({
backgroundColor: pressed
? RGB_Linear_Shade(alpha, hexToRGBA(selectedColor, opacity || 1))
: hexToRGBA(primaryColor, opacity || 1 - 0.02),
- width: '100%',
- alignSelf: 'center',
+ width: "100%",
+ alignSelf: "center",
borderRadius: noborder ? 0 : br,
- justifyContent: 'center',
- alignItems: 'center',
+ justifyContent: "center",
+ alignItems: "center",
marginBottom: 0
},
customStyle
diff --git a/apps/mobile/app/components/ui/seperator/index.tsx b/apps/mobile/app/components/ui/seperator/index.tsx
index 7f88e0598..338553089 100644
--- a/apps/mobile/app/components/ui/seperator/index.tsx
+++ b/apps/mobile/app/components/ui/seperator/index.tsx
@@ -1,5 +1,5 @@
-import React from 'react';
-import { View } from 'react-native';
+import React from "react";
+import { View } from "react-native";
const Seperator = ({ half = false }) => {
return (
diff --git a/apps/mobile/app/components/ui/sheet/index.js b/apps/mobile/app/components/ui/sheet/index.js
index f7a8d45a5..640a215e4 100644
--- a/apps/mobile/app/components/ui/sheet/index.js
+++ b/apps/mobile/app/components/ui/sheet/index.js
@@ -1,12 +1,12 @@
-import React from 'react';
-import { Platform, View } from 'react-native';
-import ActionSheet from 'react-native-actions-sheet';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { useSettingStore } from '../../../stores/use-setting-store';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { PremiumToast } from '../../premium/premium-toast';
-import { Toast } from '../../toast';
-import { BouncingView } from '../transitions/bouncing-view';
+import React from "react";
+import { Platform, View } from "react-native";
+import ActionSheet from "react-native-actions-sheet";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { useSettingStore } from "../../../stores/use-setting-store";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { PremiumToast } from "../../premium/premium-toast";
+import { Toast } from "../../toast";
+import { BouncingView } from "../transitions/bouncing-view";
const SheetWrapper = ({
children,
@@ -20,13 +20,15 @@ const SheetWrapper = ({
overlay,
overlayOpacity = 0.3
}) => {
- const colors = useThemeStore(state => state.colors);
- const deviceMode = useSettingStore(state => state.deviceMode);
- const sheetKeyboardHandler = useSettingStore(state => state.sheetKeyboardHandler);
- const largeTablet = deviceMode === 'tablet';
- const smallTablet = deviceMode === 'smallTablet';
- const dimensions = useSettingStore(state => state.dimensions);
- const pitchBlack = useSettingStore(state => state.settings.pitchBlack);
+ const colors = useThemeStore((state) => state.colors);
+ const deviceMode = useSettingStore((state) => state.deviceMode);
+ const sheetKeyboardHandler = useSettingStore(
+ (state) => state.sheetKeyboardHandler
+ );
+ const largeTablet = deviceMode === "tablet";
+ const smallTablet = deviceMode === "smallTablet";
+ const dimensions = useSettingStore((state) => state.dimensions);
+ const pitchBlack = useSettingStore((state) => state.settings.pitchBlack);
const insets = useSafeAreaInsets();
@@ -34,14 +36,14 @@ const SheetWrapper = ({
const style = React.useMemo(() => {
return {
- width: largeTablet || smallTablet ? width : '100%',
+ width: largeTablet || smallTablet ? width : "100%",
backgroundColor: colors.bg,
zIndex: 10,
paddingTop: 5,
paddingBottom: 0,
borderTopRightRadius: 10,
borderTopLeftRadius: 10,
- alignSelf: 'center',
+ alignSelf: "center",
borderBottomRightRadius: 0,
borderBottomLeftRadius: 0
};
@@ -61,7 +63,7 @@ const SheetWrapper = ({
{overlay}
- fwdRef?.current?.hide()} offset={50} />
+ fwdRef?.current?.hide()}
+ offset={50}
+ />
>
}
onClose={_onClose}
@@ -91,7 +97,10 @@ const SheetWrapper = ({
{children}
diff --git a/apps/mobile/app/components/ui/svg/index.tsx b/apps/mobile/app/components/ui/svg/index.tsx
index 47e820fa4..ceb482b10 100644
--- a/apps/mobile/app/components/ui/svg/index.tsx
+++ b/apps/mobile/app/components/ui/svg/index.tsx
@@ -1,6 +1,6 @@
-import React from 'react';
-import { View } from 'react-native';
-import { SvgXml } from './lazy';
+import React from "react";
+import { View } from "react-native";
+import { SvgXml } from "./lazy";
export const SvgView = ({
width = 250,
diff --git a/apps/mobile/app/components/ui/svg/lazy.js b/apps/mobile/app/components/ui/svg/lazy.js
index a190e56a7..d86427b8a 100644
--- a/apps/mobile/app/components/ui/svg/lazy.js
+++ b/apps/mobile/app/components/ui/svg/lazy.js
@@ -1,5 +1,5 @@
-import React from 'react';
-import module_svg from './module-svg';
+import React from "react";
+import module_svg from "./module-svg";
export const QRCode = module_svg.QRCode;
diff --git a/apps/mobile/app/components/ui/svg/module-svg.js b/apps/mobile/app/components/ui/svg/module-svg.js
index 6a34cac0f..653332c9f 100644
--- a/apps/mobile/app/components/ui/svg/module-svg.js
+++ b/apps/mobile/app/components/ui/svg/module-svg.js
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-var-requires */
-import { Bar, Circle } from 'react-native-progress';
-import QRCode from 'react-native-qrcode-svg';
-import { SvgXml } from 'react-native-svg';
+import { Bar, Circle } from "react-native-progress";
+import QRCode from "react-native-qrcode-svg";
+import { SvgXml } from "react-native-svg";
const Progress = {
Bar,
diff --git a/apps/mobile/app/components/ui/time-since/index.tsx b/apps/mobile/app/components/ui/time-since/index.tsx
index e871931c0..2350b81fd 100644
--- a/apps/mobile/app/components/ui/time-since/index.tsx
+++ b/apps/mobile/app/components/ui/time-since/index.tsx
@@ -1,14 +1,18 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { TextProps } from 'react-native';
-import { timeSince } from '../../../utils/time';
-import Paragraph from '../typography/paragraph';
+import React, { useEffect, useRef, useState } from "react";
+import { TextProps } from "react-native";
+import { timeSince } from "../../../utils/time";
+import Paragraph from "../typography/paragraph";
interface TimeSinceProps extends TextProps {
updateFrequency: number;
time: number;
}
-export const TimeSince = ({ time, style, updateFrequency = 30000 }: TimeSinceProps) => {
+export const TimeSince = ({
+ time,
+ style,
+ updateFrequency = 30000
+}: TimeSinceProps) => {
const [timeAgo, setTimeAgo] = useState(null);
const interval = useRef();
diff --git a/apps/mobile/app/components/ui/transitions/bouncing-view.js b/apps/mobile/app/components/ui/transitions/bouncing-view.js
index 5ba82ff2a..7141e9f75 100644
--- a/apps/mobile/app/components/ui/transitions/bouncing-view.js
+++ b/apps/mobile/app/components/ui/transitions/bouncing-view.js
@@ -1,10 +1,10 @@
-import React, { useEffect } from 'react';
+import React, { useEffect } from "react";
import Animated, {
Easing,
useAnimatedStyle,
useSharedValue,
withTiming
-} from 'react-native-reanimated';
+} from "react-native-reanimated";
export const BouncingView = ({
children,
@@ -34,5 +34,7 @@ export const BouncingView = ({
});
}, []);
- return {children};
+ return (
+ {children}
+ );
};
diff --git a/apps/mobile/app/components/ui/typography/heading.tsx b/apps/mobile/app/components/ui/typography/heading.tsx
index 2df48f7cd..f61ca7a20 100644
--- a/apps/mobile/app/components/ui/typography/heading.tsx
+++ b/apps/mobile/app/components/ui/typography/heading.tsx
@@ -1,9 +1,12 @@
-import React, { useMemo } from 'react';
-import { Platform, TextProps } from 'react-native';
-import { Text } from 'react-native';
-import Animated, { ComplexAnimationBuilder, Layout } from 'react-native-reanimated';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { SIZE } from '../../../utils/size';
+import React, { useMemo } from "react";
+import { Platform, TextProps } from "react-native";
+import { Text } from "react-native";
+import Animated, {
+ ComplexAnimationBuilder,
+ Layout
+} from "react-native-reanimated";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { SIZE } from "../../../utils/size";
interface HeadingProps extends TextProps {
color?: string;
@@ -14,8 +17,14 @@ interface HeadingProps extends TextProps {
const AnimatedText = Animated.createAnimatedComponent(Text);
-const Heading = ({ color, size = SIZE.xl, style, animated, ...restProps }: HeadingProps) => {
- const colors = useThemeStore(state => state.colors);
+const Heading = ({
+ color,
+ size = SIZE.xl,
+ style,
+ animated,
+ ...restProps
+}: HeadingProps) => {
+ const colors = useThemeStore((state) => state.colors);
const Component = useMemo(() => (animated ? AnimatedText : Text), [animated]);
return (
@@ -28,8 +37,9 @@ const Heading = ({ color, size = SIZE.xl, style, animated, ...restProps }: Headi
{
fontSize: size || SIZE.xl,
color: color || colors.heading,
- fontFamily: Platform.OS === 'android' ? 'OpenSans-SemiBold' : undefined,
- fontWeight: Platform.OS === 'ios' ? '600' : undefined
+ fontFamily:
+ Platform.OS === "android" ? "OpenSans-SemiBold" : undefined,
+ fontWeight: Platform.OS === "ios" ? "600" : undefined
},
style
]}
diff --git a/apps/mobile/app/components/ui/typography/paragraph.tsx b/apps/mobile/app/components/ui/typography/paragraph.tsx
index 641405cee..62a72377a 100644
--- a/apps/mobile/app/components/ui/typography/paragraph.tsx
+++ b/apps/mobile/app/components/ui/typography/paragraph.tsx
@@ -1,8 +1,11 @@
-import React, { useMemo } from 'react';
-import { Text, TextProps } from 'react-native';
-import Animated, { ComplexAnimationBuilder, Layout } from 'react-native-reanimated';
-import { useThemeStore } from '../../../stores/use-theme-store';
-import { SIZE } from '../../../utils/size';
+import React, { useMemo } from "react";
+import { Text, TextProps } from "react-native";
+import Animated, {
+ ComplexAnimationBuilder,
+ Layout
+} from "react-native-reanimated";
+import { useThemeStore } from "../../../stores/use-theme-store";
+import { SIZE } from "../../../utils/size";
interface ParagraphProps extends TextProps {
color?: string;
size?: number;
@@ -11,8 +14,14 @@ interface ParagraphProps extends TextProps {
}
const AnimatedText = Animated.createAnimatedComponent(Text);
-const Paragraph = ({ color, size = SIZE.sm, style, animated, ...restProps }: ParagraphProps) => {
- const colors = useThemeStore(state => state.colors);
+const Paragraph = ({
+ color,
+ size = SIZE.sm,
+ style,
+ animated,
+ ...restProps
+}: ParagraphProps) => {
+ const colors = useThemeStore((state) => state.colors);
const Component = useMemo(() => (animated ? AnimatedText : Text), [animated]);
return (
@@ -25,8 +34,8 @@ const Paragraph = ({ color, size = SIZE.sm, style, animated, ...restProps }: Par
{
fontSize: size || SIZE.sm,
color: color || colors.pri,
- fontWeight: '400',
- fontFamily: 'OpenSans-Regular'
+ fontWeight: "400",
+ fontFamily: "OpenSans-Regular"
},
style
]}
diff --git a/apps/mobile/app/components/walkthroughs/index.tsx b/apps/mobile/app/components/walkthroughs/index.tsx
index 0a79908be..75ce7fd08 100644
--- a/apps/mobile/app/components/walkthroughs/index.tsx
+++ b/apps/mobile/app/components/walkthroughs/index.tsx
@@ -1,22 +1,28 @@
-import React, { useState } from 'react';
-import { LayoutAnimation, View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { eSendEvent, presentSheet } from '../../services/event-manager';
-import { eCloseProgressDialog } from '../../utils/events';
-import { MMKV } from '../../common/database/mmkv';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
-import { Button } from '../ui/button';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
-import walkthroughs, { TStep } from './walkthroughs';
+import React, { useState } from "react";
+import { LayoutAnimation, View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { eSendEvent, presentSheet } from "../../services/event-manager";
+import { eCloseProgressDialog } from "../../utils/events";
+import { MMKV } from "../../common/database/mmkv";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
+import { Button } from "../ui/button";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
+import walkthroughs, { TStep } from "./walkthroughs";
-export const Walkthrough = ({ steps, canSkip = true }: { steps: TStep[]; canSkip: boolean }) => {
- const colors = useThemeStore(state => state.colors);
+export const Walkthrough = ({
+ steps,
+ canSkip = true
+}: {
+ steps: TStep[];
+ canSkip: boolean;
+}) => {
+ const colors = useThemeStore((state) => state.colors);
const [step, setStep] = useState(steps && steps[0]);
const next = () => {
- let index = steps.findIndex(s => s.text === step.text);
+ let index = steps.findIndex((s) => s.text === step.text);
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setStep(steps[index + 1]);
};
@@ -24,8 +30,8 @@ export const Walkthrough = ({ steps, canSkip = true }: { steps: TStep[]; canSkip
return (
@@ -53,7 +59,7 @@ export const Walkthrough = ({ steps, canSkip = true }: { steps: TStep[]; canSkip
marginTop: 10
}}
textStyle={{
- textDecorationLine: 'underline'
+ textDecorationLine: "underline"
}}
onPress={async () => {
step.actionButton?.action();
@@ -72,10 +78,10 @@ export const Walkthrough = ({ steps, canSkip = true }: { steps: TStep[]; canSkip
}}
onPress={async () => {
switch (step.button?.type) {
- case 'next':
+ case "next":
next();
return;
- case 'done':
+ case "done":
eSendEvent(eCloseProgressDialog);
await sleep(300);
step.button?.action && step.button.action();
@@ -95,7 +101,7 @@ export const Walkthrough = ({ steps, canSkip = true }: { steps: TStep[]; canSkip
marginTop: 10
}}
textStyle={{
- textDecorationLine: 'underline'
+ textDecorationLine: "underline"
}}
onPress={async () => {
eSendEvent(eCloseProgressDialog);
@@ -109,15 +115,17 @@ export const Walkthrough = ({ steps, canSkip = true }: { steps: TStep[]; canSkip
};
let walkthroughState: { [name: string]: boolean } = {};
-Walkthrough.update = async (id: 'notebooks' | 'trialstarted' | 'emailconfirmed' | 'prouser') => {
- console.log('walkthrough state', walkthroughState);
+Walkthrough.update = async (
+ id: "notebooks" | "trialstarted" | "emailconfirmed" | "prouser"
+) => {
+ console.log("walkthrough state", walkthroughState);
if (walkthroughState[id]) return;
walkthroughState[id] = true;
- MMKV.setItem('walkthroughState', JSON.stringify(walkthroughState));
+ MMKV.setItem("walkthroughState", JSON.stringify(walkthroughState));
};
Walkthrough.init = async () => {
- let json = MMKV.getString('walkthroughState');
+ let json = MMKV.getString("walkthroughState");
if (json) {
walkthroughState = JSON.parse(json);
console.log(walkthroughState);
@@ -125,13 +133,13 @@ Walkthrough.init = async () => {
};
Walkthrough.present = async (
- id: 'notebooks' | 'trialstarted' | 'emailconfirmed' | 'prouser',
+ id: "notebooks" | "trialstarted" | "emailconfirmed" | "prouser",
canSkip = true,
nopersist?: boolean
) => {
if (!nopersist) {
if (!walkthroughState || Object.keys(walkthroughState).length === 0) {
- console.log('late init of walkthrough state');
+ console.log("late init of walkthrough state");
await Walkthrough.init();
}
if (walkthroughState[id]) return;
diff --git a/apps/mobile/app/components/walkthroughs/walkthroughs.tsx b/apps/mobile/app/components/walkthroughs/walkthroughs.tsx
index c6488ddbb..1028889a7 100644
--- a/apps/mobile/app/components/walkthroughs/walkthroughs.tsx
+++ b/apps/mobile/app/components/walkthroughs/walkthroughs.tsx
@@ -1,27 +1,32 @@
-import React from 'react';
-import { Linking, View } from 'react-native';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { COMMUNITY_SVG, LAUNCH_ROCKET, SUPPORT_SVG, WELCOME_SVG } from '../../assets/images/assets';
-import { ThemeStore, useThemeStore } from '../../stores/use-theme-store';
-import { eSendEvent } from '../../services/event-manager';
-import { getElevation } from '../../utils';
-import { eOpenAddNotebookDialog } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import useRotator from '../../hooks/use-rotator';
-import { AccentColorPicker } from '../../screens/settings/appearance';
-import { Button } from '../ui/button';
-import { SvgView } from '../ui/svg';
-import { PinItem } from '../side-menu/pinned-section';
-import Seperator from '../ui/seperator';
-import Heading from '../ui/typography/heading';
-import Paragraph from '../ui/typography/paragraph';
+import React from "react";
+import { Linking, View } from "react-native";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import {
+ COMMUNITY_SVG,
+ LAUNCH_ROCKET,
+ SUPPORT_SVG,
+ WELCOME_SVG
+} from "../../assets/images/assets";
+import { ThemeStore, useThemeStore } from "../../stores/use-theme-store";
+import { eSendEvent } from "../../services/event-manager";
+import { getElevation } from "../../utils";
+import { eOpenAddNotebookDialog } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import useRotator from "../../hooks/use-rotator";
+import { AccentColorPicker } from "../../screens/settings/appearance";
+import { Button } from "../ui/button";
+import { SvgView } from "../ui/svg";
+import { PinItem } from "../side-menu/pinned-section";
+import Seperator from "../ui/seperator";
+import Heading from "../ui/typography/heading";
+import Paragraph from "../ui/typography/paragraph";
export type TStep = {
text?: string;
- walkthroughItem: (colors: ThemeStore['colors']) => React.ReactNode;
+ walkthroughItem: (colors: ThemeStore["colors"]) => React.ReactNode;
title?: string;
button?: {
- type: 'next' | 'done';
+ type: "next" | "done";
title: string;
action?: () => void;
};
@@ -32,21 +37,21 @@ export type TStep = {
};
const NotebookWelcome = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const data = useRotator([
{
- title: 'Work and office',
- description: 'Everything related to my job',
+ title: "Work and office",
+ description: "Everything related to my job",
count: 2
},
{
- title: 'School work',
+ title: "School work",
description: "I don't like doing this but I have to.",
count: 5
},
{
- title: 'Recipies',
- description: 'I love cooking and collecting recipies',
+ title: "Recipies",
+ description: "I love cooking and collecting recipies",
count: 10
}
]);
@@ -54,7 +59,7 @@ const NotebookWelcome = () => {
return (
{
{
};
const notebooks: { id: string; steps: TStep[] } = {
- id: 'notebooks',
+ id: "notebooks",
steps: [
{
- title: 'Notebooks',
- text: 'Boost your productivity with Notebooks and organize your notes.',
+ title: "Notebooks",
+ text: "Boost your productivity with Notebooks and organize your notes.",
walkthroughItem: () => ,
button: {
- type: 'next',
- title: 'Next'
+ type: "next",
+ title: "Next"
}
},
{
- title: 'Notebook > Topic > Notes',
- text: 'Every Notebook has various topics which are like sections that hold all your notes.',
- walkthroughItem: (colors: ThemeStore['colors']) => (
+ title: "Notebook > Topic > Notes",
+ text: "Every Notebook has various topics which are like sections that hold all your notes.",
+ walkthroughItem: (colors: ThemeStore["colors"]) => (
- Tasks
+ {" "}
+ Tasks
- Feburary 2022 Week 2
+ Feburary
+ 2022 Week 2
- Feburary 2022 Week 1
+ Feburary
+ 2022 Week 1
- Meetings
+ {" "}
+ Meetings
),
button: {
- type: 'next',
- title: 'Next'
+ type: "next",
+ title: "Next"
}
},
{
- title: 'Easy access',
- text: 'You can create shortcuts of frequently accessed notebooks or topics in Side Menu',
+ title: "Easy access",
+ text: "You can create shortcuts of frequently accessed notebooks or topics in Side Menu",
walkthroughItem: () => (
{}}
/>
@@ -227,16 +236,16 @@ const notebooks: { id: string; steps: TStep[] } = {
index={1}
placeholder={true}
item={{
- title: 'Work and office',
- type: 'notebook'
+ title: "Work and office",
+ type: "notebook"
}}
onPress={() => {}}
/>
),
button: {
- type: 'done',
- title: 'Add your first notebook',
+ type: "done",
+ title: "Add your first notebook",
action: () => {
eSendEvent(eOpenAddNotebookDialog);
}
@@ -246,13 +255,13 @@ const notebooks: { id: string; steps: TStep[] } = {
};
const ChooseTheme = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
@@ -260,9 +269,9 @@ const ChooseTheme = () => {
@@ -276,37 +285,37 @@ const ChooseTheme = () => {
};
const trialstarted: { id: string; steps: TStep[] } = {
- id: 'trialstarted',
+ id: "trialstarted",
steps: [
{
- title: 'Your trial is activated',
- text: 'You can use all permium features for free for the next 14 days',
- walkthroughItem: colors => ,
+ title: "Your trial is activated",
+ text: "You can use all permium features for free for the next 14 days",
+ walkthroughItem: (colors) => ,
button: {
- type: 'next',
- title: 'Next'
+ type: "next",
+ title: "Next"
}
},
{
walkthroughItem: () => ,
button: {
- type: 'next',
- title: 'Next'
+ type: "next",
+ title: "Next"
}
},
{
- title: 'Join the cause',
- text: 'Meet other privacy-minded people and talk to us directly about your concerns, issues and suggestions.',
- walkthroughItem: colors => ,
+ title: "Join the cause",
+ text: "Meet other privacy-minded people and talk to us directly about your concerns, issues and suggestions.",
+ walkthroughItem: (colors) => ,
button: {
- type: 'done',
- title: 'Continue'
+ type: "done",
+ title: "Continue"
},
actionButton: {
- text: 'Join Discord Community',
+ text: "Join Discord Community",
action: () => {
- Linking.openURL('https://discord.gg/zQBK97EE22').catch(console.log);
+ Linking.openURL("https://discord.gg/zQBK97EE22").catch(console.log);
}
}
}
@@ -314,50 +323,51 @@ const trialstarted: { id: string; steps: TStep[] } = {
};
const emailconfirmed: { id: string; steps: TStep[] } = {
- id: 'emailconfirmed',
+ id: "emailconfirmed",
steps: [
{
- title: 'Email confirmed',
- text: 'Your email was confirmed successfully. Thank you for choosing end-to-end encrypted note taking.',
- walkthroughItem: colors => ,
+ title: "Email confirmed",
+ text: "Your email was confirmed successfully. Thank you for choosing end-to-end encrypted note taking.",
+ walkthroughItem: (colors) => ,
button: {
- type: 'done',
- title: 'Continue'
+ type: "done",
+ title: "Continue"
}
}
]
};
const Support = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
Get Priority Support
- You can reach out to us via multiple channels if you face an issue or want to just talk.
+ You can reach out to us via multiple channels if you face an issue or
+ want to just talk.
{
- Linking.openURL('https://discord.gg/zQBK97EE22').catch(console.log);
+ Linking.openURL("https://discord.gg/zQBK97EE22").catch(console.log);
}}
icon="discord"
type="grayBg"
@@ -366,12 +376,12 @@ const Support = () => {
{
- Linking.openURL('https://t.me/notesnook').catch(console.log);
+ Linking.openURL("https://t.me/notesnook").catch(console.log);
}}
icon="telegram"
type="grayBg"
@@ -379,9 +389,9 @@ const Support = () => {
/>
{
/>
{
};
const prouser: { id: string; steps: TStep[] } = {
- id: 'prouser',
+ id: "prouser",
steps: [
{
- title: 'Welcome to Notesnook Pro',
- text: 'Thank you for reaffirming our idea that privacy comes first',
- walkthroughItem: colors => ,
+ title: "Welcome to Notesnook Pro",
+ text: "Thank you for reaffirming our idea that privacy comes first",
+ walkthroughItem: (colors) => ,
button: {
- type: 'next',
- title: 'Next'
+ type: "next",
+ title: "Next"
}
},
{
walkthroughItem: () => ,
button: {
- type: 'done',
- title: 'Continue'
+ type: "done",
+ title: "Continue"
}
}
]
diff --git a/apps/mobile/app/features.ts b/apps/mobile/app/features.ts
index 1a22bf035..71f52a54d 100644
--- a/apps/mobile/app/features.ts
+++ b/apps/mobile/app/features.ts
@@ -1,3 +1,3 @@
-import { FeatureType } from './components/sheets/new-feature';
+import { FeatureType } from "./components/sheets/new-feature";
export const features: FeatureType[] = [];
diff --git a/apps/mobile/app/hooks/use-actions.js b/apps/mobile/app/hooks/use-actions.js
index d39863b50..fa515c341 100644
--- a/apps/mobile/app/hooks/use-actions.js
+++ b/apps/mobile/app/hooks/use-actions.js
@@ -1,12 +1,12 @@
-import Clipboard from '@react-native-clipboard/clipboard';
-import React, { useEffect, useState } from 'react';
-import { Platform } from 'react-native';
-import Share from 'react-native-share';
-import { editing, toTXT } from '../utils';
-import { notesnook } from '../../e2e/test.ids';
-import { presentDialog } from '../components/dialog/functions';
-import NoteHistory from '../components/note-history';
-import { MoveNotes } from '../components/sheets/move-notes/movenote';
+import Clipboard from "@react-native-clipboard/clipboard";
+import React, { useEffect, useState } from "react";
+import { Platform } from "react-native";
+import Share from "react-native-share";
+import { editing, toTXT } from "../utils";
+import { notesnook } from "../../e2e/test.ids";
+import { presentDialog } from "../components/dialog/functions";
+import NoteHistory from "../components/note-history";
+import { MoveNotes } from "../components/sheets/move-notes/movenote";
import {
eSendEvent,
eSubscribeEvent,
@@ -14,17 +14,17 @@ import {
openVault,
presentSheet,
ToastEvent
-} from '../services/event-manager';
-import Navigation from '../services/navigation';
-import Notifications from '../services/notifications';
-import { useEditorStore } from '../stores/use-editor-store';
-import { useMenuStore } from '../stores/use-menu-store';
-import { useSelectionStore } from '../stores/use-selection-store';
-import { useTagStore } from '../stores/use-tag-store';
-import { useThemeStore } from '../stores/use-theme-store';
-import { useUserStore } from '../stores/use-user-store';
-import { toggleDarkMode } from '../utils/color-scheme/utils';
-import { db } from '../common/database';
+} from "../services/event-manager";
+import Navigation from "../services/navigation";
+import Notifications from "../services/notifications";
+import { useEditorStore } from "../stores/use-editor-store";
+import { useMenuStore } from "../stores/use-menu-store";
+import { useSelectionStore } from "../stores/use-selection-store";
+import { useTagStore } from "../stores/use-tag-store";
+import { useThemeStore } from "../stores/use-theme-store";
+import { useUserStore } from "../stores/use-user-store";
+import { toggleDarkMode } from "../utils/color-scheme/utils";
+import { db } from "../common/database";
import {
eOpenAddNotebookDialog,
eOpenAddTopicDialog,
@@ -33,28 +33,31 @@ import {
eOpenLoginDialog,
eOpenMoveNoteDialog,
eOpenPublishNoteDialog
-} from '../utils/events';
-import { deleteItems } from '../utils/functions';
-import { sleep } from '../utils/time';
-import useNavigationStore from '../stores/use-navigation-store';
+} from "../utils/events";
+import { deleteItems } from "../utils/functions";
+import { sleep } from "../utils/time";
+import useNavigationStore from "../stores/use-navigation-store";
export const useActions = ({ close = () => null, item }) => {
- const colors = useThemeStore(state => state.colors);
- const clearSelection = useSelectionStore(state => state.clearSelection);
- const setSelectedItem = useSelectionStore(state => state.setSelectedItem);
- const setMenuPins = useMenuStore(state => state.setMenuPins);
- const [isPinnedToMenu, setIsPinnedToMenu] = useState(db.settings.isPinned(item.id));
- console.log(item.readonly, 'readonly');
- const user = useUserStore(state => state.user);
+ const colors = useThemeStore((state) => state.colors);
+ const clearSelection = useSelectionStore((state) => state.clearSelection);
+ const setSelectedItem = useSelectionStore((state) => state.setSelectedItem);
+ const setMenuPins = useMenuStore((state) => state.setMenuPins);
+ const [isPinnedToMenu, setIsPinnedToMenu] = useState(
+ db.settings.isPinned(item.id)
+ );
+ console.log(item.readonly, "readonly");
+ const user = useUserStore((state) => state.user);
const [notifPinned, setNotifPinned] = useState(null);
const alias = item.alias || item.title;
- const isPublished = item.type === 'note' && db.monographs.isPublished(item.id);
+ const isPublished =
+ item.type === "note" && db.monographs.isPublished(item.id);
useEffect(() => {
if (item.id === null) return;
checkNotifPinned();
- if (item.type !== 'note') {
+ if (item.type !== "note") {
setIsPinnedToMenu(db.settings.isPinned(item.id));
}
}, [item]);
@@ -66,7 +69,7 @@ export const useActions = ({ close = () => null, item }) => {
return;
}
- let index = pinned.findIndex(notif => notif.tag === item.id);
+ let index = pinned.findIndex((notif) => notif.tag === item.id);
if (index !== -1) {
setNotifPinned(pinned[index]);
} else {
@@ -76,15 +79,15 @@ export const useActions = ({ close = () => null, item }) => {
const isNoteInTopic = () => {
const currentScreen = useNavigationStore.getState().currentScreen;
- if (item.type !== 'note' || currentScreen.name !== 'TopicNotes') return;
+ if (item.type !== "note" || currentScreen.name !== "TopicNotes") return;
return db.notebooks
.notebook(currentScreen.notebookId)
.topics.topic(currentScreen.id)
.has(item.id);
};
- const onUpdate = async type => {
- if (type === 'unpin') {
+ const onUpdate = async (type) => {
+ if (type === "unpin") {
await sleep(1000);
await Notifications.get();
checkNotifPinned();
@@ -92,10 +95,10 @@ export const useActions = ({ close = () => null, item }) => {
};
useEffect(() => {
- eSubscribeEvent('onUpdate', onUpdate);
+ eSubscribeEvent("onUpdate", onUpdate);
return () => {
- eUnSubscribeEvent('onUpdate', onUpdate);
+ eUnSubscribeEvent("onUpdate", onUpdate);
};
}, [item]);
@@ -117,11 +120,11 @@ export const useActions = ({ close = () => null, item }) => {
close();
await db.notes.note(item.id).favorite();
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes"
);
}
@@ -132,25 +135,25 @@ export const useActions = ({ close = () => null, item }) => {
if (db[`${type}s`].pinned.length === 3 && !item.pinned) {
ToastEvent.show({
heading: `Cannot pin more than 3 ${type}s`,
- type: 'error'
+ type: "error"
});
return;
}
await db[`${type}s`][type](item.id).pin();
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes',
- 'Notebooks'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes",
+ "Notebooks"
);
}
async function pinToNotifications() {
if (!checkNoteSynced()) return;
- console.log('pinToNotifications');
- if (Platform.OS === 'ios') return;
+ console.log("pinToNotifications");
+ if (Platform.OS === "ios") return;
if (notifPinned !== null) {
Notifications.remove(item.id, notifPinned.identifier);
@@ -168,7 +171,7 @@ export const useActions = ({ close = () => null, item }) => {
subtitle: item.headline || text,
bigText: html,
ongoing: true,
- actions: ['UNPIN'],
+ actions: ["UNPIN"],
tag: item.id
});
await sleep(1000);
@@ -181,18 +184,21 @@ export const useActions = ({ close = () => null, item }) => {
close();
await db.trash.restore(item.id);
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes',
- 'Notebooks',
- 'Trash'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes",
+ "Notebooks",
+ "Trash"
);
- let type = item.type === 'trash' ? item.itemType : item.type;
+ let type = item.type === "trash" ? item.itemType : item.type;
ToastEvent.show({
- heading: type === 'note' ? 'Note restored from trash' : 'Notebook restored from trash',
- type: 'success'
+ heading:
+ type === "note"
+ ? "Note restored from trash"
+ : "Notebook restored from trash",
+ type: "success"
});
}
@@ -206,15 +212,15 @@ export const useActions = ({ close = () => null, item }) => {
novault: true,
locked: true,
item: item,
- title: 'Copy note',
- description: 'Unlock note to copy to clipboard.'
+ title: "Copy note",
+ description: "Unlock note to copy to clipboard."
});
} else {
Clipboard.setString(await toTXT(item));
ToastEvent.show({
- heading: 'Note copied to clipboard',
- type: 'success',
- context: 'local'
+ heading: "Note copied to clipboard",
+ type: "success",
+ context: "local"
});
}
}
@@ -223,30 +229,30 @@ export const useActions = ({ close = () => null, item }) => {
if (!checkNoteSynced()) return;
if (!user) {
ToastEvent.show({
- heading: 'Login required',
- message: 'Login to publish note',
- context: 'local',
+ heading: "Login required",
+ message: "Login to publish note",
+ context: "local",
func: () => {
eSendEvent(eOpenLoginDialog);
},
- actionText: 'Login'
+ actionText: "Login"
});
return;
}
if (!user?.isEmailConfirmed) {
ToastEvent.show({
- heading: 'Email is not verified',
- message: 'Please verify your email first.',
- context: 'local'
+ heading: "Email is not verified",
+ message: "Please verify your email first.",
+ context: "local"
});
return;
}
if (item.locked) {
ToastEvent.show({
- heading: 'Locked notes cannot be published',
- type: 'error',
- context: 'local'
+ heading: "Locked notes cannot be published",
+ type: "error",
+ context: "local"
});
return;
}
@@ -256,24 +262,24 @@ export const useActions = ({ close = () => null, item }) => {
}
const checkNoteSynced = () => {
- if (item.type !== 'note' || item.itemType !== 'note') return true;
- let isTrash = item.itemType === 'note';
+ if (item.type !== "note" || item.itemType !== "note") return true;
+ let isTrash = item.itemType === "note";
if (!isTrash && !db.notes.note(item.id).synced()) {
ToastEvent.show({
- context: 'local',
- heading: 'Note not synced',
- message: 'Please run sync before making changes',
- type: 'error'
+ context: "local",
+ heading: "Note not synced",
+ message: "Please run sync before making changes",
+ type: "error"
});
return false;
}
if (isTrash && !db.trash.synced(item.id)) {
ToastEvent.show({
- context: 'local',
- heading: 'Note not synced',
- message: 'Please run sync before making changes',
- type: 'error'
+ context: "local",
+ heading: "Note not synced",
+ message: "Please run sync before making changes",
+ type: "error"
});
return false;
}
@@ -292,8 +298,8 @@ export const useActions = ({ close = () => null, item }) => {
novault: true,
locked: true,
permanant: true,
- title: 'Unlock note',
- description: 'Remove note from the vault.'
+ title: "Unlock note",
+ description: "Remove note from the vault."
});
return;
}
@@ -303,11 +309,11 @@ export const useActions = ({ close = () => null, item }) => {
if (note.locked) {
close();
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes"
);
}
} catch (e) {
@@ -318,8 +324,8 @@ export const useActions = ({ close = () => null, item }) => {
openVault({
item: item,
novault: false,
- title: 'Create vault',
- description: 'Set a password to create a vault and lock note.'
+ title: "Create vault",
+ description: "Set a password to create a vault and lock note."
});
break;
case db.vault.ERRORS.vaultLocked:
@@ -327,8 +333,8 @@ export const useActions = ({ close = () => null, item }) => {
item: item,
novault: true,
locked: true,
- title: 'Lock note',
- description: 'Give access to vault to lock this note.'
+ title: "Lock note",
+ description: "Give access to vault to lock this note."
});
break;
}
@@ -341,7 +347,7 @@ export const useActions = ({ close = () => null, item }) => {
if (isPinnedToMenu) {
await db.settings.unpin(item.id);
} else {
- if (item.type === 'topic') {
+ if (item.type === "topic") {
await db.settings.pin(item.type, {
id: item.id,
notebookId: item.notebookId
@@ -359,26 +365,26 @@ export const useActions = ({ close = () => null, item }) => {
close();
await sleep(300);
presentDialog({
- title: 'Rename tag',
- paragraph: 'Change the title of the tag ' + alias,
- positivePress: async value => {
- if (!value || value === '' || value.trimStart().length == 0) return;
+ title: "Rename tag",
+ paragraph: "Change the title of the tag " + alias,
+ positivePress: async (value) => {
+ if (!value || value === "" || value.trimStart().length == 0) return;
await db.tags.rename(item.id, db.tags.sanitize(value));
useTagStore.getState().setTags();
useMenuStore.getState().setMenuPins();
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes',
- 'Tags'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes",
+ "Tags"
);
},
input: true,
defaultValue: alias,
- inputPlaceholder: 'Enter title of tag',
- positiveText: 'Save'
+ inputPlaceholder: "Enter title of tag",
+ positiveText: "Save"
});
}
@@ -392,12 +398,12 @@ export const useActions = ({ close = () => null, item }) => {
novault: true,
locked: true,
share: true,
- title: 'Share note',
- description: 'Unlock note to share it.'
+ title: "Share note",
+ description: "Unlock note to share it."
});
} else {
Share.open({
- title: 'Share note to',
+ title: "Share note to",
failOnCancel: false,
message: await toTXT(item)
});
@@ -407,25 +413,25 @@ export const useActions = ({ close = () => null, item }) => {
async function deleteItem() {
if (!checkNoteSynced()) return;
close();
- if (item.type === 'tag') {
+ if (item.type === "tag") {
await sleep(300);
presentDialog({
- title: 'Delete tag',
- paragraph: 'This tag will be removed from all notes.',
- positivePress: async value => {
+ title: "Delete tag",
+ paragraph: "This tag will be removed from all notes.",
+ positivePress: async (value) => {
await db.tags.remove(item.id);
useTagStore.getState().setTags();
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes',
- 'Tags'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes",
+ "Tags"
);
},
- positiveText: 'Delete',
- positiveType: 'errorShade'
+ positiveText: "Delete",
+ positiveType: "errorShade"
});
return;
}
@@ -436,32 +442,32 @@ export const useActions = ({ close = () => null, item }) => {
novault: true,
locked: true,
item: item,
- title: 'Delete note',
- description: 'Unlock note to delete it.'
+ title: "Delete note",
+ description: "Unlock note to delete it."
});
} else {
try {
close();
- console.log('moving note to trash');
+ console.log("moving note to trash");
await deleteItems(item);
} catch (e) {}
}
}
async function removeNoteFromTopic() {
const currentScreen = useNavigationStore.getState().currentScreen;
- if (currentScreen.name !== 'TopicNotes') return;
+ if (currentScreen.name !== "TopicNotes") return;
await db.notebooks
.notebook(currentScreen.notebookId)
.topics.topic(currentScreen.id)
.delete(item.id);
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes',
- 'Notebook',
- 'Notebooks'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes",
+ "Notebook",
+ "Notebooks"
);
close();
}
@@ -473,19 +479,19 @@ export const useActions = ({ close = () => null, item }) => {
presentDialog({
title: `Permanent delete`,
paragraph: `Are you sure you want to delete this ${item.itemType} permanantly from trash?`,
- positiveText: 'Delete',
- negativeText: 'Cancel',
+ positiveText: "Delete",
+ negativeText: "Cancel",
positivePress: async () => {
await db.trash.delete(item.id);
- Navigation.queueRoutesForUpdate('Trash');
+ Navigation.queueRoutesForUpdate("Trash");
useSelectionStore.getState().setSelectionMode(false);
ToastEvent.show({
- heading: 'Permanantly deleted items',
- type: 'success',
- context: 'local'
+ heading: "Permanantly deleted items",
+ type: "success",
+ context: "local"
});
},
- positiveType: 'errorShade'
+ positiveType: "errorShade"
});
}
@@ -493,7 +499,7 @@ export const useActions = ({ close = () => null, item }) => {
close();
await sleep(300);
presentSheet({
- component: ref =>
+ component: (ref) =>
});
}
@@ -513,11 +519,11 @@ export const useActions = ({ close = () => null, item }) => {
if (!checkNoteSynced() || !user) return;
db.notes.note(item.id).localOnly();
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes"
);
close();
}
@@ -530,11 +536,11 @@ export const useActions = ({ close = () => null, item }) => {
// tiny.call(EditorWebView, tiny.toogleReadMode(current ? 'readonly' : 'design'));
}
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes"
);
close();
};
@@ -543,26 +549,26 @@ export const useActions = ({ close = () => null, item }) => {
if (!checkNoteSynced()) return;
await db.notes.note(item.id).duplicate();
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes"
);
close();
};
- console.log('isNoteInTopic', isNoteInTopic());
+ console.log("isNoteInTopic", isNoteInTopic());
const actions = [
{
- name: 'Add to notebook',
- title: 'Add to notebook',
- icon: 'book-outline',
+ name: "Add to notebook",
+ title: "Add to notebook",
+ icon: "book-outline",
func: addTo
},
{
- name: 'Move notes',
- title: 'Add notes',
- icon: 'plus',
+ name: "Move notes",
+ title: "Add notes",
+ icon: "plus",
func: async () => {
close();
await sleep(500);
@@ -571,9 +577,9 @@ export const useActions = ({ close = () => null, item }) => {
},
{
- name: 'Pin',
- title: item.pinned ? 'Unpin' : 'Pin to top',
- icon: item.pinned ? 'pin-off-outline' : 'pin-outline',
+ name: "Pin",
+ title: item.pinned ? "Unpin" : "Pin to top",
+ icon: item.pinned ? "pin-off-outline" : "pin-outline",
func: pinItem,
close: false,
check: true,
@@ -582,29 +588,32 @@ export const useActions = ({ close = () => null, item }) => {
id: notesnook.ids.dialogs.actionsheet.pin
},
{
- name: 'Favorite',
- title: !item.favorite ? 'Favorite' : 'Unfavorite',
- icon: item.favorite ? 'star-off' : 'star-outline',
+ name: "Favorite",
+ title: !item.favorite ? "Favorite" : "Unfavorite",
+ icon: item.favorite ? "star-off" : "star-outline",
func: addToFavorites,
close: false,
check: true,
on: item.favorite,
nopremium: true,
id: notesnook.ids.dialogs.actionsheet.favorite,
- color: 'orange'
+ color: "orange"
},
{
- name: 'PinToNotif',
- title: notifPinned !== null ? 'Unpin from Notifications' : 'Pin to Notifications',
- icon: 'bell',
+ name: "PinToNotif",
+ title:
+ notifPinned !== null
+ ? "Unpin from Notifications"
+ : "Pin to Notifications",
+ icon: "bell",
on: notifPinned !== null,
func: pinToNotifications
},
{
- name: 'Edit Notebook',
- title: 'Edit notebook',
- icon: 'square-edit-outline',
+ name: "Edit Notebook",
+ title: "Edit notebook",
+ icon: "square-edit-outline",
func: async () => {
close();
await sleep(300);
@@ -612,9 +621,9 @@ export const useActions = ({ close = () => null, item }) => {
}
},
{
- name: 'Edit Topic',
- title: 'Edit topic',
- icon: 'square-edit-outline',
+ name: "Edit Topic",
+ title: "Edit topic",
+ icon: "square-edit-outline",
func: async () => {
close();
await sleep(300);
@@ -625,37 +634,37 @@ export const useActions = ({ close = () => null, item }) => {
}
},
{
- name: 'Copy',
- title: 'Copy',
- icon: 'content-copy',
+ name: "Copy",
+ title: "Copy",
+ icon: "content-copy",
func: copyContent
},
{
- name: 'Restore',
- title: 'Restore ' + item.itemType,
- icon: 'delete-restore',
+ name: "Restore",
+ title: "Restore " + item.itemType,
+ icon: "delete-restore",
func: restoreTrashItem
},
{
- name: 'Publish',
- title: isPublished ? 'Published' : 'Publish',
- icon: 'cloud-upload-outline',
+ name: "Publish",
+ title: isPublished ? "Published" : "Publish",
+ icon: "cloud-upload-outline",
on: isPublished,
func: publishNote
},
{
- name: 'Vault',
- title: item.locked ? 'Remove from vault' : 'Add to vault',
- icon: item.locked ? 'shield-off-outline' : 'shield-outline',
+ name: "Vault",
+ title: item.locked ? "Remove from vault" : "Add to vault",
+ icon: item.locked ? "shield-off-outline" : "shield-outline",
func: addToVault,
on: item.locked
},
{
- name: 'Add Shortcut',
- title: isPinnedToMenu ? 'Remove Shortcut' : 'Add Shortcut',
- icon: isPinnedToMenu ? 'link-variant-remove' : 'link-variant',
+ name: "Add Shortcut",
+ title: isPinnedToMenu ? "Remove Shortcut" : "Add Shortcut",
+ icon: isPinnedToMenu ? "link-variant-remove" : "link-variant",
func: createMenuShortcut,
close: false,
check: true,
@@ -664,81 +673,83 @@ export const useActions = ({ close = () => null, item }) => {
id: notesnook.ids.dialogs.actionsheet.pinMenu
},
{
- name: 'Rename Tag',
- title: 'Rename tag',
- icon: 'square-edit-outline',
+ name: "Rename Tag",
+ title: "Rename tag",
+ icon: "square-edit-outline",
func: renameTag
},
{
- name: 'Share',
- title: 'Share',
- icon: 'share-variant',
+ name: "Share",
+ title: "Share",
+ icon: "share-variant",
func: shareNote
},
{
- name: 'Attachments',
- title: 'Attachments',
- icon: 'attachment',
+ name: "Attachments",
+ title: "Attachments",
+ icon: "attachment",
func: showAttachments
},
{
- name: 'Export',
- title: 'Export',
- icon: 'export',
+ name: "Export",
+ title: "Export",
+ icon: "export",
func: exportNote
},
{
- name: 'RemoveTopic',
- title: 'Remove from topic',
+ name: "RemoveTopic",
+ title: "Remove from topic",
hidden: !isNoteInTopic(),
- icon: 'minus-circle-outline',
+ icon: "minus-circle-outline",
func: removeNoteFromTopic
},
{
- name: 'Delete',
+ name: "Delete",
title:
- item.type !== 'notebook' && item.type !== 'note' ? 'Delete ' + item.type : 'Move to trash',
- icon: 'delete-outline',
- type: 'error',
+ item.type !== "notebook" && item.type !== "note"
+ ? "Delete " + item.type
+ : "Move to trash",
+ icon: "delete-outline",
+ type: "error",
func: deleteItem
},
{
- name: 'PermDelete',
- title: 'Delete ' + item.itemType,
- icon: 'delete',
+ name: "PermDelete",
+ title: "Delete " + item.itemType,
+ icon: "delete",
func: deleteTrashItem
},
{
- name: 'ReadOnly',
- title: 'Read only',
- icon: 'pencil-lock',
+ name: "ReadOnly",
+ title: "Read only",
+ icon: "pencil-lock",
func: toggleReadyOnlyMode,
on: item.readonly
},
{
- name: 'Local only',
- title: 'Local only',
- icon: 'sync-off',
+ name: "Local only",
+ title: "Local only",
+ icon: "sync-off",
func: toggleLocalOnly,
on: item.localOnly
},
{
- name: 'History',
- title: 'History',
- icon: 'history',
+ name: "History",
+ title: "History",
+ icon: "history",
func: openHistory
},
{
- name: 'Duplicate',
- title: 'Duplicate',
- icon: 'content-duplicate',
+ name: "Duplicate",
+ title: "Duplicate",
+ icon: "content-duplicate",
func: duplicateNote
},
{
- name: 'Dark Mode',
- title: 'Dark mode',
- icon: 'theme-light-dark',
+ name: "Dark Mode",
+ title: "Dark mode",
+ icon: "theme-light-dark",
func: switchTheme,
switch: true,
on: colors.night ? true : false,
diff --git a/apps/mobile/app/hooks/use-app-events.js b/apps/mobile/app/hooks/use-app-events.js
index b77ef20ce..2dc31bd5e 100644
--- a/apps/mobile/app/hooks/use-app-events.js
+++ b/apps/mobile/app/hooks/use-app-events.js
@@ -1,6 +1,6 @@
-import NetInfo from '@react-native-community/netinfo';
-import { EV, EVENTS } from '@streetwriters/notesnook-core/common';
-import { useEffect, useRef } from 'react';
+import NetInfo from "@react-native-community/netinfo";
+import { EV, EVENTS } from "@streetwriters/notesnook-core/common";
+import { useEffect, useRef } from "react";
import {
Alert,
Appearance,
@@ -9,48 +9,52 @@ import {
NativeEventEmitter,
NativeModules,
Platform
-} from 'react-native';
-import * as RNIap from 'react-native-iap';
-import { enabled } from 'react-native-privacy-snapshot';
-import { Walkthrough } from '../components/walkthroughs';
-import { editorController, editorState } from '../screens/editor/tiptap/utils';
-import BiometricService from '../services/biometrics';
+} from "react-native";
+import * as RNIap from "react-native-iap";
+import { enabled } from "react-native-privacy-snapshot";
+import { Walkthrough } from "../components/walkthroughs";
+import { editorController, editorState } from "../screens/editor/tiptap/utils";
+import BiometricService from "../services/biometrics";
import {
clearMessage,
setEmailVerifyMessage,
setLoginMessage,
setRecoveryKeyMessage
-} from '../services/message';
-import PremiumService from '../services/premium';
-import SettingsService from '../services/settings';
-import { updateStatusBarColor } from '../utils/color-scheme';
-import { db } from '../common/database';
-import { MMKV } from '../common/database/mmkv';
-import { eClearEditor, eCloseProgressDialog, refreshNotesPage } from '../utils/events';
-import Sync from '../services/sync';
-import { clearAllStores, initAfterSync, initialize } from '../stores';
-import { useUserStore } from '../stores/use-user-store';
-import { useMessageStore } from '../stores/use-message-store';
-import { useSettingStore } from '../stores/use-setting-store';
-import { useAttachmentStore } from '../stores/use-attachment-store';
-import { useNoteStore } from '../stores/use-notes-store';
+} from "../services/message";
+import PremiumService from "../services/premium";
+import SettingsService from "../services/settings";
+import { updateStatusBarColor } from "../utils/color-scheme";
+import { db } from "../common/database";
+import { MMKV } from "../common/database/mmkv";
+import {
+ eClearEditor,
+ eCloseProgressDialog,
+ refreshNotesPage
+} from "../utils/events";
+import Sync from "../services/sync";
+import { clearAllStores, initAfterSync, initialize } from "../stores";
+import { useUserStore } from "../stores/use-user-store";
+import { useMessageStore } from "../stores/use-message-store";
+import { useSettingStore } from "../stores/use-setting-store";
+import { useAttachmentStore } from "../stores/use-attachment-store";
+import { useNoteStore } from "../stores/use-notes-store";
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent,
ToastEvent
-} from '../services/event-manager';
-import { useEditorStore } from '../stores/use-editor-store';
-import { useDragState } from '../screens/settings/editor/state';
-import { sleep } from '../utils/time';
+} from "../services/event-manager";
+import { useEditorStore } from "../stores/use-editor-store";
+import { useDragState } from "../screens/settings/editor/state";
+import { sleep } from "../utils/time";
const SodiumEventEmitter = new NativeEventEmitter(NativeModules.Sodium);
export const useAppEvents = () => {
- const loading = useNoteStore(state => state.loading);
- const setLastSynced = useUserStore(state => state.setLastSynced);
- const setUser = useUserStore(state => state.setUser);
+ const loading = useNoteStore((state) => state.loading);
+ const setLastSynced = useUserStore((state) => state.setLastSynced);
+ const setUser = useUserStore((state) => state.setUser);
const syncedOnLaunch = useRef(false);
- const verify = useUserStore(state => state.verifyUser);
+ const verify = useUserStore((state) => state.verifyUser);
const refValues = useRef({
subsriptionSuccessListener: null,
subsriptionErrorListener: null,
@@ -61,18 +65,22 @@ export const useAppEvents = () => {
isReconnecting: false
});
- const onLoadingAttachmentProgress = data => {
- console.log('loading', data);
- useAttachmentStore.getState().setLoading(data.total === data.current ? null : data);
+ const onLoadingAttachmentProgress = (data) => {
+ console.log("loading", data);
+ useAttachmentStore
+ .getState()
+ .setLoading(data.total === data.current ? null : data);
};
const onFileEncryptionProgress = ({ total, progress }) => {
- console.log('encryption progress: ', (progress / total).toFixed(2));
- useAttachmentStore.getState().setEncryptionProgress((progress / total).toFixed(2));
+ console.log("encryption progress: ", (progress / total).toFixed(2));
+ useAttachmentStore
+ .getState()
+ .setEncryptionProgress((progress / total).toFixed(2));
};
const onSyncProgress = ({ type, total, current }) => {
console.log(type, total, current);
- if (type !== 'download') return;
+ if (type !== "download") return;
if (total < 10 || current % 10 === 0) {
initAfterSync();
}
@@ -83,22 +91,31 @@ export const useAppEvents = () => {
const eventManager = db?.eventManager;
eventManager?.subscribe(EVENTS.syncCompleted, onSyncComplete);
db?.eventManager?.subscribe(EVENTS.syncProgress, onSyncProgress);
- db?.eventManager?.subscribe(EVENTS.databaseSyncRequested, onRequestPartialSync);
+ db?.eventManager?.subscribe(
+ EVENTS.databaseSyncRequested,
+ onRequestPartialSync
+ );
}
return () => {
const eventManager = db?.eventManager;
eventManager?.unsubscribe(EVENTS.syncCompleted, onSyncComplete);
eventManager?.unsubscribe(EVENTS.syncProgress, onSyncProgress);
- eventManager?.unsubscribe(EVENTS.databaseSyncRequested, onRequestPartialSync);
+ eventManager?.unsubscribe(
+ EVENTS.databaseSyncRequested,
+ onRequestPartialSync
+ );
};
}, [loading]);
useEffect(() => {
let subs = [
Appearance.addChangeListener(SettingsService.setTheme),
- Linking.addEventListener('url', onUrlRecieved),
- SodiumEventEmitter.addListener('onSodiumProgress', onFileEncryptionProgress)
+ Linking.addEventListener("url", onUrlRecieved),
+ SodiumEventEmitter.addListener(
+ "onSodiumProgress",
+ onFileEncryptionProgress
+ )
];
EV.subscribe(EVENTS.appRefreshRequested, onSyncComplete);
@@ -108,10 +125,10 @@ export const useAppEvents = () => {
EV.subscribe(EVENTS.userCheckStatus, PremiumService.onUserStatusCheck);
EV.subscribe(EVENTS.userSubscriptionUpdated, onAccountStatusChange);
EV.subscribe(EVENTS.attachmentsLoading, onLoadingAttachmentProgress);
- eSubscribeEvent('userLoggedIn', onUserUpdated);
+ eSubscribeEvent("userLoggedIn", onUserUpdated);
return () => {
- eUnSubscribeEvent('userLoggedIn', onUserUpdated);
+ eUnSubscribeEvent("userLoggedIn", onUserUpdated);
EV.unsubscribe(EVENTS.appRefreshRequested, onSyncComplete);
EV.unsubscribe(EVENTS.userSessionExpired, onSessionExpired);
@@ -122,7 +139,7 @@ export const useAppEvents = () => {
EV.unsubscribe(EVENTS.userSubscriptionUpdated, onAccountStatusChange);
EV.unsubscribeAll();
- subs.forEach(sub => sub?.remove());
+ subs.forEach((sub) => sub?.remove());
};
}, []);
@@ -130,26 +147,27 @@ export const useAppEvents = () => {
await SettingsService.set({
sessionExpired: true
});
- eSendEvent('session_expired');
+ eSendEvent("session_expired");
};
useEffect(() => {
let sub;
if (!loading && !verify) {
setTimeout(() => {
- sub = AppState.addEventListener('change', onAppStateChanged);
+ sub = AppState.addEventListener("change", onAppStateChanged);
}, 1000);
(async () => {
try {
let url = await Linking.getInitialURL();
- if (url?.startsWith('https://app.notesnook.com/account/verified')) {
+ if (url?.startsWith("https://app.notesnook.com/account/verified")) {
await onEmailVerified();
}
await onUserUpdated();
} catch (e) {}
})();
- refValues.current.removeInternetStateListener =
- NetInfo.addEventListener(onInternetStateChanged);
+ refValues.current.removeInternetStateListener = NetInfo.addEventListener(
+ onInternetStateChanged
+ );
}
return () => {
refValues.current?.removeInternetStateListener &&
@@ -159,16 +177,16 @@ export const useAppEvents = () => {
};
}, [loading, verify]);
- const onInternetStateChanged = async state => {
+ const onInternetStateChanged = async (state) => {
if (!syncedOnLaunch.current) return;
reconnectSSE(state);
};
const onSyncComplete = async () => {
- console.log('sync complete');
+ console.log("sync complete");
initAfterSync();
setLastSynced(await db.lastSynced());
- eSendEvent(eCloseProgressDialog, 'sync_progress');
+ eSendEvent(eCloseProgressDialog, "sync_progress");
let id = useEditorStore.getState().currentEditingNote;
let note = id && db.notes.note(id).data;
if (note) {
@@ -176,10 +194,10 @@ export const useAppEvents = () => {
}
};
- const onUrlRecieved = async res => {
- let url = res ? res.url : '';
+ const onUrlRecieved = async (res) => {
+ let url = res ? res.url : "";
try {
- if (url.startsWith('https://app.notesnook.com/account/verified')) {
+ if (url.startsWith("https://app.notesnook.com/account/verified")) {
await onEmailVerified();
} else {
return;
@@ -195,7 +213,7 @@ export const useAppEvents = () => {
userEmailConfirmed: true
});
await PremiumService.setPremiumStatus();
- Walkthrough.present('emailconfirmed', false, true);
+ Walkthrough.present("emailconfirmed", false, true);
if (user?.isEmailConfirmed) {
clearMessage();
}
@@ -203,7 +221,7 @@ export const useAppEvents = () => {
const attachIAPListeners = async () => {
await RNIap.initConnection()
- .catch(e => null)
+ .catch((e) => null)
.then(async () => {
refValues.current.subsriptionSuccessListener =
RNIap.purchaseUpdatedListener(onSuccessfulSubscription);
@@ -212,25 +230,25 @@ export const useAppEvents = () => {
});
};
- const onAccountStatusChange = async userStatus => {
+ const onAccountStatusChange = async (userStatus) => {
if (!PremiumService.get() && userStatus.type === 5) {
PremiumService.subscriptions.clear();
- Walkthrough.present('prouser', false, true);
+ Walkthrough.present("prouser", false, true);
}
await PremiumService.setPremiumStatus();
};
const onRequestPartialSync = async (full, force) => {
- console.log('auto sync request', full, force);
+ console.log("auto sync request", full, force);
if (full || force) {
- await Sync.run('global', force, full);
+ await Sync.run("global", force, full);
} else {
- await Sync.run('global', false, false);
+ await Sync.run("global", false, false);
}
};
- const onLogout = async reason => {
- console.log('LOGOUT', reason);
+ const onLogout = async (reason) => {
+ console.log("LOGOUT", reason);
};
const unsubIAP = () => {
@@ -244,7 +262,7 @@ export const useAppEvents = () => {
}
};
- const onUserUpdated = async login => {
+ const onUserUpdated = async (login) => {
console.log(`onUserUpdated: ${login}`);
let user;
try {
@@ -281,7 +299,7 @@ export const useAppEvents = () => {
});
}
} catch (e) {
- ToastEvent.error(e, 'An error occured', 'global');
+ ToastEvent.error(e, "An error occured", "global");
}
user = await db.user.getUser();
@@ -298,31 +316,31 @@ export const useAppEvents = () => {
syncedOnLaunch.current = true;
};
- const onSuccessfulSubscription = async subscription => {
+ const onSuccessfulSubscription = async (subscription) => {
await PremiumService.subscriptions.set(subscription);
await PremiumService.subscriptions.verify(subscription);
};
- const onSubscriptionError = async error => {
+ const onSubscriptionError = async (error) => {
ToastEvent.show({
- heading: 'Failed to subscribe',
- type: 'error',
+ heading: "Failed to subscribe",
+ type: "error",
message: error.message,
- context: 'local'
+ context: "local"
});
};
- const onAppStateChanged = async state => {
- console.log('onAppStateChanged');
- if (state === 'active') {
+ const onAppStateChanged = async (state) => {
+ console.log("onAppStateChanged");
+ if (state === "active") {
updateStatusBarColor();
if (
- SettingsService.get().appLockMode !== 'background' &&
+ SettingsService.get().appLockMode !== "background" &&
!SettingsService.get().privacyScreen
) {
enabled(false);
}
- if (SettingsService.get().appLockMode === 'background') {
+ if (SettingsService.get().appLockMode === "background") {
if (useSettingStore.getState().requestBiometrics) {
useSettingStore.getState().setRequestBiometrics(false);
return;
@@ -331,7 +349,7 @@ export const useAppEvents = () => {
await reconnectSSE();
await checkIntentState();
- MMKV.removeItem('appState');
+ MMKV.removeItem("appState");
let user = await db.user.getUser();
if (user && !user?.isEmailConfirmed) {
try {
@@ -344,12 +362,12 @@ export const useAppEvents = () => {
} else {
let id = useEditorStore.getState().currentEditingNote;
let note = id && db.notes.note(id).data;
- if (note?.locked && SettingsService.get().appLockMode === 'background') {
+ if (note?.locked && SettingsService.get().appLockMode === "background") {
eSendEvent(eClearEditor);
}
await storeAppState();
if (
- SettingsService.get().appLockMode === 'background' &&
+ SettingsService.get().appLockMode === "background" &&
!useSettingStore.getState().requestBiometrics &&
!useUserStore.getState().verifyUser
) {
@@ -357,7 +375,7 @@ export const useAppEvents = () => {
}
if (
SettingsService.get().privacyScreen ||
- SettingsService.get().appLockMode === 'background'
+ SettingsService.get().appLockMode === "background"
) {
!useSettingStore.getState().requestBiometrics ? enabled(true) : null;
}
@@ -375,7 +393,7 @@ export const useAppEvents = () => {
}
refValues.current.isReconnecting = true;
let state = connection;
- console.log('SSE:', 'TRYING TO RECONNECT');
+ console.log("SSE:", "TRYING TO RECONNECT");
try {
if (!state) {
state = await NetInfo.fetch();
@@ -402,32 +420,35 @@ export const useAppEvents = () => {
movedAway: editorState().movedAway,
timestamp: Date.now()
});
- MMKV.setString('appState', state);
+ MMKV.setString("appState", state);
}
}
async function checkIntentState() {
try {
- let notesAddedFromIntent = MMKV.getString('notesAddedFromIntent');
- let shareExtensionOpened = MMKV.getString('shareExtensionOpened');
+ let notesAddedFromIntent = MMKV.getString("notesAddedFromIntent");
+ let shareExtensionOpened = MMKV.getString("shareExtensionOpened");
if (notesAddedFromIntent) {
- if (Platform.OS === 'ios') {
+ if (Platform.OS === "ios") {
await db.init();
await db.notes.init();
}
useNoteStore.getState().setNotes();
eSendEvent(refreshNotesPage);
- MMKV.removeItem('notesAddedFromIntent');
+ MMKV.removeItem("notesAddedFromIntent");
initAfterSync();
eSendEvent(refreshNotesPage);
}
- console.log('CHECK INTENT STATE', notesAddedFromIntent || shareExtensionOpened);
+ console.log(
+ "CHECK INTENT STATE",
+ notesAddedFromIntent || shareExtensionOpened
+ );
if (notesAddedFromIntent || shareExtensionOpened) {
let id = useEditorStore.getState().currentEditingNote;
let note = id && db.notes.note(id).data;
- eSendEvent('loadingNote', note);
- eSendEvent('webview_reset');
- MMKV.removeItem('shareExtensionOpened');
+ eSendEvent("loadingNote", note);
+ eSendEvent("webview_reset");
+ MMKV.removeItem("shareExtensionOpened");
}
} catch (e) {
console.log(e);
diff --git a/apps/mobile/app/hooks/use-app-state.ts b/apps/mobile/app/hooks/use-app-state.ts
index fe0447461..577c5104b 100644
--- a/apps/mobile/app/hooks/use-app-state.ts
+++ b/apps/mobile/app/hooks/use-app-state.ts
@@ -1,5 +1,5 @@
-import { useEffect, useState } from 'react';
-import { AppState, AppStateStatus } from 'react-native';
+import { useEffect, useState } from "react";
+import { AppState, AppStateStatus } from "react-native";
export function useAppState() {
const currentState = AppState.currentState;
@@ -10,16 +10,16 @@ export function useAppState() {
setAppState(newState);
}
- const subscription = AppState.addEventListener('change', onChange);
+ const subscription = AppState.addEventListener("change", onChange);
return () => {
// @ts-expect-error - React Native >= 0.65
- if (typeof subscription?.remove === 'function') {
+ if (typeof subscription?.remove === "function") {
// @ts-expect-error - need update @types/react-native@0.65.x
subscription.remove();
} else {
// React Native < 0.65
- AppState.removeEventListener('change', onChange);
+ AppState.removeEventListener("change", onChange);
}
};
}, []);
diff --git a/apps/mobile/app/hooks/use-attachment-progress.js b/apps/mobile/app/hooks/use-attachment-progress.js
index 9e1530313..42ce51463 100644
--- a/apps/mobile/app/hooks/use-attachment-progress.js
+++ b/apps/mobile/app/hooks/use-attachment-progress.js
@@ -1,12 +1,12 @@
-import { useEffect, useState } from 'react';
-import { useAttachmentStore } from '../stores/use-attachment-store';
+import { useEffect, useState } from "react";
+import { useAttachmentStore } from "../stores/use-attachment-store";
export const useAttachmentProgress = (attachment, encryption) => {
- const progress = useAttachmentStore(state => state.progress);
+ const progress = useAttachmentStore((state) => state.progress);
const [currentProgress, setCurrentProgress] = useState(
encryption
? {
- type: 'encrypt'
+ type: "encrypt"
}
: null
);
@@ -15,14 +15,14 @@ export const useAttachmentProgress = (attachment, encryption) => {
let prog = progress[attachment.metadata.hash];
if (prog) {
let type = prog.type;
- let loaded = prog.type === 'download' ? prog.recieved : prog.sent;
+ let loaded = prog.type === "download" ? prog.recieved : prog.sent;
prog = loaded / prog.total;
prog = (prog * 100).toFixed(0);
- console.log('progress: ', prog);
+ console.log("progress: ", prog);
console.log(prog);
setCurrentProgress({
value: prog,
- percent: prog + '%',
+ percent: prog + "%",
type: type
});
} else {
diff --git a/apps/mobile/app/hooks/use-delay-layout.ts b/apps/mobile/app/hooks/use-delay-layout.ts
index 9d11a03b2..f432f9fa7 100644
--- a/apps/mobile/app/hooks/use-delay-layout.ts
+++ b/apps/mobile/app/hooks/use-delay-layout.ts
@@ -1,5 +1,5 @@
-import { useEffect, useState } from 'react';
-import { InteractionManager } from 'react-native';
+import { useEffect, useState } from "react";
+import { InteractionManager } from "react-native";
export const useDelayLayout = (delay: number) => {
const [loading, setLoading] = useState(true);
diff --git a/apps/mobile/app/hooks/use-editor-tags.ts b/apps/mobile/app/hooks/use-editor-tags.ts
index e288ff3ab..c380174b5 100644
--- a/apps/mobile/app/hooks/use-editor-tags.ts
+++ b/apps/mobile/app/hooks/use-editor-tags.ts
@@ -1,15 +1,17 @@
-import { useEffect, useState } from 'react';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../services/event-manager';
-import { useEditorStore } from '../stores/use-editor-store';
-import { useTagStore } from '../stores/use-tag-store';
-import { db } from '../common/database';
+import { useEffect, useState } from "react";
+import { eSubscribeEvent, eUnSubscribeEvent } from "../services/event-manager";
+import { useEditorStore } from "../stores/use-editor-store";
+import { useTagStore } from "../stores/use-tag-store";
+import { db } from "../common/database";
/**
* A hook that injects/removes tags from tags bar in editor
*/
const useEditorTags = () => {
- const currentEditingNote = useEditorStore(state => state.currentEditingNote);
- const tags = useTagStore(state => state.tags);
+ const currentEditingNote = useEditorStore(
+ (state) => state.currentEditingNote
+ );
+ const tags = useTagStore((state) => state.tags);
const [note, setNote] = useState(null);
const [noteTags, setNoteTags] = useState([]);
@@ -35,9 +37,9 @@ const useEditorTags = () => {
}
useEffect(() => {
- eSubscribeEvent('updateTags', load);
+ eSubscribeEvent("updateTags", load);
return () => {
- eUnSubscribeEvent('updateTags', load);
+ eUnSubscribeEvent("updateTags", load);
};
}, [noteTags]);
diff --git a/apps/mobile/app/hooks/use-immediate.ts b/apps/mobile/app/hooks/use-immediate.ts
index 183328166..89e7bd0ec 100644
--- a/apps/mobile/app/hooks/use-immediate.ts
+++ b/apps/mobile/app/hooks/use-immediate.ts
@@ -1,4 +1,4 @@
-import { DependencyList, EffectCallback, useEffect } from 'react';
+import { DependencyList, EffectCallback, useEffect } from "react";
const useImmediateEffect = (callback: EffectCallback, deps: DependencyList) => {
useEffect(() => {
diff --git a/apps/mobile/app/hooks/use-is-floating-keyboard.ts b/apps/mobile/app/hooks/use-is-floating-keyboard.ts
index c429fcdfd..a58a35056 100644
--- a/apps/mobile/app/hooks/use-is-floating-keyboard.ts
+++ b/apps/mobile/app/hooks/use-is-floating-keyboard.ts
@@ -1,5 +1,5 @@
-import { useEffect, useState } from 'react';
-import { Keyboard, KeyboardEvent, useWindowDimensions } from 'react-native';
+import { useEffect, useState } from "react";
+import { Keyboard, KeyboardEvent, useWindowDimensions } from "react-native";
/**
* A hook that detects floating keyboard on iPad
@@ -15,7 +15,10 @@ const useIsFloatingKeyboard = () => {
};
useEffect(() => {
- let sub1 = Keyboard.addListener('keyboardWillChangeFrame', onKeyboardWillChangeFrame);
+ let sub1 = Keyboard.addListener(
+ "keyboardWillChangeFrame",
+ onKeyboardWillChangeFrame
+ );
return () => {
sub1?.remove();
};
diff --git a/apps/mobile/app/hooks/use-keyboard.ts b/apps/mobile/app/hooks/use-keyboard.ts
index 4cdf3bdb3..b9412a84a 100644
--- a/apps/mobile/app/hooks/use-keyboard.ts
+++ b/apps/mobile/app/hooks/use-keyboard.ts
@@ -1,5 +1,5 @@
-import { useEffect, useState } from 'react';
-import { Keyboard, KeyboardEventListener, ScreenRect } from 'react-native';
+import { useEffect, useState } from "react";
+import { Keyboard, KeyboardEventListener, ScreenRect } from "react-native";
const emptyCoordinates = Object.freeze({
screenX: 0,
@@ -20,18 +20,18 @@ export default function useKeyboard() {
}>(initialValue);
const [keyboardHeight, setKeyboardHeight] = useState(0);
- const handleKeyboardWillShow: KeyboardEventListener = e => {
+ const handleKeyboardWillShow: KeyboardEventListener = (e) => {
setCoordinates({ start: e.startCoordinates, end: e.endCoordinates });
};
- const handleKeyboardDidShow: KeyboardEventListener = e => {
+ const handleKeyboardDidShow: KeyboardEventListener = (e) => {
setShown(true);
setCoordinates({ start: e.startCoordinates, end: e.endCoordinates });
setKeyboardHeight(e.endCoordinates.height);
};
- const handleKeyboardWillHide: KeyboardEventListener = e => {
+ const handleKeyboardWillHide: KeyboardEventListener = (e) => {
setCoordinates({ start: e.startCoordinates, end: e.endCoordinates });
};
- const handleKeyboardDidHide: KeyboardEventListener = e => {
+ const handleKeyboardDidHide: KeyboardEventListener = (e) => {
setShown(false);
if (e) {
setCoordinates({ start: e.startCoordinates, end: e.endCoordinates });
@@ -43,14 +43,14 @@ export default function useKeyboard() {
useEffect(() => {
const subscriptions = [
- Keyboard.addListener('keyboardWillShow', handleKeyboardWillShow),
- Keyboard.addListener('keyboardDidShow', handleKeyboardDidShow),
- Keyboard.addListener('keyboardWillHide', handleKeyboardWillHide),
- Keyboard.addListener('keyboardDidHide', handleKeyboardDidHide)
+ Keyboard.addListener("keyboardWillShow", handleKeyboardWillShow),
+ Keyboard.addListener("keyboardDidShow", handleKeyboardDidShow),
+ Keyboard.addListener("keyboardWillHide", handleKeyboardWillHide),
+ Keyboard.addListener("keyboardDidHide", handleKeyboardDidHide)
];
return () => {
- subscriptions.forEach(subscription => subscription.remove());
+ subscriptions.forEach((subscription) => subscription.remove());
};
}, []);
return {
diff --git a/apps/mobile/app/hooks/use-navigation-focus.ts b/apps/mobile/app/hooks/use-navigation-focus.ts
index 07e35963a..d5ed52be0 100644
--- a/apps/mobile/app/hooks/use-navigation-focus.ts
+++ b/apps/mobile/app/hooks/use-navigation-focus.ts
@@ -1,5 +1,5 @@
-import { NativeStackNavigationProp } from '@react-navigation/native-stack';
-import { RefObject, useCallback, useEffect, useRef, useState } from 'react';
+import { NativeStackNavigationProp } from "@react-navigation/native-stack";
+import { RefObject, useCallback, useEffect, useRef, useState } from "react";
type NavigationFocus = {
onFocus?: (prev: RefObject) => boolean;
@@ -19,7 +19,7 @@ export const useNavigationFocus = (
const _onFocus = useCallback(() => {
setTimeout(
() => {
- console.log('on focus', prev);
+ console.log("on focus", prev);
let shouldFocus = onFocus ? onFocus(prev) : true;
if (shouldFocus) {
setFocused(true);
@@ -45,11 +45,11 @@ export const useNavigationFocus = (
useEffect(() => {
if (!navigation) return;
const subs = [
- navigation.addListener('focus', _onFocus),
- navigation.addListener('blur', _onBlur)
+ navigation.addListener("focus", _onFocus),
+ navigation.addListener("blur", _onBlur)
];
return () => {
- subs.forEach(sub => sub());
+ subs.forEach((sub) => sub());
};
}, [navigation]);
diff --git a/apps/mobile/app/hooks/use-pricing.ts b/apps/mobile/app/hooks/use-pricing.ts
index 4481b703e..e27ba51fb 100644
--- a/apps/mobile/app/hooks/use-pricing.ts
+++ b/apps/mobile/app/hooks/use-pricing.ts
@@ -1,8 +1,8 @@
-import { useEffect, useState } from 'react';
-import { Platform } from 'react-native';
-import { Subscription } from 'react-native-iap';
-import PremiumService from '../services/premium';
-import { db } from '../common/database';
+import { useEffect, useState } from "react";
+import { Platform } from "react-native";
+import { Subscription } from "react-native-iap";
+import PremiumService from "../services/premium";
+import { db } from "../common/database";
type PurchaseInfo = {
country: string;
@@ -13,29 +13,39 @@ type PurchaseInfo = {
const skuInfos: { [name: string]: PurchaseInfo | undefined } = {};
-export const usePricing = (period: 'monthly' | 'yearly') => {
+export const usePricing = (period: "monthly" | "yearly") => {
const [current, setCurrent] = useState<{
period: string;
info?: PurchaseInfo;
product?: Subscription;
}>();
- const getDefaultSku = (period: 'monthly' | 'yearly') => {
- return period === 'monthly'
- ? 'com.streetwriters.notesnook.sub.mo'
- : 'com.streetwriters.notesnook.sub.yr';
+ const getDefaultSku = (period: "monthly" | "yearly") => {
+ return period === "monthly"
+ ? "com.streetwriters.notesnook.sub.mo"
+ : "com.streetwriters.notesnook.sub.yr";
};
useEffect(() => {
(async () => {
let skuInfo =
skuInfos[period] ||
- (await db.pricing?.sku(Platform.OS === 'android' ? 'android' : 'ios', period));
+ (await db.pricing?.sku(
+ Platform.OS === "android" ? "android" : "ios",
+ period
+ ));
skuInfos[period] = skuInfo;
let products = (await PremiumService.getProducts()) as Subscription[];
- let product = products.find(p => p.productId === skuInfo?.sku);
- if (!product) product = products.find(p => p.productId === getDefaultSku(period));
- console.log('skuInfos: ', skuInfos, product?.productId, product?.price, products.length);
+ let product = products.find((p) => p.productId === skuInfo?.sku);
+ if (!product)
+ product = products.find((p) => p.productId === getDefaultSku(period));
+ console.log(
+ "skuInfos: ",
+ skuInfos,
+ product?.productId,
+ product?.price,
+ products.length
+ );
setCurrent({
info: skuInfo,
period,
diff --git a/apps/mobile/app/hooks/use-rotator.ts b/apps/mobile/app/hooks/use-rotator.ts
index d793cc3ff..7bd25639a 100644
--- a/apps/mobile/app/hooks/use-rotator.ts
+++ b/apps/mobile/app/hooks/use-rotator.ts
@@ -1,4 +1,4 @@
-import { useEffect, useRef, useState } from 'react';
+import { useEffect, useRef, useState } from "react";
/**
* A hook that can be used to rotate values in an array.
diff --git a/apps/mobile/app/hooks/use-sync-progress.ts b/apps/mobile/app/hooks/use-sync-progress.ts
index 8b53978ad..833b80a37 100644
--- a/apps/mobile/app/hooks/use-sync-progress.ts
+++ b/apps/mobile/app/hooks/use-sync-progress.ts
@@ -1,10 +1,10 @@
//@ts-ignore
-import { EVENTS } from '@streetwriters/notesnook-core/common';
-import { createRef, useCallback, useEffect, useRef, useState } from 'react';
-import { db } from '../common/database';
+import { EVENTS } from "@streetwriters/notesnook-core/common";
+import { createRef, useCallback, useEffect, useRef, useState } from "react";
+import { db } from "../common/database";
export type SyncProgressEventType = {
- type: 'upload' | 'download';
+ type: "upload" | "download";
total: number;
current: number;
};
@@ -13,11 +13,14 @@ const useSyncProgress = () => {
const [progress, setProgress] = useState();
const EV = db.eventManager;
- const onProgress = useCallback(({ type, current, total }: SyncProgressEventType) => {
- //@ts-ignore
+ const onProgress = useCallback(
+ ({ type, current, total }: SyncProgressEventType) => {
+ //@ts-ignore
- setProgress({ type, current, total });
- }, []);
+ setProgress({ type, current, total });
+ },
+ []
+ );
const onSyncComplete = () => {
setProgress(undefined);
diff --git a/apps/mobile/app/hooks/use-timer.ts b/apps/mobile/app/hooks/use-timer.ts
index c9dd2e96d..2b83f6c42 100644
--- a/apps/mobile/app/hooks/use-timer.ts
+++ b/apps/mobile/app/hooks/use-timer.ts
@@ -1,9 +1,9 @@
-import { useEffect, useRef, useState } from 'react';
+import { useEffect, useRef, useState } from "react";
const timers: { [name: string]: number } = {};
function getSecondsLeft(id?: string) {
- let endTime = timers[id || ''];
+ let endTime = timers[id || ""];
if (!endTime) return 0;
if (endTime < Date.now()) return 0;
console.log((endTime - Date.now()) / 1000);
@@ -16,10 +16,10 @@ const useTimer = (initialId?: string) => {
const interval = useRef();
const start = (sec: number, currentId = id) => {
- console.log('started', sec, id);
+ console.log("started", sec, id);
if (!currentId) return;
timers[currentId] = Date.now() + sec * 1000;
- console.log('timers:', timers[currentId]);
+ console.log("timers:", timers[currentId]);
setSeconds(getSecondsLeft(id));
};
diff --git a/apps/mobile/app/hooks/use-tooltip.ts b/apps/mobile/app/hooks/use-tooltip.ts
index 1f0e7a12a..ca1f29511 100644
--- a/apps/mobile/app/hooks/use-tooltip.ts
+++ b/apps/mobile/app/hooks/use-tooltip.ts
@@ -1,11 +1,15 @@
-import { RefObject, useEffect, useRef } from 'react';
-import { Platform } from 'react-native';
+import { RefObject, useEffect, useRef } from "react";
+import { Platform } from "react-native";
//@ts-ignore
-import RNTooltips from 'react-native-tooltips';
-import { useThemeStore } from '../stores/use-theme-store';
-import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../services/event-manager';
-import { Popup } from '../services/tip-manager';
-import useKeyboard from './use-keyboard';
+import RNTooltips from "react-native-tooltips";
+import { useThemeStore } from "../stores/use-theme-store";
+import {
+ eSendEvent,
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../services/event-manager";
+import { Popup } from "../services/tip-manager";
+import useKeyboard from "./use-keyboard";
let currentTargets: number[] = [];
let timers: NodeJS.Timeout[] = [];
@@ -14,10 +18,10 @@ let timers: NodeJS.Timeout[] = [];
* A function to hide all native tooltips
*/
export const hideAllTooltips = async () => {
- timers.forEach(t => t && clearTimeout(t));
+ timers.forEach((t) => t && clearTimeout(t));
for (let target of currentTargets) {
if (target) {
- console.log('dimissing targets', target);
+ console.log("dimissing targets", target);
RNTooltips.Dismiss(target);
target = -1;
}
@@ -30,7 +34,7 @@ export const hideAllTooltips = async () => {
* @returns
*/
const useTooltip = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const parent = useRef();
let keyboard = useKeyboard();
@@ -56,11 +60,11 @@ const useTooltip = () => {
currentTargets.push(target.current._nativeTag);
timers[timers.length] = setTimeout(() => {
//TipManager.markPopupUsed(popup.id);
- console.log('tooltip showing', popup.text);
+ console.log("tooltip showing", popup.text);
RNTooltips.Show(target.current, parent.current, {
text: popup.text,
- tintColor: colors.night ? colors.nav : '#404040',
- corner: Platform.OS === 'ios' ? 5 : 50,
+ tintColor: colors.night ? colors.nav : "#404040",
+ corner: Platform.OS === "ios" ? 5 : 50,
textSize: 15,
position: positions[position],
duration: duration || 10000,
@@ -74,12 +78,18 @@ const useTooltip = () => {
return { parent, show };
};
-type TTooltipIdentifiers = 'sectionheader' | 'searchreplace' | 'notebookshortcut';
+type TTooltipIdentifiers =
+ | "sectionheader"
+ | "searchreplace"
+ | "notebookshortcut";
/**
* A hook that helps in listening to tooltip show/hide requests and respond.
*/
-export const useTooltipHandler = (id: TTooltipIdentifiers, callback: () => void) => {
+export const useTooltipHandler = (
+ id: TTooltipIdentifiers,
+ callback: () => void
+) => {
useEffect(() => {
if (!id) return;
eSubscribeEvent(id, callback);
diff --git a/apps/mobile/app/hooks/use-vault-status.js b/apps/mobile/app/hooks/use-vault-status.js
index c34f00e39..2cd2d3f8c 100644
--- a/apps/mobile/app/hooks/use-vault-status.js
+++ b/apps/mobile/app/hooks/use-vault-status.js
@@ -1,7 +1,7 @@
-import React, { useCallback, useEffect } from 'react';
-import BiometicService from '../services/biometrics';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../services/event-manager';
-import { db } from '../common/database';
+import React, { useCallback, useEffect } from "react";
+import BiometicService from "../services/biometrics";
+import { eSubscribeEvent, eUnSubscribeEvent } from "../services/event-manager";
+import { db } from "../common/database";
const VaultStatusCache = {
exists: false,
@@ -13,7 +13,7 @@ export const useVaultStatus = () => {
const [vaultStatus, setVaultStatus] = React.useState(VaultStatusCache);
const checkVaultStatus = useCallback(() => {
- db.vault.exists().then(async exists => {
+ db.vault.exists().then(async (exists) => {
let available = await BiometicService.isBiometryAvailable();
let fingerprint = await BiometicService.hasInternetCredentials();
if (
@@ -32,9 +32,9 @@ export const useVaultStatus = () => {
useEffect(() => {
checkVaultStatus();
- eSubscribeEvent('vaultUpdated', () => checkVaultStatus());
+ eSubscribeEvent("vaultUpdated", () => checkVaultStatus());
return () => {
- eUnSubscribeEvent('vaultUpdated', () => checkVaultStatus());
+ eUnSubscribeEvent("vaultUpdated", () => checkVaultStatus());
};
}, []);
diff --git a/apps/mobile/app/navigation/index.js b/apps/mobile/app/navigation/index.js
index 79ec2332c..53ad6c5c5 100644
--- a/apps/mobile/app/navigation/index.js
+++ b/apps/mobile/app/navigation/index.js
@@ -1,19 +1,21 @@
-import React from 'react';
-import { SafeAreaView } from 'react-native';
-import DelayLayout from '../components/delay-layout';
-import DialogProvider from '../components/dialog-provider';
-import { Header } from '../components/header';
-import { Toast } from '../components/toast';
-import { useNoteStore } from '../stores/use-notes-store';
-import { useSettingStore } from '../stores/use-setting-store';
-import { useThemeStore } from '../stores/use-theme-store';
-import { TabsHolder } from './tabs-holder';
+import React from "react";
+import { SafeAreaView } from "react-native";
+import DelayLayout from "../components/delay-layout";
+import DialogProvider from "../components/dialog-provider";
+import { Header } from "../components/header";
+import { Toast } from "../components/toast";
+import { useNoteStore } from "../stores/use-notes-store";
+import { useSettingStore } from "../stores/use-setting-store";
+import { useThemeStore } from "../stores/use-theme-store";
+import { TabsHolder } from "./tabs-holder";
export const ApplicationHolder = React.memo(
() => {
- const loading = useNoteStore(state => state.loading);
- const introCompleted = useSettingStore(state => state.settings.introCompleted);
- const colors = useThemeStore(state => state.colors);
+ const loading = useNoteStore((state) => state.loading);
+ const introCompleted = useSettingStore(
+ (state) => state.settings.introCompleted
+ );
+ const colors = useThemeStore((state) => state.colors);
return (
<>
diff --git a/apps/mobile/app/navigation/navigation-stack.js b/apps/mobile/app/navigation/navigation-stack.js
index baf3076e3..d995ec772 100644
--- a/apps/mobile/app/navigation/navigation-stack.js
+++ b/apps/mobile/app/navigation/navigation-stack.js
@@ -1,32 +1,32 @@
-import { NavigationContainer } from '@react-navigation/native';
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import * as React from 'react';
-import Container from '../components/container';
-import Intro from '../components/intro';
-import Favorites from '../screens/favorites';
-import Home from '../screens/home';
-import Notebook from '../screens/notebook';
-import Notebooks from '../screens/notebooks';
-import { ColoredNotes } from '../screens/notes/colored';
-import { Monographs } from '../screens/notes/monographs';
-import { TaggedNotes } from '../screens/notes/tagged';
-import { TopicNotes } from '../screens/notes/topic-notes';
-import { Search } from '../screens/search';
-import Settings from '../screens/settings';
-import AppLock from '../screens/settings/app-lock';
-import Tags from '../screens/tags';
-import Trash from '../screens/trash';
-import { eSendEvent } from '../services/event-manager';
-import SettingsService from '../services/settings';
-import useNavigationStore from '../stores/use-navigation-store';
-import { useSelectionStore } from '../stores/use-selection-store';
-import { useThemeStore } from '../stores/use-theme-store';
-import { history } from '../utils';
-import { rootNavigatorRef } from '../utils/global-refs';
-import { hideAllTooltips } from '../hooks/use-tooltip';
-import { useWindowDimensions } from 'react-native';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { useSettingStore } from '../stores/use-setting-store';
+import { NavigationContainer } from "@react-navigation/native";
+import { createNativeStackNavigator } from "@react-navigation/native-stack";
+import * as React from "react";
+import Container from "../components/container";
+import Intro from "../components/intro";
+import Favorites from "../screens/favorites";
+import Home from "../screens/home";
+import Notebook from "../screens/notebook";
+import Notebooks from "../screens/notebooks";
+import { ColoredNotes } from "../screens/notes/colored";
+import { Monographs } from "../screens/notes/monographs";
+import { TaggedNotes } from "../screens/notes/tagged";
+import { TopicNotes } from "../screens/notes/topic-notes";
+import { Search } from "../screens/search";
+import Settings from "../screens/settings";
+import AppLock from "../screens/settings/app-lock";
+import Tags from "../screens/tags";
+import Trash from "../screens/trash";
+import { eSendEvent } from "../services/event-manager";
+import SettingsService from "../services/settings";
+import useNavigationStore from "../stores/use-navigation-store";
+import { useSelectionStore } from "../stores/use-selection-store";
+import { useThemeStore } from "../stores/use-theme-store";
+import { history } from "../utils";
+import { rootNavigatorRef } from "../utils/global-refs";
+import { hideAllTooltips } from "../hooks/use-tooltip";
+import { useWindowDimensions } from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { useSettingStore } from "../stores/use-setting-store";
const NativeStack = createNativeStackNavigator();
const IntroStack = createNativeStackNavigator();
@@ -40,18 +40,18 @@ const IntroStack = createNativeStackNavigator();
*/
const IntroStackNavigator = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
@@ -61,10 +61,12 @@ const IntroStackNavigator = () => {
const Tabs = React.memo(
() => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const homepage = SettingsService.get().homepage;
- const introCompleted = useSettingStore(state => state.settings.introCompleted);
- const height = useSettingStore(state => state.dimensions.height);
+ const introCompleted = useSettingStore(
+ (state) => state.settings.introCompleted
+ );
+ const height = useSettingStore((state) => state.dimensions.height);
const insets = useSafeAreaInsets();
const screenHeight = height - (50 + insets.top + insets.bottom);
React.useEffect(() => {
@@ -76,12 +78,12 @@ const Tabs = React.memo(
return (
null}
- initialRouteName={!introCompleted ? 'Welcome' : homepage}
+ initialRouteName={!introCompleted ? "Welcome" : homepage}
backBehavior="history"
screenOptions={{
headerShown: false,
lazy: false,
- animation: 'none',
+ animation: "none",
contentStyle: {
backgroundColor: colors.bg,
height: !introCompleted ? undefined : screenHeight
@@ -91,16 +93,52 @@ const Tabs = React.memo(
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
);
},
@@ -109,19 +147,22 @@ const Tabs = React.memo(
export const NavigationStack = React.memo(
() => {
- const clearSelection = useSelectionStore(state => state.clearSelection);
+ const clearSelection = useSelectionStore((state) => state.clearSelection);
const onStateChange = React.useCallback(() => {
if (history.selectionMode) {
clearSelection(true);
}
hideAllTooltips();
- eSendEvent('navigate');
+ eSendEvent("navigate");
});
return (
-
+
diff --git a/apps/mobile/app/navigation/tabs-holder.js b/apps/mobile/app/navigation/tabs-holder.js
index 31241edb8..93c15e317 100644
--- a/apps/mobile/app/navigation/tabs-holder.js
+++ b/apps/mobile/app/navigation/tabs-holder.js
@@ -1,58 +1,71 @@
-import { activateKeepAwake, deactivateKeepAwake } from '@sayem314/react-native-keep-awake';
-import React, { useEffect, useRef, useState } from 'react';
-import { Platform, View, StatusBar } from 'react-native';
+import {
+ activateKeepAwake,
+ deactivateKeepAwake
+} from "@sayem314/react-native-keep-awake";
+import React, { useEffect, useRef, useState } from "react";
+import { Platform, View, StatusBar } from "react-native";
import {
addSpecificOrientationListener,
getInitialOrientation,
getSpecificOrientation,
removeSpecificOrientationListener
-} from 'react-native-orientation';
-import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { notesnook } from '../../e2e/test.ids';
-import { SideMenu } from '../components/side-menu';
-import { FluidTabs } from '../components/tabs';
-import { editorController, editorState } from '../screens/editor/tiptap/utils';
-import { EditorWrapper } from '../screens/editor/wrapper';
-import { DDS } from '../services/device-detection';
-import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../services/event-manager';
-import { useEditorStore } from '../stores/use-editor-store';
-import { useSettingStore } from '../stores/use-setting-store';
-import { useThemeStore } from '../stores/use-theme-store';
-import { setWidthHeight } from '../utils';
-import { db } from '../common/database';
+} from "react-native-orientation";
+import Animated, {
+ useAnimatedStyle,
+ useSharedValue,
+ withTiming
+} from "react-native-reanimated";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { notesnook } from "../../e2e/test.ids";
+import { SideMenu } from "../components/side-menu";
+import { FluidTabs } from "../components/tabs";
+import { editorController, editorState } from "../screens/editor/tiptap/utils";
+import { EditorWrapper } from "../screens/editor/wrapper";
+import { DDS } from "../services/device-detection";
+import {
+ eSendEvent,
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../services/event-manager";
+import { useEditorStore } from "../stores/use-editor-store";
+import { useSettingStore } from "../stores/use-setting-store";
+import { useThemeStore } from "../stores/use-theme-store";
+import { setWidthHeight } from "../utils";
+import { db } from "../common/database";
import {
eClearEditor,
eCloseFullscreenEditor,
eOnLoadNote,
eOpenFullscreenEditor
-} from '../utils/events';
-import { editorRef, tabBarRef } from '../utils/global-refs';
-import { hideAllTooltips } from '../hooks/use-tooltip';
-import { NavigationStack } from './navigation-stack';
+} from "../utils/events";
+import { editorRef, tabBarRef } from "../utils/global-refs";
+import { hideAllTooltips } from "../hooks/use-tooltip";
+import { NavigationStack } from "./navigation-stack";
export const TabsHolder = React.memo(
() => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
- const deviceMode = useSettingStore(state => state.deviceMode);
- const setFullscreen = useSettingStore(state => state.setFullscreen);
- const fullscreen = useSettingStore(state => state.fullscreen);
- const setDeviceModeState = useSettingStore(state => state.setDeviceMode);
- const dimensions = useSettingStore(state => state.dimensions);
- const setDimensions = useSettingStore(state => state.setDimensions);
+ const deviceMode = useSettingStore((state) => state.deviceMode);
+ const setFullscreen = useSettingStore((state) => state.setFullscreen);
+ const fullscreen = useSettingStore((state) => state.fullscreen);
+ const setDeviceModeState = useSettingStore((state) => state.setDeviceMode);
+ const dimensions = useSettingStore((state) => state.dimensions);
+ const setDimensions = useSettingStore((state) => state.setDimensions);
const insets = useSafeAreaInsets();
const animatedOpacity = useSharedValue(0);
const animatedTranslateY = useSharedValue(-9999);
const overlayRef = useRef();
const [orientation, setOrientation] = useState(getInitialOrientation());
- const introCompleted = useSettingStore(state => state.settings.introCompleted);
+ const introCompleted = useSettingStore(
+ (state) => state.settings.introCompleted
+ );
const onOrientationChange = (o, o2) => {
setOrientation(o || o2);
};
useEffect(() => {
- if (Platform.OS === 'ios') {
+ if (Platform.OS === "ios") {
addSpecificOrientationListener(onOrientationChange);
getSpecificOrientation && getSpecificOrientation(onOrientationChange);
}
@@ -63,7 +76,7 @@ export const TabsHolder = React.memo(
const showFullScreenEditor = () => {
setFullscreen(true);
- if (deviceMode === 'smallTablet') {
+ if (deviceMode === "smallTablet") {
tabBarRef.current?.openDrawer();
}
editorRef.current?.setNativeProps({
@@ -71,13 +84,15 @@ export const TabsHolder = React.memo(
width: dimensions.width,
zIndex: 999,
paddingHorizontal:
- deviceMode === 'smallTablet' ? dimensions.width * 0 : dimensions.width * 0.15
+ deviceMode === "smallTablet"
+ ? dimensions.width * 0
+ : dimensions.width * 0.15
}
});
};
const closeFullScreenEditor = () => {
- if (deviceMode === 'smallTablet') {
+ if (deviceMode === "smallTablet") {
tabBarRef.current?.closeDrawer();
}
setFullscreen(false);
@@ -87,14 +102,15 @@ export const TabsHolder = React.memo(
editorRef.current?.setNativeProps({
style: {
width:
- deviceMode === 'smallTablet'
- ? dimensions.width - valueLimiter(dimensions.width * 0.4, 300, 450)
+ deviceMode === "smallTablet"
+ ? dimensions.width -
+ valueLimiter(dimensions.width * 0.4, 300, 450)
: dimensions.width * 0.55,
zIndex: null,
paddingHorizontal: 0
}
});
- if (deviceMode === 'smallTablet') {
+ if (deviceMode === "smallTablet") {
setTimeout(() => {
tabBarRef.current?.goToIndex(1);
}, 100);
@@ -114,8 +130,8 @@ export const TabsHolder = React.memo(
};
}, [deviceMode, dimensions, colors]);
- const _onLayout = async event => {
- console.log('layout called here');
+ const _onLayout = async (event) => {
+ console.log("layout called here");
if (layoutTimer) {
clearTimeout(layoutTimer);
layoutTimer = null;
@@ -138,17 +154,17 @@ export const TabsHolder = React.memo(
width: size.width,
height: size.height
});
- console.log('height change', size.width, size.height);
+ console.log("height change", size.width, size.height);
setWidthHeight(size);
DDS.setSize(size);
if (DDS.isLargeTablet()) {
- setDeviceMode('tablet', size);
+ setDeviceMode("tablet", size);
setTimeout(() => {
introCompleted && tabBarRef.current?.goToIndex(0);
}, 500);
} else if (DDS.isSmallTab) {
- setDeviceMode('smallTablet', size);
+ setDeviceMode("smallTablet", size);
if (!fullscreen) {
setTimeout(() => {
introCompleted && tabBarRef.current?.closeDrawer();
@@ -159,7 +175,7 @@ export const TabsHolder = React.memo(
}, 500);
}
} else {
- setDeviceMode('mobile', size);
+ setDeviceMode("mobile", size);
}
}
@@ -172,17 +188,18 @@ export const TabsHolder = React.memo(
style: {
width: size.width,
zIndex: 999,
- paddingHorizontal: current === 'smallTablet' ? size.width * 0 : size.width * 0.15
+ paddingHorizontal:
+ current === "smallTablet" ? size.width * 0 : size.width * 0.15
}
});
} else {
editorRef.current?.setNativeProps({
style: {
- position: 'relative',
+ position: "relative",
width:
- current === 'tablet'
+ current === "tablet"
? size.width * 0.55
- : current === 'smallTablet'
+ : current === "smallTablet"
? size.width - valueLimiter(size.width * 0.4, 300, 450)
: size.width,
zIndex: null,
@@ -194,20 +211,20 @@ export const TabsHolder = React.memo(
return;
}
setTimeout(() => {
- if (current === 'tablet') {
+ if (current === "tablet") {
tabBarRef.current?.goToIndex(0);
} else {
if (!editorState().movedAway) {
tabBarRef.current?.goToIndex(2);
} else {
- console.log('index one', editorState().movedAway);
+ console.log("index one", editorState().movedAway);
tabBarRef.current?.goToIndex(1);
}
}
}, 1);
}
- const onScroll = scrollOffset => {
+ const onScroll = (scrollOffset) => {
hideAllTooltips();
if (scrollOffset > offsets[deviceMode].a - 10) {
animatedOpacity.value = 0;
@@ -225,7 +242,7 @@ export const TabsHolder = React.memo(
}
};
- const toggleView = show => {
+ const toggleView = (show) => {
animatedTranslateY.value = show ? 0 : -9999;
};
@@ -249,8 +266,12 @@ export const TabsHolder = React.memo(
},
smallTablet: {
a: fullscreen ? 0 : valueLimiter(dimensions.width * 0.3, 300, 350),
- b: fullscreen ? 0 : dimensions.width + valueLimiter(dimensions.width * 0.3, 300, 350),
- c: fullscreen ? 0 : dimensions.width + valueLimiter(dimensions.width * 0.3, 300, 350)
+ b: fullscreen
+ ? 0
+ : dimensions.width + valueLimiter(dimensions.width * 0.3, 300, 350),
+ c: fullscreen
+ ? 0
+ : dimensions.width + valueLimiter(dimensions.width * 0.3, 300, 350)
},
tablet: {
a: 0,
@@ -295,14 +316,19 @@ export const TabsHolder = React.memo(
style={{
flex: 1,
backgroundColor: colors.bg,
- paddingBottom: Platform.OS === 'android' ? insets?.bottom : 0,
+ paddingBottom: Platform.OS === "android" ? insets?.bottom : 0,
marginRight:
- orientation === 'LANDSCAPE-RIGHT' && Platform.OS === 'ios' ? insets.right : 0,
- marginLeft: orientation === 'LANDSCAPE-LEFT' && Platform.OS === 'ios' ? insets.left : 0
+ orientation === "LANDSCAPE-RIGHT" && Platform.OS === "ios"
+ ? insets.right
+ : 0,
+ marginLeft:
+ orientation === "LANDSCAPE-LEFT" && Platform.OS === "ios"
+ ? insets.left
+ : 0
}}
>
@@ -311,17 +337,19 @@ export const TabsHolder = React.memo(
true}
+ onDrawerStateChange={(state) => true}
>
@@ -330,11 +358,13 @@ export const TabsHolder = React.memo(
- {deviceMode === 'mobile' ? (
+ {deviceMode === "mobile" ? (
{
tabBarRef.current?.closeDrawer();
@@ -343,11 +373,11 @@ export const TabsHolder = React.memo(
}}
style={[
{
- position: 'absolute',
- width: '100%',
- height: '100%',
+ position: "absolute",
+ width: "100%",
+ height: "100%",
zIndex: 999,
- backgroundColor: 'rgba(0,0,0,0.2)'
+ backgroundColor: "rgba(0,0,0,0.2)"
},
animatedStyle
]}
@@ -368,20 +398,20 @@ export const TabsHolder = React.memo(
let layoutTimer = null;
-const onChangeTab = async obj => {
+const onChangeTab = async (obj) => {
if (obj.i === 2) {
editorState().movedAway = false;
editorState().isFocused = true;
activateKeepAwake();
if (!editorState().currentlyEditing) {
- eSendEvent(eOnLoadNote, { type: 'new' });
+ eSendEvent(eOnLoadNote, { type: "new" });
}
} else {
if (obj.from === 2) {
deactivateKeepAwake();
editorState().movedAway = true;
editorState().isFocused = false;
- eSendEvent(eClearEditor, 'removeHandler');
+ eSendEvent(eClearEditor, "removeHandler");
setTimeout(() => useEditorStore.getState().setSearchReplace(false), 1);
let id = useEditorStore.getState().currentEditingNote;
let note = db.notes.note(id);
diff --git a/apps/mobile/app/screens/editor/index.tsx b/apps/mobile/app/screens/editor/index.tsx
index b6a474d03..b288471a6 100755
--- a/apps/mobile/app/screens/editor/index.tsx
+++ b/apps/mobile/app/screens/editor/index.tsx
@@ -1,32 +1,41 @@
/* eslint-disable @typescript-eslint/no-var-requires */
-import { EV, EVENTS } from '@streetwriters/notesnook-core/common';
-import React, { forwardRef, ReactElement, useEffect, useImperativeHandle, useState } from 'react';
-import { Platform, ViewStyle } from 'react-native';
-import WebView from 'react-native-webview';
-import { ShouldStartLoadRequest } from 'react-native-webview/lib/WebViewTypes';
-import { notesnook } from '../../../e2e/test.ids';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import { useEditorStore } from '../../stores/use-editor-store';
-import { getElevation } from '../../utils';
-import { db } from '../../common/database';
-import { openLinkInBrowser } from '../../utils/functions';
-import { NoteType } from '../../utils/types';
-import { EDITOR_URI } from './source';
-import { EditorProps, useEditorType } from './tiptap/types';
-import { useEditor } from './tiptap/use-editor';
-import { useEditorEvents } from './tiptap/use-editor-events';
-import { editorController } from './tiptap/utils';
+import { EV, EVENTS } from "@streetwriters/notesnook-core/common";
+import React, {
+ forwardRef,
+ ReactElement,
+ useEffect,
+ useImperativeHandle,
+ useState
+} from "react";
+import { Platform, ViewStyle } from "react-native";
+import WebView from "react-native-webview";
+import { ShouldStartLoadRequest } from "react-native-webview/lib/WebViewTypes";
+import { notesnook } from "../../../e2e/test.ids";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import { useEditorStore } from "../../stores/use-editor-store";
+import { getElevation } from "../../utils";
+import { db } from "../../common/database";
+import { openLinkInBrowser } from "../../utils/functions";
+import { NoteType } from "../../utils/types";
+import { EDITOR_URI } from "./source";
+import { EditorProps, useEditorType } from "./tiptap/types";
+import { useEditor } from "./tiptap/use-editor";
+import { useEditorEvents } from "./tiptap/use-editor-events";
+import { editorController } from "./tiptap/utils";
const style: ViewStyle = {
- height: '100%',
- maxHeight: '100%',
- width: '100%',
- alignSelf: 'center',
- backgroundColor: 'transparent'
+ height: "100%",
+ maxHeight: "100%",
+ width: "100%",
+ alignSelf: "center",
+ backgroundColor: "transparent"
};
const onShouldStartLoadWithRequest = (request: ShouldStartLoadRequest) => {
- if (request.url.includes('https')) {
- if (Platform.OS === 'ios' && !request.isTopFrame) return true;
+ if (request.url.includes("https")) {
+ if (Platform.OS === "ios" && !request.isTopFrame) return true;
openLinkInBrowser(request.url);
return false;
} else {
@@ -47,14 +56,14 @@ const Editor = React.memo(
noToolbar = false,
noHeader = false,
withController = true,
- editorId = '',
+ editorId = "",
onLoad,
onChange,
theme
},
ref
) => {
- const editor = useEditor(editorId || '', readonly, onChange, theme);
+ const editor = useEditor(editorId || "", readonly, onChange, theme);
const onMessage = useEditorEvents(editor, {
readonly,
noToolbar,
@@ -74,7 +83,7 @@ const Editor = React.memo(
groupId: string;
src: string;
}) => {
- console.log('onMediaDownoaded', groupId);
+ console.log("onMediaDownoaded", groupId);
if (groupId !== editor.note.current?.id) return;
editor.commands.updateImage({
@@ -85,10 +94,10 @@ const Editor = React.memo(
useEffect(() => {
onLoad && onLoad();
- eSubscribeEvent('webview_reset', onError);
+ eSubscribeEvent("webview_reset", onError);
EV.subscribe(EVENTS.mediaAttachmentDownloaded, onMediaDownloaded);
return () => {
- eUnSubscribeEvent('webview_reset', onError);
+ eUnSubscribeEvent("webview_reset", onError);
EV.unsubscribe(EVENTS.mediaAttachmentDownloaded, onMediaDownloaded);
};
}, []);
@@ -99,11 +108,11 @@ const Editor = React.memo(
}
const onError = () => {
- console.log('RENDER PROCESS GONE!!!');
+ console.log("RENDER PROCESS GONE!!!");
editor.setLoading(true);
setTimeout(() => editor.setLoading(false), 10);
};
- console.log(editor.loading, 'loading editor');
+ console.log(editor.loading, "loading editor");
return editor.loading ? null : (
<>
- {editorId === 'shareEditor' ? null : }
+ {editorId === "shareEditor" ? null : (
+
+ )}
>
);
}
@@ -164,25 +175,29 @@ const AppSection = ({ editor, editorId }) => {
const [loaded, setLoaded] = useState(false);
useEffect(() => {
//@ts-ignore
- EditorOverlay = require('./loading.js').default;
+ EditorOverlay = require("./loading.js").default;
//@ts-ignore
- IconButton = require('../../components/ui/icon-button/index.tsx').IconButton;
+ IconButton =
+ require("../../components/ui/icon-button/index.tsx").IconButton;
setLoaded(true);
}, []);
return loaded ? (
<>
- {EditorOverlay ? : null}
+ {EditorOverlay ? (
+
+ ) : null}
>
) : null;
};
const ReadonlyButton = ({ editor }: { editor: useEditorType }) => {
- const readonly = useEditorStore(state => state.readonly);
+ const readonly = useEditorStore((state) => state.readonly);
const onPress = async () => {
if (editor.note.current) {
await db.notes?.note(editor.note.current.id).readonly();
- editor.note.current = db.notes?.note(editor.note.current.id).data as NoteType;
+ editor.note.current = db.notes?.note(editor.note.current.id)
+ .data as NoteType;
useEditorStore.getState().setReadonly(false);
}
};
@@ -194,7 +209,7 @@ const ReadonlyButton = ({ editor }: { editor: useEditorType }) => {
onPress={onPress}
color="accent"
customStyle={{
- position: 'absolute',
+ position: "absolute",
bottom: 20,
width: 60,
height: 60,
diff --git a/apps/mobile/app/screens/editor/loading.js b/apps/mobile/app/screens/editor/loading.js
index d7f3cd950..528b3cbca 100644
--- a/apps/mobile/app/screens/editor/loading.js
+++ b/apps/mobile/app/screens/editor/loading.js
@@ -1,23 +1,31 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { View } from 'react-native';
-import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { Button } from '../../components/ui/button';
-import { IconButton } from '../../components/ui/icon-button';
-import Paragraph from '../../components/ui/typography/paragraph';
-import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { eClearEditor, eOnLoadNote } from '../../utils/events';
-import { SIZE } from '../../utils/size';
-import { editorState } from './tiptap/utils';
+import React, { useEffect, useRef, useState } from "react";
+import { View } from "react-native";
+import Animated, {
+ useAnimatedStyle,
+ useSharedValue,
+ withTiming
+} from "react-native-reanimated";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { Button } from "../../components/ui/button";
+import { IconButton } from "../../components/ui/icon-button";
+import Paragraph from "../../components/ui/typography/paragraph";
+import {
+ eSendEvent,
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { eClearEditor, eOnLoadNote } from "../../utils/events";
+import { SIZE } from "../../utils/size";
+import { editorState } from "./tiptap/utils";
-const EditorOverlay = ({ editorId = '', editor }) => {
- const colors = useThemeStore(state => state.colors);
+const EditorOverlay = ({ editorId = "", editor }) => {
+ const colors = useThemeStore((state) => state.colors);
const [error, setError] = useState(false);
const opacity = useSharedValue(1);
const translateValue = useSharedValue(6000);
const insets = useSafeAreaInsets();
- const isDefaultEditor = editorId === '';
+ const isDefaultEditor = editorId === "";
const timers = useRef({
loading: 0,
error: 0,
@@ -30,7 +38,7 @@ const EditorOverlay = ({ editorId = '', editor }) => {
clearTimeout(timers.current.closing);
};
- const load = async _loading => {
+ const load = async (_loading) => {
editorState().overlay = true;
clearTimers();
if (_loading) {
@@ -60,10 +68,10 @@ const EditorOverlay = ({ editorId = '', editor }) => {
};
useEffect(() => {
- eSubscribeEvent('loadingNote' + editorId, load);
+ eSubscribeEvent("loadingNote" + editorId, load);
return () => {
clearTimers();
- eUnSubscribeEvent('loadingNote' + editorId, load);
+ eUnSubscribeEvent("loadingNote" + editorId, load);
};
}, [editorId]);
@@ -82,12 +90,12 @@ const EditorOverlay = ({ editorId = '', editor }) => {
{
>
{isDefaultEditor ? (
{
@@ -140,8 +148,8 @@ const EditorOverlay = ({ editorId = '', editor }) => {
{isDefaultEditor ? (
@@ -151,9 +159,9 @@ const EditorOverlay = ({ editorId = '', editor }) => {
backgroundColor: colors.nav,
borderRadius: 100,
marginBottom: 10,
- justifyContent: 'flex-start',
- alignItems: 'center',
- flexDirection: 'row',
+ justifyContent: "flex-start",
+ alignItems: "center",
+ flexDirection: "row",
paddingHorizontal: 10,
marginTop: 10
}}
@@ -176,7 +184,7 @@ const EditorOverlay = ({ editorId = '', editor }) => {
{
{
{
{
type="error"
style={{
marginTop: 20,
- alignSelf: 'flex-start',
+ alignSelf: "flex-start",
borderRadius: 100,
height: 40
}}
@@ -271,11 +279,12 @@ const EditorOverlay = ({ editorId = '', editor }) => {
size={SIZE.xs}
color={colors.icon}
style={{
- maxWidth: '100%',
+ maxWidth: "100%",
marginTop: 5
}}
>
- If the editor fails to load even after reloading. Try restarting the app.
+ If the editor fails to load even after reloading. Try restarting
+ the app.
>
) : null}
diff --git a/apps/mobile/app/screens/editor/progress.js b/apps/mobile/app/screens/editor/progress.js
index b99533650..b642d1955 100644
--- a/apps/mobile/app/screens/editor/progress.js
+++ b/apps/mobile/app/screens/editor/progress.js
@@ -1,14 +1,14 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { View } from 'react-native';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useAttachmentStore } from '../../stores/use-attachment-store';
-import { SIZE } from '../../utils/size';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { ProgressBarComponent } from '../../components/ui/svg/lazy';
+import React, { useEffect, useRef, useState } from "react";
+import { View } from "react-native";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useAttachmentStore } from "../../stores/use-attachment-store";
+import { SIZE } from "../../utils/size";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { ProgressBarComponent } from "../../components/ui/svg/lazy";
export const ProgressBar = () => {
- const colors = useThemeStore(state => state.colors);
- const loading = useAttachmentStore(state => state.loading);
+ const colors = useThemeStore((state) => state.colors);
+ const loading = useAttachmentStore((state) => state.loading);
const [prog, setProg] = useState(0);
const [visible, setVisible] = useState(false);
const timer = useRef();
@@ -43,13 +43,13 @@ export const ProgressBar = () => {
return visible ? (
setWidth(event.nativeEvent.layout.width)}
+ onLayout={(event) => setWidth(event.nativeEvent.layout.width)}
>
, action?: Action) {
if (!webview.current || !action) return;
setImmediate(() => webview.current?.injectJavaScript(action.job));
let response = await getResponse(action.id);
- console.log('webview job: ', action.id, response ? response.value : response);
+ console.log("webview job: ", action.id, response ? response.value : response);
if (!response) {
- console.warn('webview job failed', action.id);
+ console.warn("webview job failed", action.id);
}
return response ? response.value : response;
}
const fn = (fn: string) => {
- let id = randId('fn_');
+ let id = randId("fn_");
return {
job: `(async () => {
try {
@@ -59,7 +59,7 @@ class Commands {
focus = async () => {
if (!this.ref.current) return;
- if (Platform.OS === 'android') {
+ if (Platform.OS === "android") {
//this.ref.current?.requestFocus();
setTimeout(async () => {
if (!this.ref) return;
@@ -92,7 +92,8 @@ typeof globalThis.statusBar !== "undefined" && statusBar.current.set({date:"",sa
);
};
- setSessionId = async (id: string | null) => await this.doAsync(`globalThis.sessionId = "${id}"`);
+ setSessionId = async (id: string | null) =>
+ await this.doAsync(`globalThis.sessionId = "${id}"`);
setStatus = async (date: string | undefined, saved: string) =>
await this.doAsync(
@@ -109,7 +110,7 @@ typeof globalThis.statusBar !== "undefined" && statusBar.current.set({date:"",sa
};
setInsets = async (insets: EdgeInsets) => {
- logger.info('setInsets', insets);
+ logger.info("setInsets", insets);
await this.doAsync(`
if (typeof safeAreaController !== "undefined") {
safeAreaController.update(${JSON.stringify(insets)})
@@ -125,7 +126,9 @@ typeof globalThis.statusBar !== "undefined" && statusBar.current.set({date:"",sa
};
await this.doAsync(`
if (typeof globalThis.settingsController !== "undefined") {
- globalThis.settingsController.update(${JSON.stringify(this.previousSettings)})
+ globalThis.settingsController.update(${JSON.stringify(
+ this.previousSettings
+ )})
}
`);
};
@@ -140,7 +143,7 @@ typeof globalThis.statusBar !== "undefined" && statusBar.current.set({date:"",sa
return;
}
}
- console.log('setSettings', JSON.stringify(settings));
+ console.log("setSettings", JSON.stringify(settings));
await this.doAsync(`
if (typeof globalThis.settingsController !== "undefined") {
globalThis.settingsController.update(${JSON.stringify(settings)})
@@ -154,7 +157,9 @@ typeof globalThis.statusBar !== "undefined" && statusBar.current.set({date:"",sa
? []
: note.tags
.map((t: any) =>
- db.tags?.tag(t) ? { title: db.tags.tag(t).title, alias: db.tags.tag(t).alias } : null
+ db.tags?.tag(t)
+ ? { title: db.tags.tag(t).title, alias: db.tags.tag(t).alias }
+ : null
)
.filter((t: any) => t !== null);
await this.doAsync(`
@@ -173,18 +178,26 @@ typeof globalThis.statusBar !== "undefined" && statusBar.current.set({date:"",sa
};
insertAttachment = async (attachment: Attachment) => {
- await this.doAsync(`editor && editor.commands.insertAttachment(${JSON.stringify(attachment)})`);
+ await this.doAsync(
+ `editor && editor.commands.insertAttachment(${JSON.stringify(
+ attachment
+ )})`
+ );
};
setAttachmentProgress = async (attachmentProgress: AttachmentProgress) => {
await this.doAsync(
- `editor && editor.commands.setAttachmentProgress(${JSON.stringify(attachmentProgress)})`
+ `editor && editor.commands.setAttachmentProgress(${JSON.stringify(
+ attachmentProgress
+ )})`
);
};
insertImage = async (image: ImageAttributes) => {
- console.log('image data', image);
- await this.doAsync(`editor && editor.commands.insertImage(${JSON.stringify(image)})`);
+ console.log("image data", image);
+ await this.doAsync(
+ `editor && editor.commands.insertImage(${JSON.stringify(image)})`
+ );
};
updateImage = async ({ src, hash }: ImageAttributes) => {
diff --git a/apps/mobile/app/screens/editor/tiptap/picker.js b/apps/mobile/app/screens/editor/tiptap/picker.js
index b1e6f8c1e..12a751186 100644
--- a/apps/mobile/app/screens/editor/tiptap/picker.js
+++ b/apps/mobile/app/screens/editor/tiptap/picker.js
@@ -1,25 +1,29 @@
-import React from 'react';
-import { Platform, View } from 'react-native';
-import DocumentPicker from 'react-native-document-picker';
-import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
-import Sodium from 'react-native-sodium';
-import RNFetchBlob from 'rn-fetch-blob';
-import { AttachmentItem } from '../../../components/attachments/attachment-item';
-import { eSendEvent, presentSheet, ToastEvent } from '../../../services/event-manager';
-import PremiumService from '../../../services/premium';
-import { db } from '../../../common/database';
-import { eCloseProgressDialog } from '../../../utils/events';
-import { sleep } from '../../../utils/time';
-import { editorController, editorState } from './utils';
+import React from "react";
+import { Platform, View } from "react-native";
+import DocumentPicker from "react-native-document-picker";
+import { launchCamera, launchImageLibrary } from "react-native-image-picker";
+import Sodium from "react-native-sodium";
+import RNFetchBlob from "rn-fetch-blob";
+import { AttachmentItem } from "../../../components/attachments/attachment-item";
+import {
+ eSendEvent,
+ presentSheet,
+ ToastEvent
+} from "../../../services/event-manager";
+import PremiumService from "../../../services/premium";
+import { db } from "../../../common/database";
+import { eCloseProgressDialog } from "../../../utils/events";
+import { sleep } from "../../../utils/time";
+import { editorController, editorState } from "./utils";
const FILE_SIZE_LIMIT = 500 * 1024 * 1024;
const IMAGE_SIZE_LIMIT = 50 * 1024 * 1024;
-const showEncryptionSheet = file => {
+const showEncryptionSheet = (file) => {
presentSheet({
- title: 'Encrypting attachment',
- paragraph: 'Please wait while we encrypt file for upload',
- icon: 'attachment',
+ title: "Encrypting attachment",
+ paragraph: "Please wait while we encrypt file for upload",
+ icon: "attachment",
component: (
{
});
};
-const santizeUri = uri => {
+const santizeUri = (uri) => {
uri = decodeURI(uri);
- uri = Platform.OS === 'ios' ? uri.replace('file:///', '/') : uri;
+ uri = Platform.OS === "ios" ? uri.replace("file:///", "/") : uri;
return uri;
};
-const file = async fileOptions => {
+const file = async (fileOptions) => {
try {
const options = {
- mode: 'import',
+ mode: "import",
allowMultiSelection: false
};
- if (Platform.OS == 'ios') {
- options.copyTo = 'cachesDirectory';
+ if (Platform.OS == "ios") {
+ options.copyTo = "cachesDirectory";
}
- console.log('generate key for attachment');
+ console.log("generate key for attachment");
const key = await db.attachments.generateKey();
- console.log('generated key for attachments: ', key);
+ console.log("generated key for attachments: ", key);
let file;
try {
file = await DocumentPicker.pick(options);
@@ -66,42 +70,43 @@ const file = async fileOptions => {
}
file = file[0];
- if (file.type.startsWith('image')) {
+ if (file.type.startsWith("image")) {
ToastEvent.show({
- title: 'Type not supported',
- message: 'Please add images from gallery or camera picker.',
- type: 'error'
+ title: "Type not supported",
+ message: "Please add images from gallery or camera picker.",
+ type: "error"
});
return;
}
if (file.size > FILE_SIZE_LIMIT) {
ToastEvent.show({
- title: 'File too large',
- message: 'The maximum allowed size per file is 500 MB',
- type: 'error'
+ title: "File too large",
+ message: "The maximum allowed size per file is 500 MB",
+ type: "error"
});
return;
}
if (file.copyError) {
ToastEvent.show({
- heading: 'Failed to open file',
+ heading: "Failed to open file",
message: file.copyError,
- type: 'error',
- context: 'global'
+ type: "error",
+ context: "global"
});
return;
}
- let uri = Platform.OS === 'ios' ? file.fileCopyUri : file.uri;
- console.log('file uri: ', uri);
- uri = Platform.OS === 'ios' ? santizeUri(uri) : uri;
+ let uri = Platform.OS === "ios" ? file.fileCopyUri : file.uri;
+ console.log("file uri: ", uri);
+ uri = Platform.OS === "ios" ? santizeUri(uri) : uri;
showEncryptionSheet(file);
const hash = await Sodium.hashFile({
uri: uri,
- type: 'url'
+ type: "url"
});
- if (!(await attachFile(uri, hash, file.type, file.name, fileOptions))) return;
+ if (!(await attachFile(uri, hash, file.type, file.name, fileOptions)))
+ return;
editorController.current?.commands.insertAttachment({
hash: hash,
filename: file.name,
@@ -114,15 +119,15 @@ const file = async fileOptions => {
} catch (e) {
ToastEvent.show({
heading: e.message,
- message: 'You need internet access to attach a file',
- type: 'error',
- context: 'global'
+ message: "You need internet access to attach a file",
+ type: "error",
+ context: "global"
});
- console.log('attachment error: ', e);
+ console.log("attachment error: ", e);
}
};
-const camera = async options => {
+const camera = async (options) => {
try {
await db.attachments.generateKey();
eSendEvent(eCloseProgressDialog);
@@ -130,22 +135,22 @@ const camera = async options => {
launchCamera(
{
includeBase64: true,
- mediaType: 'photo'
+ mediaType: "photo"
},
- response => handleImageResponse(response, options)
+ (response) => handleImageResponse(response, options)
);
} catch (e) {
ToastEvent.show({
heading: e.message,
- message: 'You need internet access to attach a file',
- type: 'error',
- context: 'global'
+ message: "You need internet access to attach a file",
+ type: "error",
+ context: "global"
});
- console.log('attachment error:', e);
+ console.log("attachment error:", e);
}
};
-const gallery = async options => {
+const gallery = async (options) => {
try {
await db.attachments.generateKey();
eSendEvent(eCloseProgressDialog);
@@ -153,23 +158,23 @@ const gallery = async options => {
launchImageLibrary(
{
includeBase64: true,
- mediaType: 'photo',
+ mediaType: "photo",
selectionLimit: 1
},
- response => handleImageResponse(response, options)
+ (response) => handleImageResponse(response, options)
);
} catch (e) {
ToastEvent.show({
heading: e.message,
- message: 'You need internet access to attach a file',
- type: 'error',
- context: 'global'
+ message: "You need internet access to attach a file",
+ type: "error",
+ context: "global"
});
- console.log('attachment error:', e);
+ console.log("attachment error:", e);
}
};
-const pick = async options => {
+const pick = async (options) => {
if (!PremiumService.get()) {
let user = await db.user.getUser();
if (editorState().isFocused) {
@@ -182,9 +187,9 @@ const pick = async options => {
}
return;
}
- console.log('opening picker', options.type);
- if (options?.type.startsWith('image') || options?.type === 'camera') {
- if (options.type === 'image') {
+ console.log("opening picker", options.type);
+ if (options?.type.startsWith("image") || options?.type === "camera") {
+ if (options.type === "image") {
gallery(options);
} else {
camera(options);
@@ -207,9 +212,9 @@ const handleImageResponse = async (response, options) => {
let image = response.assets[0];
if (image.fileSize > IMAGE_SIZE_LIMIT) {
ToastEvent.show({
- title: 'File too large',
- message: 'The maximum allowed size per image is 50 MB',
- type: 'error'
+ title: "File too large",
+ message: "The maximum allowed size per image is 50 MB",
+ type: "error"
});
return;
}
@@ -217,7 +222,7 @@ const handleImageResponse = async (response, options) => {
const uri = decodeURI(image.uri);
const hash = await Sodium.hashFile({
uri: uri,
- type: 'url'
+ type: "url"
});
let fileName = image.originalFileName || image.fileName;
@@ -240,10 +245,10 @@ async function attachFile(uri, hash, type, filename, options) {
if (options?.hash && options.hash !== hash) {
ToastEvent.show({
- heading: 'Please select the same file for reuploading',
+ heading: "Please select the same file for reuploading",
message: `Expected hash ${options.hash} but got ${hash}.`,
- type: 'error',
- context: 'local'
+ type: "error",
+ context: "local"
});
return false;
}
@@ -252,7 +257,7 @@ async function attachFile(uri, hash, type, filename, options) {
let key = await db.attachments.generateKey();
encryptionInfo = await Sodium.encryptFile(key, {
uri: uri,
- type: 'url',
+ type: "url",
hash: hash
});
encryptionInfo.type = type;
@@ -264,13 +269,16 @@ async function attachFile(uri, hash, type, filename, options) {
} else {
encryptionInfo = { hash: hash };
}
- await db.attachments.add(encryptionInfo, editorController.current?.note?.id);
- if (Platform.OS === 'ios') await RNFetchBlob.fs.unlink(uri);
+ await db.attachments.add(
+ encryptionInfo,
+ editorController.current?.note?.id
+ );
+ if (Platform.OS === "ios") await RNFetchBlob.fs.unlink(uri);
return true;
} catch (e) {
- console.log('attach file error: ', e);
- if (Platform.OS === 'ios') {
+ console.log("attach file error: ", e);
+ if (Platform.OS === "ios") {
await RNFetchBlob.fs.unlink(uri);
}
return false;
diff --git a/apps/mobile/app/screens/editor/tiptap/types.ts b/apps/mobile/app/screens/editor/tiptap/types.ts
index aa2e854e6..0ff7bebe2 100644
--- a/apps/mobile/app/screens/editor/tiptap/types.ts
+++ b/apps/mobile/app/screens/editor/tiptap/types.ts
@@ -1,6 +1,6 @@
-import { useEditor } from './use-editor';
-import type { ToolbarGroupDefinition } from '@streetwriters/editor/dist/es/toolbar/types';
-import { ThemeStore } from '../../../stores/use-theme-store';
+import { useEditor } from "./use-editor";
+import type { ToolbarGroupDefinition } from "@streetwriters/editor/dist/es/toolbar/types";
+import { ThemeStore } from "../../../stores/use-theme-store";
export type useEditorType = ReturnType;
export type EditorState = {
@@ -8,7 +8,7 @@ export type EditorState = {
isFullscreen: boolean;
onNoteCreated?: ((id: string) => void) | null;
isFocused: boolean;
- focusType: 'title' | 'editor' | null;
+ focusType: "title" | "editor" | null;
movedAway: boolean;
tooltip: boolean;
isRestoringState: boolean;
@@ -37,7 +37,7 @@ export type EditorProps = {
editorId?: string;
onLoad?: () => void;
onChange?: (html: string) => void;
- theme?: ThemeStore['colors'];
+ theme?: ThemeStore["colors"];
};
export type EditorMessage = {
@@ -66,8 +66,8 @@ export type Content = {
export type SavePayload = {
title?: string;
id?: string | null;
- data?: Content['data'];
- type?: Content['type'];
+ data?: Content["data"];
+ type?: Content["type"];
sessionId?: string | null;
sessionHistoryId?: number;
};
diff --git a/apps/mobile/app/screens/editor/tiptap/use-editor-events.ts b/apps/mobile/app/screens/editor/tiptap/use-editor-events.ts
index a35b47f84..adc34c6c7 100644
--- a/apps/mobile/app/screens/editor/tiptap/use-editor-events.ts
+++ b/apps/mobile/app/screens/editor/tiptap/use-editor-events.ts
@@ -1,23 +1,27 @@
/* eslint-disable no-case-declarations */
/* eslint-disable @typescript-eslint/no-var-requires */
-import { getDefaultPresets } from '@streetwriters/editor/dist/es/toolbar/tooldefinitions';
-import { useCallback, useEffect, useRef } from 'react';
-import { BackHandler, InteractionManager, NativeEventSubscription } from 'react-native';
-import { WebViewMessageEvent } from 'react-native-webview';
-import { DDS } from '../../../services/device-detection';
+import { getDefaultPresets } from "@streetwriters/editor/dist/es/toolbar/tooldefinitions";
+import { useCallback, useEffect, useRef } from "react";
+import {
+ BackHandler,
+ InteractionManager,
+ NativeEventSubscription
+} from "react-native";
+import { WebViewMessageEvent } from "react-native-webview";
+import { DDS } from "../../../services/device-detection";
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent,
ToastEvent
-} from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import { useEditorStore } from '../../../stores/use-editor-store';
-import { useSettingStore } from '../../../stores/use-setting-store';
-import { useTagStore } from '../../../stores/use-tag-store';
-import { useUserStore } from '../../../stores/use-user-store';
-import umami from '../../../common/analytics/index';
-import { db } from '../../../common/database';
+} from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import { useEditorStore } from "../../../stores/use-editor-store";
+import { useSettingStore } from "../../../stores/use-setting-store";
+import { useTagStore } from "../../../stores/use-tag-store";
+import { useUserStore } from "../../../stores/use-user-store";
+import umami from "../../../common/analytics/index";
+import { db } from "../../../common/database";
import {
eClearEditor,
eCloseFullscreenEditor,
@@ -27,53 +31,53 @@ import {
eOpenPremiumDialog,
eOpenPublishNoteDialog,
eOpenTagsDialog
-} from '../../../utils/events';
-import filesystem from '../../../common/filesystem';
-import { tabBarRef } from '../../../utils/global-refs';
-import useKeyboard from '../../../hooks/use-keyboard';
-import { NoteType } from '../../../utils/types';
-import { useDragState } from '../../settings/editor/state';
-import { EditorMessage, EditorProps, useEditorType } from './types';
-import { EditorEvents, editorState } from './utils';
+} from "../../../utils/events";
+import filesystem from "../../../common/filesystem";
+import { tabBarRef } from "../../../utils/global-refs";
+import useKeyboard from "../../../hooks/use-keyboard";
+import { NoteType } from "../../../utils/types";
+import { useDragState } from "../../settings/editor/state";
+import { EditorMessage, EditorProps, useEditorType } from "./types";
+import { EditorEvents, editorState } from "./utils";
export const EventTypes = {
- selection: 'editor-event:selection',
- content: 'editor-event:content',
- title: 'editor-event:title',
- scroll: 'editor-event:scroll',
- history: 'editor-event:history',
- newtag: 'editor-event:newtag',
- tag: 'editor-event:tag',
- filepicker: 'editor-event:picker',
- download: 'editor-event:download-attachment',
- logger: 'native:logger',
- back: 'editor-event:back',
- pro: 'editor-event:pro',
- monograph: 'editor-event:monograph',
- properties: 'editor-event:properties',
- fullscreen: 'editor-event:fullscreen'
+ selection: "editor-event:selection",
+ content: "editor-event:content",
+ title: "editor-event:title",
+ scroll: "editor-event:scroll",
+ history: "editor-event:history",
+ newtag: "editor-event:newtag",
+ tag: "editor-event:tag",
+ filepicker: "editor-event:picker",
+ download: "editor-event:download-attachment",
+ logger: "native:logger",
+ back: "editor-event:back",
+ pro: "editor-event:pro",
+ monograph: "editor-event:monograph",
+ properties: "editor-event:properties",
+ fullscreen: "editor-event:fullscreen"
};
const publishNote = async (editor: useEditorType) => {
const user = useUserStore.getState().user;
if (!user) {
ToastEvent.show({
- heading: 'Login required',
- message: 'Login to publish',
- context: 'global',
+ heading: "Login required",
+ message: "Login to publish",
+ context: "global",
func: () => {
eSendEvent(eOpenLoginDialog);
},
- actionText: 'Login'
+ actionText: "Login"
});
return;
}
if (!user?.isEmailConfirmed) {
ToastEvent.show({
- heading: 'Email not verified',
- message: 'Please verify your email first.',
- context: 'global'
+ heading: "Email not verified",
+ message: "Please verify your email first.",
+ context: "global"
});
return;
}
@@ -82,9 +86,9 @@ const publishNote = async (editor: useEditorType) => {
let note = db.notes?.note(currentNote.id)?.data as NoteType;
if (note?.locked) {
ToastEvent.show({
- heading: 'Locked notes cannot be published',
- type: 'error',
- context: 'global'
+ heading: "Locked notes cannot be published",
+ type: "error",
+ context: "global"
});
return;
}
@@ -103,13 +107,13 @@ const showActionsheet = async (editor: useEditorType) => {
if (editorState().isFocused || editorState().isFocused) {
editorState().isFocused = true;
}
- const { Properties } = require('../../../components/properties/index.js');
- Properties.present(note, ['Dark Mode']);
+ const { Properties } = require("../../../components/properties/index.js");
+ Properties.present(note, ["Dark Mode"]);
} else {
ToastEvent.show({
- heading: 'Start writing to create a new note',
- type: 'success',
- context: 'global'
+ heading: "Start writing to create a new note",
+ type: "success",
+ context: "global"
});
}
};
@@ -118,20 +122,22 @@ export const useEditorEvents = (
editor: useEditorType,
{ readonly: editorPropReadonly, noHeader, noToolbar }: Partial
) => {
- const deviceMode = useSettingStore(state => state.deviceMode);
- const fullscreen = useSettingStore(state => state.fullscreen);
+ const deviceMode = useSettingStore((state) => state.deviceMode);
+ const fullscreen = useSettingStore((state) => state.fullscreen);
const handleBack = useRef();
- const readonly = useEditorStore(state => state.readonly);
- const isPremium = useUserStore(state => state.premium);
- const doubleSpacedLines = useSettingStore(state => state.settings?.doubleSpacedLines);
- const tools = useDragState(state => state.data);
+ const readonly = useEditorStore((state) => state.readonly);
+ const isPremium = useUserStore((state) => state.premium);
+ const doubleSpacedLines = useSettingStore(
+ (state) => state.settings?.doubleSpacedLines
+ );
+ const tools = useDragState((state) => state.data);
const { keyboardShown } = useKeyboard();
if (!editor) return null;
useEffect(() => {
- console.log('keyboardShown', keyboardShown);
+ console.log("keyboardShown", keyboardShown);
editor.commands.setSettings({
- deviceMode: deviceMode || 'mobile',
+ deviceMode: deviceMode || "mobile",
fullscreen: fullscreen || false,
premium: isPremium,
readonly: readonly || editorPropReadonly,
@@ -157,25 +163,30 @@ export const useEditorEvents = (
const onBackPress = useCallback(async () => {
const editorHandledBack = await editor.commands.handleBack();
if (!editorHandledBack) {
- logger.info('editor handled back event', editorHandledBack);
+ logger.info("editor handled back event", editorHandledBack);
return;
}
setTimeout(async () => {
- if (deviceMode !== 'mobile' && fullscreen) {
+ if (deviceMode !== "mobile" && fullscreen) {
if (fullscreen) {
eSendEvent(eCloseFullscreenEditor);
}
return;
}
- if (deviceMode === 'mobile') {
+ if (deviceMode === "mobile") {
editorState().movedAway = true;
tabBarRef.current?.goToPage(0);
}
setImmediate(() => {
useEditorStore.getState().setCurrentlyEditingNote(null);
setTimeout(() => {
- Navigation.queueRoutesForUpdate('ColoredNotes', 'Notes', 'TaggedNotes', 'TopicNotes');
+ Navigation.queueRoutesForUpdate(
+ "ColoredNotes",
+ "Notes",
+ "TaggedNotes",
+ "TopicNotes"
+ );
}, 500);
});
editorState().currentlyEditing = false;
@@ -193,23 +204,29 @@ export const useEditorEvents = (
const onLoadNote = useCallback(async () => {
InteractionManager.runAfterInteractions(() => {
if (!DDS.isTab) {
- handleBack.current = BackHandler.addEventListener('hardwareBackPress', onHardwareBackPress);
+ handleBack.current = BackHandler.addEventListener(
+ "hardwareBackPress",
+ onHardwareBackPress
+ );
}
});
}, []);
const onCallClear = useCallback(async (value: string) => {
- if (value === 'removeHandler') {
+ if (value === "removeHandler") {
if (handleBack.current) {
handleBack.current.remove();
}
return;
}
- if (value === 'addHandler') {
+ if (value === "addHandler") {
if (handleBack.current) {
handleBack.current.remove();
}
- handleBack.current = BackHandler.addEventListener('hardwareBackPress', onHardwareBackPress);
+ handleBack.current = BackHandler.addEventListener(
+ "hardwareBackPress",
+ onHardwareBackPress
+ );
return;
}
if (editorState().currentlyEditing) {
@@ -219,7 +236,10 @@ export const useEditorEvents = (
useEffect(() => {
if (fullscreen && DDS.isTab) {
- handleBack.current = BackHandler.addEventListener('hardwareBackPress', onHardwareBackPress);
+ handleBack.current = BackHandler.addEventListener(
+ "hardwareBackPress",
+ onHardwareBackPress
+ );
}
return () => {
@@ -242,14 +262,14 @@ export const useEditorEvents = (
const data = event.nativeEvent.data;
let editorMessage = JSON.parse(data) as EditorMessage;
- logger.info('editor', editorMessage.type);
+ logger.info("editor", editorMessage.type);
if (
editorMessage.sessionId !== editor.sessionId &&
editorMessage.type !== EditorEvents.status
) {
logger.error(
- 'editor',
- 'invalid session',
+ "editor",
+ "invalid session",
editorMessage.type,
editor.sessionId,
editorMessage.sessionId
@@ -259,7 +279,7 @@ export const useEditorEvents = (
}
switch (editorMessage.type) {
case EventTypes.logger:
- logger.info('[WEBVIEW LOG]', editorMessage.value);
+ logger.info("[WEBVIEW LOG]", editorMessage.value);
break;
case EventTypes.content:
editor.saveContent({
@@ -290,28 +310,28 @@ export const useEditorEvents = (
useTagStore.getState().setTags();
await editor.commands.setTags(editor.note.current);
Navigation.queueRoutesForUpdate(
- 'ColoredNotes',
- 'Notes',
- 'TaggedNotes',
- 'TopicNotes',
- 'Tags'
+ "ColoredNotes",
+ "Notes",
+ "TaggedNotes",
+ "TopicNotes",
+ "Tags"
);
});
}
break;
case EventTypes.filepicker:
- const { pick } = require('./picker.js').default;
+ const { pick } = require("./picker.js").default;
pick({ type: editorMessage.value });
break;
case EventTypes.download:
- console.log('download attachment request', editorMessage.value);
+ console.log("download attachment request", editorMessage.value);
filesystem.downloadAttachment(editorMessage.value?.hash, true);
break;
case EventTypes.pro:
if (editor.state.current?.isFocused) {
editor.state.current.isFocused = true;
}
- umami.pageView('/pro-screen', '/editor');
+ umami.pageView("/pro-screen", "/editor");
eSendEvent(eOpenPremiumDialog);
break;
case EventTypes.monograph:
@@ -329,7 +349,7 @@ export const useEditorEvents = (
break;
default:
console.log(
- 'unhandled event recieved from editor: ',
+ "unhandled event recieved from editor: ",
editorMessage.type,
editorMessage.value
);
diff --git a/apps/mobile/app/screens/editor/tiptap/use-editor.ts b/apps/mobile/app/screens/editor/tiptap/use-editor.ts
index 4b5928d67..a1f9bc0ee 100644
--- a/apps/mobile/app/screens/editor/tiptap/use-editor.ts
+++ b/apps/mobile/app/screens/editor/tiptap/use-editor.ts
@@ -1,21 +1,25 @@
-import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import WebView from 'react-native-webview';
-import { DDS } from '../../../services/device-detection';
-import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../../../services/event-manager';
-import Navigation from '../../../services/navigation';
-import { TipManager } from '../../../services/tip-manager';
-import { useEditorStore } from '../../../stores/use-editor-store';
-import { useTagStore } from '../../../stores/use-tag-store';
-import { ThemeStore, useThemeStore } from '../../../stores/use-theme-store';
-import { db } from '../../../common/database';
-import { MMKV } from '../../../common/database/mmkv';
-import { eOnLoadNote } from '../../../utils/events';
-import { tabBarRef } from '../../../utils/global-refs';
-import { timeConverter } from '../../../utils/time';
-import { NoteType } from '../../../utils/types';
-import Commands from './commands';
-import { AppState, Content, EditorState, Note, SavePayload } from './types';
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import WebView from "react-native-webview";
+import { DDS } from "../../../services/device-detection";
+import {
+ eSendEvent,
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../../services/event-manager";
+import Navigation from "../../../services/navigation";
+import { TipManager } from "../../../services/tip-manager";
+import { useEditorStore } from "../../../stores/use-editor-store";
+import { useTagStore } from "../../../stores/use-tag-store";
+import { ThemeStore, useThemeStore } from "../../../stores/use-theme-store";
+import { db } from "../../../common/database";
+import { MMKV } from "../../../common/database/mmkv";
+import { eOnLoadNote } from "../../../utils/events";
+import { tabBarRef } from "../../../utils/global-refs";
+import { timeConverter } from "../../../utils/time";
+import { NoteType } from "../../../utils/types";
+import Commands from "./commands";
+import { AppState, Content, EditorState, Note, SavePayload } from "./types";
import {
defaultState,
EditorEvents,
@@ -23,13 +27,13 @@ import {
isEditorLoaded,
makeSessionId,
post
-} from './utils';
+} from "./utils";
export const useEditor = (
- editorId = '',
+ editorId = "",
readonly?: boolean,
onChange?: (html: string) => void,
- theme?: ThemeStore['colors']
+ theme?: ThemeStore["colors"]
) => {
const [loading, setLoading] = useState(false);
const [sessionId, setSessionId] = useState(makeSessionId());
@@ -42,18 +46,21 @@ export const useEditor = (
const sessionHistoryId = useRef();
const state = useRef>(defaultState);
const placeholderTip = useRef(TipManager.placeholderTip());
- const tags = useTagStore(state => state.tags);
+ const tags = useTagStore((state) => state.tags);
const insets = useSafeAreaInsets();
- const isDefaultEditor = editorId === '';
+ const isDefaultEditor = editorId === "";
const saveCount = useRef(0);
const postMessage = useCallback(
- async (type: string, data: any) => await post(editorRef, sessionIdRef.current, type, data),
+ async (type: string, data: any) =>
+ await post(editorRef, sessionIdRef.current, type, data),
[sessionIdRef]
);
useEffect(() => {
- commands.setInsets(isDefaultEditor ? insets : { top: 0, left: 0, right: 0, bottom: 0 });
+ commands.setInsets(
+ isDefaultEditor ? insets : { top: 0, left: 0, right: 0, bottom: 0 }
+ );
}, [insets]);
useEffect(() => {
@@ -66,7 +73,7 @@ export const useEditor = (
useEffect(() => {
if (theme) return;
- let unsub = useThemeStore.subscribe(state => {
+ let unsub = useThemeStore.subscribe((state) => {
postMessage(EditorEvents.theme, state.colors);
});
@@ -76,7 +83,7 @@ export const useEditor = (
}, []);
useEffect(() => {
- console.log('sessionId:', sessionId);
+ console.log("sessionId:", sessionId);
async () => {
await commands.setSessionId(sessionIdRef.current);
if (sessionIdRef.current) {
@@ -89,13 +96,16 @@ export const useEditor = (
};
}, [sessionId, loading]);
- const overlay = (show: boolean, data = { type: 'new' }) => {
- eSendEvent('loadingNote' + editorId, show ? currentNote.current || data : false);
+ const overlay = (show: boolean, data = { type: "new" }) => {
+ eSendEvent(
+ "loadingNote" + editorId,
+ show ? currentNote.current || data : false
+ );
};
const onReady = useCallback(async () => {
if (!(await isEditorLoaded(editorRef, sessionIdRef.current))) {
- console.log('ON READY CALLED');
+ console.log("ON READY CALLED");
overlay(true);
setLoading(true);
}
@@ -107,10 +117,13 @@ export const useEditor = (
}
}, [loading]);
- const withTimer = useCallback((id: string, fn: () => void, duration: number) => {
- clearTimeout(timers.current[id]);
- timers.current[id] = setTimeout(fn, duration);
- }, []);
+ const withTimer = useCallback(
+ (id: string, fn: () => void, duration: number) => {
+ clearTimeout(timers.current[id]);
+ timers.current[id] = setTimeout(fn, duration);
+ },
+ []
+ );
const reset = useCallback(async (resetState = true) => {
currentNote.current?.id && db.fs.cancel(currentNote.current.id);
@@ -119,12 +132,13 @@ export const useEditor = (
sessionHistoryId.current = undefined;
saveCount.current = 0;
useEditorStore.getState().setReadonly(false);
- postMessage(EditorEvents.title, '');
+ postMessage(EditorEvents.title, "");
await commands.clearContent();
await commands.clearTags();
- console.log('reset state: ', resetState);
+ console.log("reset state: ", resetState);
if (resetState) {
- isDefaultEditor && useEditorStore.getState().setCurrentlyEditingNote(null);
+ isDefaultEditor &&
+ useEditorStore.getState().setCurrentlyEditingNote(null);
placeholderTip.current = TipManager.placeholderTip();
await commands.setPlaceholder(placeholderTip.current);
}
@@ -139,12 +153,18 @@ export const useEditor = (
sessionId: currentSessionId,
sessionHistoryId: currentSessionHistoryId
}: SavePayload) => {
- if (readonly || useEditorStore.getState().readonly || currentNote.current?.readonly) return;
+ if (
+ readonly ||
+ useEditorStore.getState().readonly ||
+ currentNote.current?.readonly
+ )
+ return;
- console.log('saving note', id);
+ console.log("saving note", id);
try {
if (id && !db.notes?.note(id)) {
- isDefaultEditor && useEditorStore.getState().setCurrentlyEditingNote(null);
+ isDefaultEditor &&
+ useEditorStore.getState().setCurrentlyEditingNote(null);
await reset();
return;
}
@@ -181,11 +201,17 @@ export const useEditor = (
currentNote.current = db.notes?.note(id).data as NoteType;
state.current?.onNoteCreated && state.current.onNoteCreated(id);
if (!noteData.title) {
- postMessage(EditorEvents.titleplaceholder, currentNote.current.title);
+ postMessage(
+ EditorEvents.titleplaceholder,
+ currentNote.current.title
+ );
}
}
- if (useEditorStore.getState().currentEditingNote !== id && isDefaultEditor) {
+ if (
+ useEditorStore.getState().currentEditingNote !== id &&
+ isDefaultEditor
+ ) {
setTimeout(() => {
id && useEditorStore.getState().setCurrentlyEditingNote(id);
});
@@ -198,23 +224,29 @@ export const useEditor = (
}
console.log(id, sessionIdRef.current, currentSessionId);
if (id && sessionIdRef.current === currentSessionId) {
- console.log('updating state');
+ console.log("updating state");
note = db.notes?.note(id)?.data as Note;
- await commands.setStatus(timeConverter(note.dateEdited), 'Saved');
+ await commands.setStatus(timeConverter(note.dateEdited), "Saved");
if (
saveCount.current < 2 ||
currentNote.current?.title !== note.title ||
- currentNote.current?.headline?.slice(0, 200) !== note.headline?.slice(0, 200)
+ currentNote.current?.headline?.slice(0, 200) !==
+ note.headline?.slice(0, 200)
) {
- Navigation.queueRoutesForUpdate('ColoredNotes', 'Notes', 'TaggedNotes', 'TopicNotes');
+ Navigation.queueRoutesForUpdate(
+ "ColoredNotes",
+ "Notes",
+ "TaggedNotes",
+ "TopicNotes"
+ );
}
}
saveCount.current++;
return id;
} catch (e) {
- console.log('error saving: ', e);
+ console.log("error saving: ", e);
}
},
[commands, reset]
@@ -225,7 +257,7 @@ export const useEditor = (
if (note.locked || note.content) {
currentContent.current = {
data: note.content?.data,
- type: note.content?.type || 'tiny'
+ type: note.content?.type || "tiny"
};
} else {
currentContent.current = await db.content?.raw(note.contentId);
@@ -234,12 +266,12 @@ export const useEditor = (
const loadNote = useCallback(
async (item: NoteType) => {
- console.log('loading note', item.type, eOnLoadNote + editorId);
+ console.log("loading note", item.type, eOnLoadNote + editorId);
state.current.currentlyEditing = true;
const editorState = useEditorStore.getState();
//@ts-ignore todo
- if (item && item.type === 'new') {
+ if (item && item.type === "new") {
currentNote.current && (await reset());
let nextSessionId = makeSessionId(item);
setSessionId(nextSessionId);
@@ -261,7 +293,7 @@ export const useEditor = (
sessionIdRef.current = nextSessionId;
await commands.setSessionId(nextSessionId);
currentNote.current = item;
- await commands.setStatus(timeConverter(item.dateEdited), 'Saved');
+ await commands.setStatus(timeConverter(item.dateEdited), "Saved");
await postMessage(EditorEvents.title, item.title);
await postMessage(EditorEvents.html, currentContent.current?.data);
useEditorStore.getState().setReadonly(item.readonly);
@@ -280,9 +312,16 @@ export const useEditor = (
if (!currentNote.current?.id) return;
//@ts-ignore
if (currentNote.current?.content?.isPreview) {
- db.content?.downloadMedia(currentNote.current?.id, currentNote.current.content, true);
+ db.content?.downloadMedia(
+ currentNote.current?.id,
+ currentNote.current.content,
+ true
+ );
} else {
- const images = db.attachments?.ofNote(currentNote.current?.id, 'images');
+ const images = db.attachments?.ofNote(
+ currentNote.current?.id,
+ "images"
+ );
if (images && images.length > 0) {
db.attachments?.downloadImages(currentNote.current.id);
}
@@ -298,26 +337,38 @@ export const useEditor = (
}, [editorId]);
const saveContent = useCallback(
- ({ title, content, type }: { title?: string; content?: string; type: string }) => {
+ ({
+ title,
+ content,
+ type
+ }: {
+ title?: string;
+ content?: string;
+ type: string;
+ }) => {
if (type === EditorEvents.content) {
currentContent.current = {
data: content,
- type: 'tiptap'
+ type: "tiptap"
};
}
let params = {
title,
data: content,
- type: 'tiptap',
+ type: "tiptap",
sessionId,
id: currentNote.current?.id,
sessionHistoryId: sessionHistoryId.current
};
withTimer(
- currentNote.current?.id || 'newnote',
+ currentNote.current?.id || "newnote",
() => {
- if (currentNote.current && !params.id && params.sessionId === sessionId) {
+ if (
+ currentNote.current &&
+ !params.id &&
+ params.sessionId === sessionId
+ ) {
params.id = currentNote.current?.id;
}
if (onChange && params.data) {
@@ -333,13 +384,15 @@ export const useEditor = (
);
const onLoad = useCallback(async () => {
- console.log('on editor load');
+ console.log("on editor load");
state.current.ready = true;
onReady();
postMessage(EditorEvents.theme, theme || useThemeStore.getState().colors);
- commands.setInsets(isDefaultEditor ? insets : { top: 0, left: 0, right: 0, bottom: 0 });
+ commands.setInsets(
+ isDefaultEditor ? insets : { top: 0, left: 0, right: 0, bottom: 0 }
+ );
if (currentNote.current) {
- console.log('force reload note');
+ console.log("force reload note");
//@ts-ignore
loadNote({ ...currentNote.current, forced: true });
} else {
@@ -350,7 +403,7 @@ export const useEditor = (
}, [state, currentNote, loadNote]);
async function restoreEditorState() {
- let json = await MMKV.getItem('appState');
+ let json = await MMKV.getItem("appState");
if (json) {
let appState = JSON.parse(json) as AppState;
if (
@@ -366,15 +419,15 @@ export const useEditor = (
tabBarRef.current?.goToPage(1);
}
setTimeout(() => {
- console.log('restoring app state here');
+ console.log("restoring app state here");
if (appState.note) {
//@ts-ignore
loadNote(appState.note);
}
}, 1);
- MMKV.removeItem('appState');
+ MMKV.removeItem("appState");
state.current.movedAway = false;
- eSendEvent('load_overlay', 'hide_editor');
+ eSendEvent("load_overlay", "hide_editor");
state.current.isRestoringState = false;
return;
}
diff --git a/apps/mobile/app/screens/editor/tiptap/utils.ts b/apps/mobile/app/screens/editor/tiptap/utils.ts
index 3bca0c93f..c20abaaee 100644
--- a/apps/mobile/app/screens/editor/tiptap/utils.ts
+++ b/apps/mobile/app/screens/editor/tiptap/utils.ts
@@ -1,9 +1,12 @@
-import { createRef, RefObject } from 'react';
-import { TextInput } from 'react-native';
-import WebView from 'react-native-webview';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../../services/event-manager';
-import { NoteType } from '../../../utils/types';
-import { EditorState, useEditorType } from './types';
+import { createRef, RefObject } from "react";
+import { TextInput } from "react-native";
+import WebView from "react-native-webview";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../../services/event-manager";
+import { NoteType } from "../../../utils/types";
+import { EditorState, useEditorType } from "./types";
export const textInput = createRef();
export const editorController = createRef();
@@ -13,37 +16,45 @@ export const defaultState: Partial = {
export function editorState() {
if (!editorController.current?.state.current) {
- console.warn('Editor state not ready');
+ console.warn("Editor state not ready");
}
return editorController.current?.state.current || defaultState;
}
export const EditorEvents: { [name: string]: string } = {
- html: 'native:html',
- title: 'native:title',
- theme: 'native:theme',
- titleplaceholder: 'native:titleplaceholder',
- logger: 'native:logger',
- status: 'native:status'
+ html: "native:html",
+ title: "native:title",
+ theme: "native:theme",
+ titleplaceholder: "native:titleplaceholder",
+ logger: "native:logger",
+ status: "native:status"
};
export function randId(prefix: string) {
return Math.random()
.toString(36)
- .replace('0.', prefix || '');
+ .replace("0.", prefix || "");
}
export function makeSessionId(item?: NoteType) {
- return item?.id ? item.id + randId('_session_') : randId('session_');
+ return item?.id ? item.id + randId("_session_") : randId("session_");
}
-export async function isEditorLoaded(ref: RefObject, sessionId: string) {
+export async function isEditorLoaded(
+ ref: RefObject,
+ sessionId: string
+) {
return await post(ref, sessionId, EditorEvents.status);
}
-export async function post(ref: RefObject, sessionId: string, type: string, value = null) {
+export async function post(
+ ref: RefObject,
+ sessionId: string,
+ type: string,
+ value = null
+) {
if (!sessionId) {
- console.warn('post called without sessionId of type:', type);
+ console.warn("post called without sessionId of type:", type);
return;
}
let message = {
@@ -53,7 +64,7 @@ export async function post(ref: RefObject, sessionId: string, type: str
};
setImmediate(() => ref.current?.postMessage(JSON.stringify(message)));
let response = await getResponse(type);
- console.log('post: ', type, sessionId, 'result:', !!response);
+ console.log("post: ", type, sessionId, "result:", !!response);
return response;
}
@@ -64,8 +75,10 @@ type WebviewResponseData = {
value: any;
};
-export const getResponse = async (type: string): Promise => {
- return new Promise(resolve => {
+export const getResponse = async (
+ type: string
+): Promise => {
+ return new Promise((resolve) => {
let callback = (data: WebviewResponseData) => {
eUnSubscribeEvent(type, callback);
resolve(data);
@@ -80,10 +93,10 @@ export const getResponse = async (type: string): Promise
' ||
- content === '
' ||
- content === '
'
+ content === "" ||
+ content.trim() === "" ||
+ content === "" ||
+ content === "
" ||
+ content === "
"
);
}
diff --git a/apps/mobile/app/screens/editor/wrapper.js b/apps/mobile/app/screens/editor/wrapper.js
index fd99f097d..98c3c443b 100644
--- a/apps/mobile/app/screens/editor/wrapper.js
+++ b/apps/mobile/app/screens/editor/wrapper.js
@@ -1,37 +1,45 @@
-import React, { useEffect } from 'react';
-import { AppState, KeyboardAvoidingView, Platform, TextInput, View } from 'react-native';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import Editor from '.';
-import { PremiumToast } from '../../components/premium/premium-toast';
-import { DDS } from '../../services/device-detection';
-import { useNoteStore } from '../../stores/use-notes-store';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { editorRef } from '../../utils/global-refs';
-import useIsFloatingKeyboard from '../../hooks/use-is-floating-keyboard';
-import useKeyboard from '../../hooks/use-keyboard';
-import { ProgressBar } from './progress';
-import { editorController, editorState, textInput } from './tiptap/utils';
+import React, { useEffect } from "react";
+import {
+ AppState,
+ KeyboardAvoidingView,
+ Platform,
+ TextInput,
+ View
+} from "react-native";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import Editor from ".";
+import { PremiumToast } from "../../components/premium/premium-toast";
+import { DDS } from "../../services/device-detection";
+import { useNoteStore } from "../../stores/use-notes-store";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { editorRef } from "../../utils/global-refs";
+import useIsFloatingKeyboard from "../../hooks/use-is-floating-keyboard";
+import useKeyboard from "../../hooks/use-keyboard";
+import { ProgressBar } from "./progress";
+import { editorController, editorState, textInput } from "./tiptap/utils";
export const EditorWrapper = ({ width }) => {
- const colors = useThemeStore(state => state.colors);
- const deviceMode = useSettingStore(state => state.deviceMode);
- const loading = useNoteStore(state => state.loading);
+ const colors = useThemeStore((state) => state.colors);
+ const deviceMode = useSettingStore((state) => state.deviceMode);
+ const loading = useNoteStore((state) => state.loading);
const insets = useSafeAreaInsets();
const floating = useIsFloatingKeyboard();
- const introCompleted = useSettingStore(state => state.settings.introCompleted);
+ const introCompleted = useSettingStore(
+ (state) => state.settings.introCompleted
+ );
const keyboard = useKeyboard();
- const onAppStateChanged = async state => {
+ const onAppStateChanged = async (state) => {
if (editorState().movedAway) return;
- if (state === 'active') {
+ if (state === "active") {
editorController.current.onReady();
}
};
useEffect(() => {
if (loading) return;
- let sub = AppState.addEventListener('change', onAppStateChanged);
+ let sub = AppState.addEventListener("change", onAppStateChanged);
return () => {
sub?.remove();
};
@@ -41,7 +49,7 @@ export const EditorWrapper = ({ width }) => {
console.log(insets.top);
if (!keyboard.keyboardShown) return insets.bottom / 2;
if (Platform.isPad && !floating) return 16;
- if (Platform.OS === 'ios') return insets.bottom / 2;
+ if (Platform.OS === "ios") return insets.bottom / 2;
return 6;
};
@@ -50,16 +58,16 @@ export const EditorWrapper = ({ width }) => {
testID="editor-wrapper"
ref={editorRef}
style={{
- width: width[!introCompleted ? 'mobile' : deviceMode]?.c,
- height: '100%',
+ width: width[!introCompleted ? "mobile" : deviceMode]?.c,
+ height: "100%",
backgroundColor: colors.bg,
borderLeftWidth: DDS.isTab ? 1 : 0,
- borderLeftColor: DDS.isTab ? colors.nav : 'transparent'
+ borderLeftColor: DDS.isTab ? colors.nav : "transparent"
}}
>
{loading || !introCompleted ? null : (
{
diff --git a/apps/mobile/app/screens/favorites/index.tsx b/apps/mobile/app/screens/favorites/index.tsx
index 11f9b0834..782ed1da3 100644
--- a/apps/mobile/app/screens/favorites/index.tsx
+++ b/apps/mobile/app/screens/favorites/index.tsx
@@ -1,38 +1,44 @@
-import React from 'react';
-import DelayLayout from '../../components/delay-layout';
-import List from '../../components/list';
-import Navigation, { NavigationProps } from '../../services/navigation';
-import SearchService from '../../services/search';
-import SettingsService from '../../services/settings';
-import { useFavoriteStore } from '../../stores/use-favorite-store';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { useNoteStore } from '../../stores/use-notes-store';
-import { db } from '../../common/database';
-import { useNavigationFocus } from '../../hooks/use-navigation-focus';
+import React from "react";
+import DelayLayout from "../../components/delay-layout";
+import List from "../../components/list";
+import Navigation, { NavigationProps } from "../../services/navigation";
+import SearchService from "../../services/search";
+import SettingsService from "../../services/settings";
+import { useFavoriteStore } from "../../stores/use-favorite-store";
+import useNavigationStore from "../../stores/use-navigation-store";
+import { useNoteStore } from "../../stores/use-notes-store";
+import { db } from "../../common/database";
+import { useNavigationFocus } from "../../hooks/use-navigation-focus";
const prepareSearch = () => {
SearchService.update({
- placeholder: 'Search in favorites',
- type: 'notes',
- title: 'Favorites',
+ placeholder: "Search in favorites",
+ type: "notes",
+ title: "Favorites",
get: () => db.notes?.favorites
});
};
const PLACEHOLDER_DATA = {
- heading: 'Your favorites',
- paragraph: 'You have not added any notes to favorites yet.',
+ heading: "Your favorites",
+ paragraph: "You have not added any notes to favorites yet.",
button: null,
- loading: 'Loading your favorites'
+ loading: "Loading your favorites"
};
-export const Favorites = ({ navigation, route }: NavigationProps<'Favorites'>) => {
- const favorites = useFavoriteStore(state => state.favorites);
- const setFavorites = useFavoriteStore(state => state.setFavorites);
- const loading = useNoteStore(state => state.loading);
+export const Favorites = ({
+ navigation,
+ route
+}: NavigationProps<"Favorites">) => {
+ const favorites = useFavoriteStore((state) => state.favorites);
+ const setFavorites = useFavoriteStore((state) => state.setFavorites);
+ const loading = useNoteStore((state) => state.loading);
const isFocused = useNavigationFocus(navigation, {
- onFocus: prev => {
- Navigation.routeNeedsUpdate(route.name, Navigation.routeUpdateFunctions[route.name]);
+ onFocus: (prev) => {
+ Navigation.routeNeedsUpdate(
+ route.name,
+ Navigation.routeUpdateFunctions[route.name]
+ );
useNavigationStore.getState().update({
name: route.name
});
@@ -55,7 +61,7 @@ export const Favorites = ({ navigation, route }: NavigationProps<'Favorites'>) =
loading={loading || !isFocused}
placeholderData={PLACEHOLDER_DATA}
headerProps={{
- heading: 'Favorites'
+ heading: "Favorites"
}}
/>
diff --git a/apps/mobile/app/screens/home/index.tsx b/apps/mobile/app/screens/home/index.tsx
index 16a794a94..db4fd5166 100755
--- a/apps/mobile/app/screens/home/index.tsx
+++ b/apps/mobile/app/screens/home/index.tsx
@@ -1,39 +1,42 @@
-import React from 'react';
-import { db } from '../../common/database';
-import { FloatingButton } from '../../components/container/floating-button';
-import DelayLayout from '../../components/delay-layout';
-import List from '../../components/list';
-import Navigation, { NavigationProps } from '../../services/navigation';
-import SearchService from '../../services/search';
-import SettingsService from '../../services/settings';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { useNoteStore } from '../../stores/use-notes-store';
-import { openEditor } from '../notes/common';
-import { useNavigationFocus } from '../../hooks/use-navigation-focus';
+import React from "react";
+import { db } from "../../common/database";
+import { FloatingButton } from "../../components/container/floating-button";
+import DelayLayout from "../../components/delay-layout";
+import List from "../../components/list";
+import Navigation, { NavigationProps } from "../../services/navigation";
+import SearchService from "../../services/search";
+import SettingsService from "../../services/settings";
+import useNavigationStore from "../../stores/use-navigation-store";
+import { useNoteStore } from "../../stores/use-notes-store";
+import { openEditor } from "../notes/common";
+import { useNavigationFocus } from "../../hooks/use-navigation-focus";
const prepareSearch = () => {
SearchService.update({
- placeholder: 'Type a keyword to search in notes',
- type: 'notes',
- title: 'Notes',
+ placeholder: "Type a keyword to search in notes",
+ type: "notes",
+ title: "Notes",
get: () => db.notes?.all
});
};
const PLACEHOLDER_DATA = {
- heading: 'Notes',
- paragraph: 'You have not added any notes yet.',
- button: 'Add your first note',
+ heading: "Notes",
+ paragraph: "You have not added any notes yet.",
+ button: "Add your first note",
action: openEditor,
- loading: 'Loading your notes'
+ loading: "Loading your notes"
};
-export const Home = ({ navigation, route }: NavigationProps<'Notes'>) => {
- const notes = useNoteStore(state => state.notes);
- const loading = useNoteStore(state => state.loading);
+export const Home = ({ navigation, route }: NavigationProps<"Notes">) => {
+ const notes = useNoteStore((state) => state.notes);
+ const loading = useNoteStore((state) => state.loading);
const isFocused = useNavigationFocus(navigation, {
- onFocus: prev => {
- console.log('updating', route.name, 'on focus');
- Navigation.routeNeedsUpdate(route.name, Navigation.routeUpdateFunctions[route.name]);
+ onFocus: (prev) => {
+ console.log("updating", route.name, "on focus");
+ Navigation.routeNeedsUpdate(
+ route.name,
+ Navigation.routeUpdateFunctions[route.name]
+ );
useNavigationStore.getState().update({
name: route.name
});
@@ -53,7 +56,7 @@ export const Home = ({ navigation, route }: NavigationProps<'Notes'>) => {
screen="Notes"
loading={loading || !isFocused}
headerProps={{
- heading: 'Notes'
+ heading: "Notes"
}}
placeholderData={PLACEHOLDER_DATA}
/>
diff --git a/apps/mobile/app/screens/notebook/index.tsx b/apps/mobile/app/screens/notebook/index.tsx
index 545e17c47..2dfb3a8a8 100644
--- a/apps/mobile/app/screens/notebook/index.tsx
+++ b/apps/mobile/app/screens/notebook/index.tsx
@@ -1,22 +1,36 @@
-import { groupArray } from '@streetwriters/notesnook-core/utils/grouping';
-import { qclone } from 'qclone';
-import React, { useEffect, useRef, useState } from 'react';
-import { db } from '../../common/database';
-import { FloatingButton } from '../../components/container/floating-button';
-import DelayLayout from '../../components/delay-layout';
-import List from '../../components/list';
-import { NotebookHeader } from '../../components/list-items/headers/notebook-header';
-import { useNavigationFocus } from '../../hooks/use-navigation-focus';
-import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import Navigation, { NavigationProps, NotebookScreenParams } from '../../services/navigation';
-import SearchService from '../../services/search';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { eOnNewTopicAdded, eOpenAddNotebookDialog, eOpenAddTopicDialog } from '../../utils/events';
-import { NotebookType } from '../../utils/types';
+import { groupArray } from "@streetwriters/notesnook-core/utils/grouping";
+import { qclone } from "qclone";
+import React, { useEffect, useRef, useState } from "react";
+import { db } from "../../common/database";
+import { FloatingButton } from "../../components/container/floating-button";
+import DelayLayout from "../../components/delay-layout";
+import List from "../../components/list";
+import { NotebookHeader } from "../../components/list-items/headers/notebook-header";
+import { useNavigationFocus } from "../../hooks/use-navigation-focus";
+import {
+ eSendEvent,
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import Navigation, {
+ NavigationProps,
+ NotebookScreenParams
+} from "../../services/navigation";
+import SearchService from "../../services/search";
+import useNavigationStore from "../../stores/use-navigation-store";
+import {
+ eOnNewTopicAdded,
+ eOpenAddNotebookDialog,
+ eOpenAddTopicDialog
+} from "../../utils/events";
+import { NotebookType } from "../../utils/types";
-const Notebook = ({ route, navigation }: NavigationProps<'Notebook'>) => {
+const Notebook = ({ route, navigation }: NavigationProps<"Notebook">) => {
const [topics, setTopics] = useState(
- groupArray(qclone(route?.params.item?.topics) || [], db.settings?.getGroupOptions('topics'))
+ groupArray(
+ qclone(route?.params.item?.topics) || [],
+ db.settings?.getGroupOptions("topics")
+ )
);
const params = useRef(route?.params);
useNavigationFocus(navigation, {
@@ -35,7 +49,7 @@ const Notebook = ({ route, navigation }: NavigationProps<'Notebook'>) => {
name: route.name,
title: params.current?.title,
id: params.current?.item?.id,
- type: 'notebook'
+ type: "notebook"
},
params.current?.canGoBack
);
@@ -46,10 +60,16 @@ const Notebook = ({ route, navigation }: NavigationProps<'Notebook'>) => {
if (data) params.current = data;
params.current.title = params.current.item.title;
try {
- let notebook = db.notebooks?.notebook(params?.current?.item?.id)?.data as NotebookType;
+ let notebook = db.notebooks?.notebook(params?.current?.item?.id)
+ ?.data as NotebookType;
if (notebook) {
params.current.item = notebook;
- setTopics(groupArray(qclone(notebook.topics), db.settings?.getGroupOptions('topics')));
+ setTopics(
+ groupArray(
+ qclone(notebook.topics),
+ db.settings?.getGroupOptions("topics")
+ )
+ );
syncWithNavigation();
}
} catch (e) {}
@@ -65,10 +85,11 @@ const Notebook = ({ route, navigation }: NavigationProps<'Notebook'>) => {
const prepareSearch = () => {
SearchService.update({
placeholder: `Search in "${params.current.title}"`,
- type: 'topics',
+ type: "topics",
title: params.current.title,
get: () => {
- let notebook = db.notebooks?.notebook(params?.current?.item?.id)?.data as NotebookType;
+ let notebook = db.notebooks?.notebook(params?.current?.item?.id)
+ ?.data as NotebookType;
return notebook?.topics;
}
});
@@ -81,10 +102,10 @@ const Notebook = ({ route, navigation }: NavigationProps<'Notebook'>) => {
const PLACEHOLDER_DATA = {
heading: params.current.item?.title,
- paragraph: 'You have not added any topics yet.',
- button: 'Add first topic',
+ paragraph: "You have not added any topics yet.",
+ button: "Add first topic",
action: onPressFloatingButton,
- loading: 'Loading notebook topics'
+ loading: "Loading notebook topics"
};
return (
@@ -117,12 +138,12 @@ const Notebook = ({ route, navigation }: NavigationProps<'Notebook'>) => {
Notebook.navigate = (item: NotebookType, canGoBack: boolean) => {
if (!item) return;
- Navigation.navigate<'Notebook'>(
+ Navigation.navigate<"Notebook">(
{
title: item.title,
- name: 'Notebook',
+ name: "Notebook",
id: item.id,
- type: 'notebook'
+ type: "notebook"
},
{
title: item.title,
diff --git a/apps/mobile/app/screens/notebooks/index.tsx b/apps/mobile/app/screens/notebooks/index.tsx
index 211b84921..e646eef02 100644
--- a/apps/mobile/app/screens/notebooks/index.tsx
+++ b/apps/mobile/app/screens/notebooks/index.tsx
@@ -1,16 +1,16 @@
-import React from 'react';
-import { db } from '../../common/database';
-import { FloatingButton } from '../../components/container/floating-button';
-import DelayLayout from '../../components/delay-layout';
-import { AddNotebookEvent } from '../../components/dialog-provider/recievers';
-import List from '../../components/list';
-import { Walkthrough } from '../../components/walkthroughs';
-import { useNavigationFocus } from '../../hooks/use-navigation-focus';
-import Navigation, { NavigationProps } from '../../services/navigation';
-import SearchService from '../../services/search';
-import SettingsService from '../../services/settings';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { useNotebookStore } from '../../stores/use-notebook-store';
+import React from "react";
+import { db } from "../../common/database";
+import { FloatingButton } from "../../components/container/floating-button";
+import DelayLayout from "../../components/delay-layout";
+import { AddNotebookEvent } from "../../components/dialog-provider/recievers";
+import List from "../../components/list";
+import { Walkthrough } from "../../components/walkthroughs";
+import { useNavigationFocus } from "../../hooks/use-navigation-focus";
+import Navigation, { NavigationProps } from "../../services/navigation";
+import SearchService from "../../services/search";
+import SettingsService from "../../services/settings";
+import useNavigationStore from "../../stores/use-navigation-store";
+import { useNotebookStore } from "../../stores/use-notebook-store";
const onPressFloatingButton = () => {
AddNotebookEvent();
@@ -18,26 +18,32 @@ const onPressFloatingButton = () => {
const prepareSearch = () => {
SearchService.update({
- placeholder: 'Type a keyword to search in notebooks',
- type: 'notebooks',
- title: 'Notebooks',
+ placeholder: "Type a keyword to search in notebooks",
+ type: "notebooks",
+ title: "Notebooks",
get: () => db.notebooks?.all
});
};
const PLACEHOLDER_DATA = {
- heading: 'Your notebooks',
- paragraph: 'You have not added any notebooks yet.',
- button: 'Add your first notebook',
+ heading: "Your notebooks",
+ paragraph: "You have not added any notebooks yet.",
+ button: "Add your first notebook",
action: onPressFloatingButton,
- loading: 'Loading your notebooks'
+ loading: "Loading your notebooks"
};
-export const Notebooks = ({ navigation, route }: NavigationProps<'Notebooks'>) => {
- const notebooks = useNotebookStore(state => state.notebooks);
+export const Notebooks = ({
+ navigation,
+ route
+}: NavigationProps<"Notebooks">) => {
+ const notebooks = useNotebookStore((state) => state.notebooks);
const isFocused = useNavigationFocus(navigation, {
- onFocus: prev => {
- Navigation.routeNeedsUpdate(route.name, Navigation.routeUpdateFunctions[route.name]);
+ onFocus: (prev) => {
+ Navigation.routeNeedsUpdate(
+ route.name,
+ Navigation.routeUpdateFunctions[route.name]
+ );
useNavigationStore.getState().update({
name: route.name
});
@@ -45,9 +51,9 @@ export const Notebooks = ({ navigation, route }: NavigationProps<'Notebooks'>) =
useNavigationStore.getState().setButtonAction(onPressFloatingButton);
if (notebooks.length === 0) {
- Walkthrough.present('notebooks');
+ Walkthrough.present("notebooks");
} else {
- Walkthrough.update('notebooks');
+ Walkthrough.update("notebooks");
}
return !prev?.current;
@@ -65,12 +71,15 @@ export const Notebooks = ({ navigation, route }: NavigationProps<'Notebooks'>) =
loading={!isFocused}
placeholderData={PLACEHOLDER_DATA}
headerProps={{
- heading: 'Notebooks'
+ heading: "Notebooks"
}}
/>
{!notebooks || notebooks.length === 0 || !isFocused ? null : (
-
+
)}
);
diff --git a/apps/mobile/app/screens/notes/colored.tsx b/apps/mobile/app/screens/notes/colored.tsx
index d9633d7dd..4fb8f4535 100644
--- a/apps/mobile/app/screens/notes/colored.tsx
+++ b/apps/mobile/app/screens/notes/colored.tsx
@@ -1,12 +1,18 @@
-import { groupArray } from '@streetwriters/notesnook-core/utils/grouping';
-import React from 'react';
-import NotesPage, { PLACEHOLDER_DATA } from '.';
-import Navigation, { NavigationProps, NotesScreenParams } from '../../services/navigation';
-import { db } from '../../common/database';
-import { ColorType, TagType } from '../../utils/types';
-import { getAlias, openEditor, toCamelCase } from './common';
+import { groupArray } from "@streetwriters/notesnook-core/utils/grouping";
+import React from "react";
+import NotesPage, { PLACEHOLDER_DATA } from ".";
+import Navigation, {
+ NavigationProps,
+ NotesScreenParams
+} from "../../services/navigation";
+import { db } from "../../common/database";
+import { ColorType, TagType } from "../../utils/types";
+import { getAlias, openEditor, toCamelCase } from "./common";
-export const ColoredNotes = ({ navigation, route }: NavigationProps<'ColoredNotes'>) => {
+export const ColoredNotes = ({
+ navigation,
+ route
+}: NavigationProps<"ColoredNotes">) => {
return (
{
let notes = db.notes?.colored(params.item.id) || [];
- return grouped ? groupArray(notes, db.settings?.getGroupOptions('notes')) : notes;
+ return grouped
+ ? groupArray(notes, db.settings?.getGroupOptions("notes"))
+ : notes;
};
ColoredNotes.navigate = (item: ColorType, canGoBack: boolean) => {
if (!item) return;
//@ts-ignore TODO
let alias = getAlias({ item: item });
- Navigation.navigate<'ColoredNotes'>(
+ Navigation.navigate<"ColoredNotes">(
{
- name: 'ColoredNotes',
+ name: "ColoredNotes",
alias: toCamelCase(alias),
title: toCamelCase(item.title),
id: item.id,
- type: 'color',
+ type: "color",
//@ts-ignore
color: item.title?.toLowerCase()
},
diff --git a/apps/mobile/app/screens/notes/common.ts b/apps/mobile/app/screens/notes/common.ts
index c4c20f2f1..0498d7b9e 100644
--- a/apps/mobile/app/screens/notes/common.ts
+++ b/apps/mobile/app/screens/notes/common.ts
@@ -1,20 +1,20 @@
-import { DDS } from '../../services/device-detection';
-import { eSendEvent } from '../../services/event-manager';
-import Navigation, { NotesScreenParams } from '../../services/navigation';
-import { useMenuStore } from '../../stores/use-menu-store';
-import { useTagStore } from '../../stores/use-tag-store';
-import { db } from '../../common/database';
-import { eOnLoadNote } from '../../utils/events';
-import { openLinkInBrowser } from '../../utils/functions';
-import { tabBarRef } from '../../utils/global-refs';
-import { editorController, editorState } from '../editor/tiptap/utils';
+import { DDS } from "../../services/device-detection";
+import { eSendEvent } from "../../services/event-manager";
+import Navigation, { NotesScreenParams } from "../../services/navigation";
+import { useMenuStore } from "../../stores/use-menu-store";
+import { useTagStore } from "../../stores/use-tag-store";
+import { db } from "../../common/database";
+import { eOnLoadNote } from "../../utils/events";
+import { openLinkInBrowser } from "../../utils/functions";
+import { tabBarRef } from "../../utils/global-refs";
+import { editorController, editorState } from "../editor/tiptap/utils";
export function toCamelCase(title: string) {
return title.slice(0, 1).toUpperCase() + title.slice(1);
}
export function getAlias(params: NotesScreenParams) {
- if (!params) return '';
+ if (!params) return "";
const { item } = params;
//@ts-ignore
return item.alias || item.title;
@@ -22,20 +22,20 @@ export function getAlias(params: NotesScreenParams) {
export function openMonographsWebpage() {
try {
- openLinkInBrowser('https://docs.notesnook.com/monographs/');
+ openLinkInBrowser("https://docs.notesnook.com/monographs/");
} catch (e) {}
}
export function openEditor() {
if (!DDS.isTab) {
if (editorController.current?.note) {
- eSendEvent(eOnLoadNote, { type: 'new' });
+ eSendEvent(eOnLoadNote, { type: "new" });
editorState().currentlyEditing = true;
editorState().movedAway = false;
}
tabBarRef.current?.goToPage(1);
} else {
- eSendEvent(eOnLoadNote, { type: 'new' });
+ eSendEvent(eOnLoadNote, { type: "new" });
}
}
@@ -59,14 +59,16 @@ export const setOnFirstSave = (
return;
}
//@ts-ignore
- editorState().onNoteCreated = id => onNoteCreated(id, data);
+ editorState().onNoteCreated = (id) => onNoteCreated(id, data);
};
export function isSynced(params: NotesScreenParams) {
- if (params.item.type === 'topic') {
+ if (params.item.type === "topic") {
console.log(params.item.type);
- let topic = db.notebooks?.notebook(params.item.notebookId)?.topics.topic(params.item.id);
- console.log(topic?.synced(), 'sycned');
+ let topic = db.notebooks
+ ?.notebook(params.item.notebookId)
+ ?.topics.topic(params.item.id);
+ console.log(topic?.synced(), "sycned");
return !topic ? true : topic?.synced();
}
return true;
@@ -75,7 +77,7 @@ export function isSynced(params: NotesScreenParams) {
async function onNoteCreated(id: string, params: FirstSaveData) {
if (!params) return;
switch (params.type) {
- case 'topic': {
+ case "topic": {
await db.notes?.move(
{
topic: params.id,
@@ -85,37 +87,37 @@ async function onNoteCreated(id: string, params: FirstSaveData) {
);
editorState().onNoteCreated = null;
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes',
- 'Notebook'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes",
+ "Notebook"
);
break;
}
- case 'tag': {
+ case "tag": {
await db.notes?.note(id).tag(params.id);
editorState().onNoteCreated = null;
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes"
);
useTagStore.getState().setTags();
break;
}
- case 'color': {
+ case "color": {
await db.notes?.note(id).color(params.color);
editorState().onNoteCreated = null;
Navigation.queueRoutesForUpdate(
- 'TaggedNotes',
- 'ColoredNotes',
- 'TopicNotes',
- 'Favorites',
- 'Notes'
+ "TaggedNotes",
+ "ColoredNotes",
+ "TopicNotes",
+ "Favorites",
+ "Notes"
);
useMenuStore.getState().setColorNotes();
break;
diff --git a/apps/mobile/app/screens/notes/index.tsx b/apps/mobile/app/screens/notes/index.tsx
index 4ff4e0838..4cc60a792 100644
--- a/apps/mobile/app/screens/notes/index.tsx
+++ b/apps/mobile/app/screens/notes/index.tsx
@@ -1,14 +1,23 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { FloatingButton } from '../../components/container/floating-button';
-import DelayLayout from '../../components/delay-layout';
-import List from '../../components/list';
-import { useNavigationFocus } from '../../hooks/use-navigation-focus';
-import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/event-manager';
-import Navigation, { NavigationProps, NotesScreenParams } from '../../services/navigation';
-import SearchService from '../../services/search';
-import useNavigationStore, { HeaderRightButton, RouteName } from '../../stores/use-navigation-store';
-import { useNoteStore } from '../../stores/use-notes-store';
-import { NoteType } from '../../utils/types';
+import React, { useEffect, useRef, useState } from "react";
+import { FloatingButton } from "../../components/container/floating-button";
+import DelayLayout from "../../components/delay-layout";
+import List from "../../components/list";
+import { useNavigationFocus } from "../../hooks/use-navigation-focus";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent
+} from "../../services/event-manager";
+import Navigation, {
+ NavigationProps,
+ NotesScreenParams
+} from "../../services/navigation";
+import SearchService from "../../services/search";
+import useNavigationStore, {
+ HeaderRightButton,
+ RouteName
+} from "../../stores/use-navigation-store";
+import { useNoteStore } from "../../stores/use-notes-store";
+import { NoteType } from "../../utils/types";
import {
getAlias,
isSynced,
@@ -16,28 +25,28 @@ import {
openMonographsWebpage,
setOnFirstSave,
toCamelCase
-} from './common';
+} from "./common";
export const WARNING_DATA = {
- title: 'Some notes in this topic are not synced'
+ title: "Some notes in this topic are not synced"
};
export const PLACEHOLDER_DATA = {
- heading: 'Your notes',
- paragraph: 'You have not added any notes yet.',
- button: 'Add your first Note',
+ heading: "Your notes",
+ paragraph: "You have not added any notes yet.",
+ button: "Add your first Note",
action: openEditor,
- loading: 'Loading your notes.'
+ loading: "Loading your notes."
};
export const MONOGRAPH_PLACEHOLDER_DATA = {
- heading: 'Your monographs',
- paragraph: 'You have not published any notes as monographs yet.',
- button: 'Learn more about monographs',
+ heading: "Your monographs",
+ paragraph: "You have not published any notes as monographs yet.",
+ button: "Learn more about monographs",
action: openMonographsWebpage,
- loading: 'Loading published notes.',
- type: 'monographs',
- buttonIcon: 'information-outline'
+ loading: "Loading published notes.",
+ type: "monographs",
+ buttonIcon: "information-outline"
};
export interface RouteProps extends NavigationProps {
@@ -50,11 +59,11 @@ export interface RouteProps extends NavigationProps {
}
function getItemType(routeName: RouteName) {
- if (routeName === 'TaggedNotes') return 'tag';
- if (routeName === 'ColoredNotes') return 'color';
- if (routeName === 'TopicNotes') return 'topic';
- if (routeName === 'Monographs') return 'monograph';
- return 'note';
+ if (routeName === "TaggedNotes") return "tag";
+ if (routeName === "ColoredNotes") return "color";
+ if (routeName === "TopicNotes") return "topic";
+ if (routeName === "Monographs") return "monograph";
+ return "note";
}
const NotesPage = ({
@@ -66,18 +75,20 @@ const NotesPage = ({
focusControl = true,
canGoBack,
rightButtons
-}: RouteProps<'NotesPage' | 'TaggedNotes' | 'Monographs' | 'ColoredNotes' | 'TopicNotes'>) => {
+}: RouteProps<
+ "NotesPage" | "TaggedNotes" | "Monographs" | "ColoredNotes" | "TopicNotes"
+>) => {
const params = useRef(route?.params);
const [notes, setNotes] = useState(get(route.params, true));
const [warning, setWarning] = useState(!isSynced(route.params));
- const loading = useNoteStore(state => state.loading);
+ const loading = useNoteStore((state) => state.loading);
const [loadingNotes, setLoadingNotes] = useState(false);
const alias = getAlias(params.current);
- const isMonograph = route.name === 'Monographs';
- console.log(warning, 'isWarning', isSynced(route.params));
+ const isMonograph = route.name === "Monographs";
+ console.log(warning, "isWarning", isSynced(route.params));
const isFocused = useNavigationFocus(navigation, {
- onFocus: prev => {
+ onFocus: (prev) => {
Navigation.routeNeedsUpdate(route.name, onRequestUpdate);
syncWithNavigation();
if (focusControl) return !prev.current;
@@ -94,18 +105,19 @@ const NotesPage = ({
const { item, title } = params.current;
//@ts-ignore
let alias = getAlias(params.current);
- console.log(alias, title, 'syncWithNavigation', params.current);
+ console.log(alias, title, "syncWithNavigation", params.current);
useNavigationStore.getState().update(
{
name: route.name,
title: alias || title,
id: item?.id,
- type: 'notes',
+ type: "notes",
//@ts-ignore
notebookId: item?.notebookId,
- alias: route.name === 'ColoredNotes' ? toCamelCase(alias) : alias,
+ alias: route.name === "ColoredNotes" ? toCamelCase(alias) : alias,
//@ts-ignore
- color: route.name === 'ColoredNotes' ? item.title?.toLowerCase() : undefined
+ color:
+ route.name === "ColoredNotes" ? item.title?.toLowerCase() : undefined
},
params.current.canGoBack,
rightButtons && rightButtons(params.current)
@@ -131,10 +143,13 @@ const NotesPage = ({
try {
if (isNew) setLoadingNotes(true);
let notes = get(params.current, true) as NoteType[];
- if ((item.type === 'tag' || item.type === 'color') && (!notes || notes.length === 0)) {
+ if (
+ (item.type === "tag" || item.type === "color") &&
+ (!notes || notes.length === 0)
+ ) {
return Navigation.goBack();
}
- if (item.type === 'topic') setWarning(!isSynced(params.current));
+ if (item.type === "topic") setWarning(!isSynced(params.current));
setNotes(notes);
syncWithNavigation();
} catch (e) {}
@@ -158,8 +173,8 @@ const NotesPage = ({
const { item } = params.current;
SearchService.update({
placeholder: `Search in ${alias}`,
- type: 'notes',
- title: item.type === 'tag' ? '#' + alias : toCamelCase(item.title),
+ type: "notes",
+ title: item.type === "tag" ? "#" + alias : toCamelCase(item.title),
get: () => {
return get(params.current, false);
}
@@ -168,7 +183,11 @@ const NotesPage = ({
return (
diff --git a/apps/mobile/app/screens/notes/monographs.tsx b/apps/mobile/app/screens/notes/monographs.tsx
index 5509e7e76..c16c69e4d 100644
--- a/apps/mobile/app/screens/notes/monographs.tsx
+++ b/apps/mobile/app/screens/notes/monographs.tsx
@@ -1,12 +1,18 @@
-import { groupArray } from '@streetwriters/notesnook-core/utils/grouping';
-import React from 'react';
-import NotesPage, { PLACEHOLDER_DATA } from '.';
-import Navigation, { NavigationProps, NotesScreenParams } from '../../services/navigation';
-import { db } from '../../common/database';
-import { MonographType } from '../../utils/types';
-import { openMonographsWebpage } from './common';
+import { groupArray } from "@streetwriters/notesnook-core/utils/grouping";
+import React from "react";
+import NotesPage, { PLACEHOLDER_DATA } from ".";
+import Navigation, {
+ NavigationProps,
+ NotesScreenParams
+} from "../../services/navigation";
+import { db } from "../../common/database";
+import { MonographType } from "../../utils/types";
+import { openMonographsWebpage } from "./common";
-export const Monographs = ({ navigation, route }: NavigationProps<'Monographs'>) => {
+export const Monographs = ({
+ navigation,
+ route
+}: NavigationProps<"Monographs">) => {
return (
)
Monographs.get = (params: NotesScreenParams, grouped = true) => {
let notes = db.monographs?.all || [];
- return grouped ? groupArray(notes, db.settings?.getGroupOptions('notes')) : notes;
+ return grouped
+ ? groupArray(notes, db.settings?.getGroupOptions("notes"))
+ : notes;
};
Monographs.navigate = (item: MonographType, canGoBack: boolean) => {
- Navigation.navigate<'Monographs'>(
+ Navigation.navigate<"Monographs">(
{
- name: 'Monographs',
- type: 'monograph'
+ name: "Monographs",
+ type: "monograph"
},
{
//@ts-ignore
- item: { type: 'monograph' },
+ item: { type: "monograph" },
canGoBack,
- title: 'Monographs'
+ title: "Monographs"
}
);
};
diff --git a/apps/mobile/app/screens/notes/tagged.tsx b/apps/mobile/app/screens/notes/tagged.tsx
index e71632d32..cc0cad9c5 100644
--- a/apps/mobile/app/screens/notes/tagged.tsx
+++ b/apps/mobile/app/screens/notes/tagged.tsx
@@ -1,12 +1,18 @@
-import { groupArray } from '@streetwriters/notesnook-core/utils/grouping';
-import React from 'react';
-import NotesPage, { PLACEHOLDER_DATA } from '.';
-import Navigation, { NavigationProps, NotesScreenParams } from '../../services/navigation';
-import { db } from '../../common/database';
-import { TagType } from '../../utils/types';
-import { getAlias, openEditor } from './common';
+import { groupArray } from "@streetwriters/notesnook-core/utils/grouping";
+import React from "react";
+import NotesPage, { PLACEHOLDER_DATA } from ".";
+import Navigation, {
+ NavigationProps,
+ NotesScreenParams
+} from "../../services/navigation";
+import { db } from "../../common/database";
+import { TagType } from "../../utils/types";
+import { getAlias, openEditor } from "./common";
-export const TaggedNotes = ({ navigation, route }: NavigationProps<'TaggedNotes'>) => {
+export const TaggedNotes = ({
+ navigation,
+ route
+}: NavigationProps<"TaggedNotes">) => {
return (
{
let notes = db.notes?.tagged(params.item.id) || [];
- return grouped ? groupArray(notes, db.settings?.getGroupOptions('notes')) : notes;
+ return grouped
+ ? groupArray(notes, db.settings?.getGroupOptions("notes"))
+ : notes;
};
TaggedNotes.navigate = (item: TagType, canGoBack: boolean) => {
if (!item) return;
//@ts-ignore TODO
let alias = getAlias({ item: item });
- Navigation.navigate<'TaggedNotes'>(
+ Navigation.navigate<"TaggedNotes">(
{
- name: 'TaggedNotes',
+ name: "TaggedNotes",
alias: alias,
title: item.title,
id: item.id,
- type: 'tag'
+ type: "tag"
},
{
item: item,
diff --git a/apps/mobile/app/screens/notes/topic-notes.tsx b/apps/mobile/app/screens/notes/topic-notes.tsx
index 5cd94d108..2987fb276 100644
--- a/apps/mobile/app/screens/notes/topic-notes.tsx
+++ b/apps/mobile/app/screens/notes/topic-notes.tsx
@@ -1,20 +1,23 @@
-import { groupArray } from '@streetwriters/notesnook-core/utils/grouping';
-import React from 'react';
-import NotesPage, { PLACEHOLDER_DATA } from '.';
-import { MoveNotes } from '../../components/sheets/move-notes/movenote';
-import { eSendEvent } from '../../services/event-manager';
-import Navigation, { NavigationProps, NotesScreenParams } from '../../services/navigation';
-import { db } from '../../common/database';
-import { eOpenAddTopicDialog } from '../../utils/events';
-import { TopicType } from '../../utils/types';
-import { openEditor } from './common';
+import { groupArray } from "@streetwriters/notesnook-core/utils/grouping";
+import React from "react";
+import NotesPage, { PLACEHOLDER_DATA } from ".";
+import { MoveNotes } from "../../components/sheets/move-notes/movenote";
+import { eSendEvent } from "../../services/event-manager";
+import Navigation, {
+ NavigationProps,
+ NotesScreenParams
+} from "../../services/navigation";
+import { db } from "../../common/database";
+import { eOpenAddTopicDialog } from "../../utils/events";
+import { TopicType } from "../../utils/types";
+import { openEditor } from "./common";
const headerRightButtons = (params: NotesScreenParams) => [
{
- title: 'Edit topic',
+ title: "Edit topic",
onPress: () => {
const { item } = params;
- if (item.type !== 'topic') return;
+ if (item.type !== "topic") return;
eSendEvent(eOpenAddTopicDialog, {
notebookId: item.notebookId,
toEdit: item
@@ -22,16 +25,19 @@ const headerRightButtons = (params: NotesScreenParams) => [
}
},
{
- title: 'Move notes',
+ title: "Move notes",
onPress: () => {
const { item } = params;
- if (item?.type !== 'topic') return;
+ if (item?.type !== "topic") return;
MoveNotes.present(db.notebooks?.notebook(item.notebookId).data, item);
}
}
];
-export const TopicNotes = ({ navigation, route }: NavigationProps<'TopicNotes'>) => {
+export const TopicNotes = ({
+ navigation,
+ route
+}: NavigationProps<"TopicNotes">) => {
return (
{
//@ts-ignore
const { id, notebookId } = params.item;
let notes = db.notebooks?.notebook(notebookId)?.topics.topic(id)?.all || [];
- return grouped ? groupArray(notes, db.settings?.getGroupOptions('notes')) : notes;
+ return grouped
+ ? groupArray(notes, db.settings?.getGroupOptions("notes"))
+ : notes;
};
TopicNotes.navigate = (item: TopicType, canGoBack: boolean) => {
if (!item) return;
- Navigation.navigate<'TopicNotes'>(
+ Navigation.navigate<"TopicNotes">(
{
- name: 'TopicNotes',
+ name: "TopicNotes",
title: item.title,
id: item.id,
- type: 'topic',
+ type: "topic",
notebookId: item.notebookId
},
{
diff --git a/apps/mobile/app/screens/search/index.js b/apps/mobile/app/screens/search/index.js
index e2e330d50..46c0fb7d2 100644
--- a/apps/mobile/app/screens/search/index.js
+++ b/apps/mobile/app/screens/search/index.js
@@ -1,19 +1,19 @@
-import React, { useEffect } from 'react';
-import DelayLayout from '../../components/delay-layout';
-import List from '../../components/list';
-import SearchService from '../../services/search';
-import useNavigationStore from '../../stores/use-navigation-store';
-import { useSearchStore } from '../../stores/use-search-store';
-import { inputRef } from '../../utils/global-refs';
-import { useNavigationFocus } from '../../hooks/use-navigation-focus';
-import { sleep } from '../../utils/time';
+import React, { useEffect } from "react";
+import DelayLayout from "../../components/delay-layout";
+import List from "../../components/list";
+import SearchService from "../../services/search";
+import useNavigationStore from "../../stores/use-navigation-store";
+import { useSearchStore } from "../../stores/use-search-store";
+import { inputRef } from "../../utils/global-refs";
+import { useNavigationFocus } from "../../hooks/use-navigation-focus";
+import { sleep } from "../../utils/time";
export const Search = ({ navigation, route }) => {
- const searchResults = useSearchStore(state => state.searchResults);
- const searching = useSearchStore(state => state.searching);
- const searchStatus = useSearchStore(state => state.searchStatus);
- const setSearchResults = useSearchStore(state => state.setSearchResults);
- const setSearchStatus = useSearchStore(state => state.setSearchStatus);
+ const searchResults = useSearchStore((state) => state.searchResults);
+ const searching = useSearchStore((state) => state.searching);
+ const searchStatus = useSearchStore((state) => state.searchStatus);
+ const setSearchResults = useSearchStore((state) => state.setSearchResults);
+ const setSearchStatus = useSearchStore((state) => state.setSearchStatus);
useNavigationFocus(navigation, {
onFocus: () => {
@@ -45,12 +45,14 @@ export const Search = ({ navigation, route }) => {
loading={searching}
CustomHeader={true}
placeholderData={{
- heading: 'Search',
+ heading: "Search",
paragraph:
searchStatus ||
- `Type a keyword to search in ${SearchService.getSearchInformation().title}`,
+ `Type a keyword to search in ${
+ SearchService.getSearchInformation().title
+ }`,
button: null,
- loading: 'Searching...'
+ loading: "Searching..."
}}
/>
diff --git a/apps/mobile/app/screens/search/search-bar.js b/apps/mobile/app/screens/search/search-bar.js
index a3b3fc77d..cf9c6aa7c 100644
--- a/apps/mobile/app/screens/search/search-bar.js
+++ b/apps/mobile/app/screens/search/search-bar.js
@@ -1,23 +1,27 @@
-import React, { useEffect, useRef, useState } from 'react';
-import { Platform, View } from 'react-native';
-import { TextInput } from 'react-native-gesture-handler';
-import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import { IconButton } from '../../components/ui/icon-button';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { useSearchStore } from '../../stores/use-search-store';
-import { eSubscribeEvent, eUnSubscribeEvent, ToastEvent } from '../../services/event-manager';
-import Navigation from '../../services/navigation';
-import SearchService from '../../services/search';
-import { eScrollEvent } from '../../utils/events';
-import { normalize, SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
+import React, { useEffect, useRef, useState } from "react";
+import { Platform, View } from "react-native";
+import { TextInput } from "react-native-gesture-handler";
+import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { IconButton } from "../../components/ui/icon-button";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { useSearchStore } from "../../stores/use-search-store";
+import {
+ eSubscribeEvent,
+ eUnSubscribeEvent,
+ ToastEvent
+} from "../../services/event-manager";
+import Navigation from "../../services/navigation";
+import SearchService from "../../services/search";
+import { eScrollEvent } from "../../utils/events";
+import { normalize, SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
export const SearchBar = () => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
const [value, setValue] = useState(null);
const inputRef = useRef();
- const setSearchResults = useSearchStore(state => state.setSearchResults);
- const setSearchStatus = useSearchStore(state => state.setSearchStatus);
+ const setSearchResults = useSearchStore((state) => state.setSearchResults);
+ const setSearchStatus = useSearchStore((state) => state.setSearchStatus);
const searchingRef = useRef(0);
const insets = useSafeAreaInsets();
const onClear = () => {
@@ -35,7 +39,7 @@ export const SearchBar = () => {
});
}, []);
- const onScroll = event => {
+ const onScroll = (event) => {
console.log(event);
};
useEffect(() => {
@@ -45,16 +49,16 @@ export const SearchBar = () => {
};
}, []);
- const onChangeText = value => {
+ const onChangeText = (value) => {
setValue(value);
search(value);
};
- const search = value => {
+ const search = (value) => {
clearTimeout(searchingRef.current);
searchingRef.current = setTimeout(async () => {
try {
- if (value === '' || !value) {
+ if (value === "" || !value) {
setSearchResults([]);
setSearchStatus(false, null);
return;
@@ -66,9 +70,9 @@ export const SearchBar = () => {
} catch (e) {
console.log(e);
ToastEvent.show({
- heading: 'Error occured while searching',
+ heading: "Error occured while searching",
message: e.message,
- type: 'error'
+ type: "error"
});
}
}, 300);
@@ -78,10 +82,10 @@ export const SearchBar = () => {
{
testID="search-input"
style={{
fontSize: SIZE.md + 1,
- fontFamily: 'OpenSans-Regular',
+ fontFamily: "OpenSans-Regular",
flexGrow: 1,
- height: '100%',
+ height: "100%",
color: colors.pri
}}
onChangeText={onChangeText}
diff --git a/apps/mobile/app/screens/settings/2fa.tsx b/apps/mobile/app/screens/settings/2fa.tsx
index c857d29ae..c1d153e7f 100644
--- a/apps/mobile/app/screens/settings/2fa.tsx
+++ b/apps/mobile/app/screens/settings/2fa.tsx
@@ -1,52 +1,62 @@
-import Clipboard from '@react-native-clipboard/clipboard';
-import React, { Dispatch, SetStateAction, useEffect, useRef, useState } from 'react';
-import { ActivityIndicator, Linking, Platform, View } from 'react-native';
-import { FlatList } from 'react-native-gesture-handler';
-import * as ScopedStorage from 'react-native-scoped-storage';
-import RNFetchBlob from 'rn-fetch-blob';
-import DialogHeader from '../../components/dialog/dialog-header';
-import { Button } from '../../components/ui/button';
-import { IconButton } from '../../components/ui/icon-button';
-import Input from '../../components/ui/input';
-import { PressableButton } from '../../components/ui/pressable';
-import Seperator from '../../components/ui/seperator';
-import { SvgView } from '../../components/ui/svg';
-import Heading from '../../components/ui/typography/heading';
-import Paragraph from '../../components/ui/typography/paragraph';
-import { eSendEvent, presentSheet, ToastEvent } from '../../services/event-manager';
-import { useUserStore } from '../../stores/use-user-store';
-import { ThemeStore, useThemeStore } from '../../stores/use-theme-store';
-import { db } from '../../common/database';
-import Storage from '../../common/database/storage';
-import { eCloseProgressDialog } from '../../utils/events';
-import useTimer from '../../hooks/use-timer';
-import { sanitizeFilename } from '../../utils/sanitizer';
-import { SIZE } from '../../utils/size';
-import { sleep } from '../../utils/time';
+import Clipboard from "@react-native-clipboard/clipboard";
+import React, {
+ Dispatch,
+ SetStateAction,
+ useEffect,
+ useRef,
+ useState
+} from "react";
+import { ActivityIndicator, Linking, Platform, View } from "react-native";
+import { FlatList } from "react-native-gesture-handler";
+import * as ScopedStorage from "react-native-scoped-storage";
+import RNFetchBlob from "rn-fetch-blob";
+import DialogHeader from "../../components/dialog/dialog-header";
+import { Button } from "../../components/ui/button";
+import { IconButton } from "../../components/ui/icon-button";
+import Input from "../../components/ui/input";
+import { PressableButton } from "../../components/ui/pressable";
+import Seperator from "../../components/ui/seperator";
+import { SvgView } from "../../components/ui/svg";
+import Heading from "../../components/ui/typography/heading";
+import Paragraph from "../../components/ui/typography/paragraph";
+import {
+ eSendEvent,
+ presentSheet,
+ ToastEvent
+} from "../../services/event-manager";
+import { useUserStore } from "../../stores/use-user-store";
+import { ThemeStore, useThemeStore } from "../../stores/use-theme-store";
+import { db } from "../../common/database";
+import Storage from "../../common/database/storage";
+import { eCloseProgressDialog } from "../../utils/events";
+import useTimer from "../../hooks/use-timer";
+import { sanitizeFilename } from "../../utils/sanitizer";
+import { SIZE } from "../../utils/size";
+import { sleep } from "../../utils/time";
const mfaMethods: MFAMethod[] = [
{
- id: 'app',
- title: 'Setup using an Authenticator app',
- body: 'Use an authenticator app like Google Authenticator on your phone to get authentication codes',
- icon: 'cellphone-key',
+ id: "app",
+ title: "Setup using an Authenticator app",
+ body: "Use an authenticator app like Google Authenticator on your phone to get authentication codes",
+ icon: "cellphone-key",
recommended: true
},
{
- id: 'sms',
- title: 'Set up using SMS',
- body: 'Notesnook will send you an SMS with a 2FA code when prompted',
- icon: 'message-plus-outline'
+ id: "sms",
+ title: "Set up using SMS",
+ body: "Notesnook will send you an SMS with a 2FA code when prompted",
+ icon: "message-plus-outline"
},
{
- id: 'email',
- title: 'Set up using Email',
- body: 'Notesnook will send you a 2FA code on your email when prompted',
- icon: 'email-outline'
+ id: "email",
+ title: "Set up using Email",
+ body: "Notesnook will send you a 2FA code on your email when prompted",
+ icon: "email-outline"
}
];
type MFAMethod = {
- id: 'email' | 'sms' | 'app';
+ id: "email" | "sms" | "app";
title?: string;
body?: string;
icon?: string;
@@ -66,12 +76,12 @@ type MFAStepProps = {
isSetup?: boolean;
};
export const MFAMethodsPickerStep = ({ recovery, onSuccess }: MFAStepProps) => {
- const colors = useThemeStore(state => state.colors);
- const user = useUserStore(state => state.user);
+ const colors = useThemeStore((state) => state.colors);
+ const user = useUserStore((state) => state.user);
const getMethods = () => {
if (!recovery) return mfaMethods;
- return mfaMethods.filter(m => m.id !== user?.mfa?.primaryMethod);
+ return mfaMethods.filter((m) => m.id !== user?.mfa?.primaryMethod);
};
return (
@@ -82,7 +92,7 @@ export const MFAMethodsPickerStep = ({ recovery, onSuccess }: MFAStepProps) => {
padding={12}
/>
- {getMethods().map(item => (
+ {getMethods().map((item) => (
{
@@ -93,9 +103,9 @@ export const MFAMethodsPickerStep = ({ recovery, onSuccess }: MFAStepProps) => {
paddingVertical: 12,
marginTop: 0,
marginBottom: 12,
- flexDirection: 'row',
+ flexDirection: "row",
borderRadius: 0,
- alignItems: 'flex-start'
+ alignItems: "flex-start"
}}
>
{
);
};
-export const MFASetup = ({ method, onSuccess, setStep, recovery }: MFAStepProps) => {
- const colors = useThemeStore(state => state.colors);
- const user = useUserStore(state => state.user);
+export const MFASetup = ({
+ method,
+ onSuccess,
+ setStep,
+ recovery
+}: MFAStepProps) => {
+ const colors = useThemeStore((state) => state.colors);
+ const user = useUserStore((state) => state.user);
const [authenticatorDetails, setAuthenticatorDetails] = useState({
sharedKey: null,
authenticatorUri: null
@@ -134,14 +149,14 @@ export const MFASetup = ({ method, onSuccess, setStep, recovery }: MFAStepProps)
const phoneNumber = useRef();
const { seconds, setId, start } = useTimer(method?.id);
- const [loading, setLoading] = useState(method?.id === 'app' ? true : false);
+ const [loading, setLoading] = useState(method?.id === "app" ? true : false);
const [enabling, setEnabling] = useState(false);
const [sending, setSending] = useState(false);
const [error, setError] = useState(false);
useEffect(() => {
- if (method?.id === 'app') {
- db.mfa?.setup('app').then(data => {
+ if (method?.id === "app") {
+ db.mfa?.setup("app").then((data) => {
setAuthenticatorDetails(data);
setLoading(false);
});
@@ -149,9 +164,10 @@ export const MFASetup = ({ method, onSuccess, setStep, recovery }: MFAStepProps)
}, []);
const codeHelpText = {
- app: 'After putting the above code in authenticator app, the app will display a code that you can enter below.',
- sms: 'You will receive a 2FA code on your phone number which you can enter below',
- email: 'You will receive a 2FA code on your email address which you can enter below'
+ app: "After putting the above code in authenticator app, the app will display a code that you can enter below.",
+ sms: "You will receive a 2FA code on your phone number which you can enter below",
+ email:
+ "You will receive a 2FA code on your email address which you can enter below"
};
const onNext = async () => {
@@ -160,10 +176,10 @@ export const MFASetup = ({ method, onSuccess, setStep, recovery }: MFAStepProps)
if (!method) return;
setEnabling(true);
if (recovery) {
- console.log('enabling secondary method for 2FA');
+ console.log("enabling secondary method for 2FA");
await db.mfa?.enableFallback(method.id, code.current);
} else {
- console.log('enabling primary method for 2FA');
+ console.log("enabling primary method for 2FA");
await db.mfa?.enable(method.id, code.current);
}
@@ -173,60 +189,71 @@ export const MFASetup = ({ method, onSuccess, setStep, recovery }: MFAStepProps)
setEnabling(false);
} catch (e) {
const error = e as Error;
- console.log('2fa submit code:', error.message);
- ToastEvent.error(error, 'Error submitting 2fa code');
+ console.log("2fa submit code:", error.message);
+ ToastEvent.error(error, "Error submitting 2fa code");
setEnabling(false);
}
};
const onSendCode = async () => {
- console.log('send code');
+ console.log("send code");
if (error) return;
if (!method || sending) return;
- if (method.id === 'app' && authenticatorDetails.sharedKey) {
+ if (method.id === "app" && authenticatorDetails.sharedKey) {
Clipboard.setString(authenticatorDetails.sharedKey);
if (authenticatorDetails.authenticatorUri) {
- await Linking.openURL(authenticatorDetails.authenticatorUri).catch(console.log);
+ await Linking.openURL(authenticatorDetails.authenticatorUri).catch(
+ console.log
+ );
}
ToastEvent.show({
heading: `Code copied!`,
- type: 'success',
- context: 'local'
+ type: "success",
+ context: "local"
});
return;
}
try {
- console.log('seconds', seconds);
- if (seconds) throw new Error('Please wait a few seconds before resending code');
- if (method.id === 'sms' && !phoneNumber.current) throw new Error('Phone number not entered');
+ console.log("seconds", seconds);
+ if (seconds)
+ throw new Error("Please wait a few seconds before resending code");
+ if (method.id === "sms" && !phoneNumber.current)
+ throw new Error("Phone number not entered");
setSending(true);
await db.mfa?.setup(method?.id, phoneNumber.current);
- if (method.id === 'sms') {
+ if (method.id === "sms") {
console.log(phoneNumber.current);
setId(method.id + phoneNumber.current);
}
await sleep(300);
- start(60, method.id === 'sms' ? method.id + phoneNumber.current : method.id);
+ start(
+ 60,
+ method.id === "sms" ? method.id + phoneNumber.current : method.id
+ );
setSending(false);
ToastEvent.show({
heading: `2FA code sent via ${method.id}.`,
- type: 'success',
- context: 'local'
+ type: "success",
+ context: "local"
});
} catch (e) {
setSending(false);
const error = e as Error;
- console.log('Send code:', error.message);
- ToastEvent.error(error, 'Error sending 2FA code');
+ console.log("Send code:", error.message);
+ ToastEvent.error(error, "Error sending 2FA code");
}
};
return !method ? null : (
-
+
@@ -254,24 +281,26 @@ export const MFASetup = ({ method, onSuccess, setStep, recovery }: MFAStepProps)
) : (
<>
{
+ multiline={method.id === "app"}
+ onChangeText={(value) => {
phoneNumber.current = value;
}}
- placeholder={method?.id === 'email' ? 'Enter email address' : '+1234567890'}
+ placeholder={
+ method?.id === "email" ? "Enter email address" : "+1234567890"
+ }
onSubmit={() => {
onSendCode();
}}
- onErrorCheck={e => setError(e)}
+ onErrorCheck={(e) => setError(e)}
validationType="phonenumber"
keyboardType="phone-pad"
errorMessage="Please enter a valid phone number with country code"
@@ -283,9 +312,13 @@ export const MFASetup = ({ method, onSuccess, setStep, recovery }: MFAStepProps)
title={
sending
? null
- : method.id === 'app'
- ? 'Copy'
- : `${seconds ? `Resend code in (${seconds})` : 'Send code'}`
+ : method.id === "app"
+ ? "Copy"
+ : `${
+ seconds
+ ? `Resend code in (${seconds})`
+ : "Send code"
+ }`
}
/>
)
@@ -301,12 +334,12 @@ export const MFASetup = ({ method, onSuccess, setStep, recovery }: MFAStepProps)
loading={loading}
textAlign="center"
keyboardType="numeric"
- onChangeText={value => (code.current = value)}
+ onChangeText={(value) => (code.current = value)}
//@ts-ignore
inputStyle={{
fontSize: SIZE.lg,
height: 60,
- textAlign: 'center',
+ textAlign: "center",
letterSpacing: 10,
width: null
}}
@@ -319,7 +352,7 @@ export const MFASetup = ({ method, onSuccess, setStep, recovery }: MFAStepProps)
/>
{
setStep &&
setStep({
- id: 'mfapick',
+ id: "mfapick",
props: {
recovery: recovery
}
@@ -351,8 +384,13 @@ export const MFASetup = ({ method, onSuccess, setStep, recovery }: MFAStepProps)
);
};
-export const MFARecoveryCodes = ({ method, recovery, onSuccess, isSetup = true }: MFAStepProps) => {
- const colors = useThemeStore(state => state.colors);
+export const MFARecoveryCodes = ({
+ method,
+ recovery,
+ onSuccess,
+ isSetup = true
+}: MFAStepProps) => {
+ const colors = useThemeStore((state) => state.colors);
const [codes, setCodes] = useState([]);
const [loading, setLoading] = useState(true);
@@ -364,7 +402,7 @@ export const MFARecoveryCodes = ({ method, recovery, onSuccess, isSetup = true }
setLoading(false);
} catch (e) {
const error = e as Error;
- ToastEvent.error(error, 'Error getting codes', 'local');
+ ToastEvent.error(error, "Error getting codes", "local");
setLoading(false);
}
})();
@@ -376,7 +414,11 @@ export const MFARecoveryCodes = ({ method, recovery, onSuccess, isSetup = true }
centered={true}
title="Save your recovery codes"
paragraph={`If you lose access to your ${
- method?.id === 'email' ? 'email' : method?.id === 'sms' ? 'phone' : 'auth app'
+ method?.id === "email"
+ ? "email"
+ : method?.id === "sms"
+ ? "phone"
+ : "auth app"
}, you can login to Notesnook using your recovery codes. Each code can only be used once.`}
padding={12}
/>
@@ -385,9 +427,9 @@ export const MFARecoveryCodes = ({ method, recovery, onSuccess, isSetup = true }
{loading ? (
@@ -404,12 +446,16 @@ export const MFARecoveryCodes = ({ method, recovery, onSuccess, isSetup = true }
(
{item}
@@ -420,8 +466,8 @@ export const MFARecoveryCodes = ({ method, recovery, onSuccess, isSetup = true }
@@ -429,12 +475,12 @@ export const MFARecoveryCodes = ({ method, recovery, onSuccess, isSetup = true }
title="Copy codes"
fontSize={SIZE.md}
onPress={() => {
- let codeString = codes.join('\n');
+ let codeString = codes.join("\n");
Clipboard.setString(codeString);
ToastEvent.show({
- heading: 'Recovery codes copied!',
- type: 'success',
- context: 'global'
+ heading: "Recovery codes copied!",
+ type: "success",
+ context: "global"
});
}}
style={{
@@ -448,29 +494,33 @@ export const MFARecoveryCodes = ({ method, recovery, onSuccess, isSetup = true }
onPress={async () => {
try {
let path;
- let fileName = 'notesnook_recoverycodes';
- fileName = sanitizeFilename(fileName, { replacement: '_' });
- fileName = fileName + '.txt';
- const codeString = codes.join('\n');
- if (Platform.OS === 'android') {
+ let fileName = "notesnook_recoverycodes";
+ fileName = sanitizeFilename(fileName, { replacement: "_" });
+ fileName = fileName + ".txt";
+ const codeString = codes.join("\n");
+ if (Platform.OS === "android") {
let file = await ScopedStorage.createDocument(
fileName,
- 'text/plain',
+ "text/plain",
codeString,
- 'utf8'
+ "utf8"
);
if (!file) return;
path = file.uri;
} else {
- path = await Storage.checkAndCreateDir('/');
- await RNFetchBlob.fs.writeFile(path + fileName, codeString, 'utf8');
+ path = await Storage.checkAndCreateDir("/");
+ await RNFetchBlob.fs.writeFile(
+ path + fileName,
+ codeString,
+ "utf8"
+ );
path = path + fileName;
}
ToastEvent.show({
- heading: 'Recovery codes saved to text file',
- type: 'success',
- context: 'local'
+ heading: "Recovery codes saved to text file",
+ type: "success",
+ context: "local"
});
return path;
} catch (e) {}
@@ -479,7 +529,7 @@ export const MFARecoveryCodes = ({ method, recovery, onSuccess, isSetup = true }
{
@@ -500,14 +550,14 @@ export const MFARecoveryCodes = ({ method, recovery, onSuccess, isSetup = true }
);
};
-MFARecoveryCodes.present = (methodId: MFAMethod['id']) => {
+MFARecoveryCodes.present = (methodId: MFAMethod["id"]) => {
presentSheet({
component:
});
};
const mfaSvg = (
- colors: ThemeStore['colors']
+ colors: ThemeStore["colors"]
) => ``;
const MFASuccess = ({ recovery }: MFAStepProps) => {
- const colors = useThemeStore(state => state.colors);
+ const colors = useThemeStore((state) => state.colors);
return (
@@ -528,7 +578,11 @@ const MFASuccess = ({ recovery }: MFAStepProps) => {
@@ -563,7 +617,7 @@ const MFASuccess = ({ recovery }: MFAStepProps) => {
export const MFASheet = ({ recovery }: { recovery?: boolean }) => {
const [step, setStep] = useState({
- id: 'mfapick',
+ id: "mfapick",
props: {
recovery: recovery
}
@@ -573,9 +627,9 @@ export const MFASheet = ({ recovery }: { recovery?: boolean }) => {
mfapick: (
{
+ onSuccess={(method) => {
setStep({
- id: 'setup',
+ id: "setup",
props: {
method: method
}
@@ -588,9 +642,9 @@ export const MFASheet = ({ recovery }: { recovery?: boolean }) => {
recovery={recovery}
setStep={setStep}
{...step.props}
- onSuccess={method => {
+ onSuccess={(method) => {
setStep({
- id: 'recoveryCodes',
+ id: "recoveryCodes",
props: {
method: method
}
@@ -602,9 +656,9 @@ export const MFASheet = ({ recovery }: { recovery?: boolean }) => {
{
+ onSuccess={(method) => {
setStep({
- id: 'success',
+ id: "success",
props: {
method: method
}
diff --git a/apps/mobile/app/screens/settings/app-lock.js b/apps/mobile/app/screens/settings/app-lock.js
index e24a972cc..f6823eb8f 100644
--- a/apps/mobile/app/screens/settings/app-lock.js
+++ b/apps/mobile/app/screens/settings/app-lock.js
@@ -1,53 +1,53 @@
-import React, { useState } from 'react';
-import { Dimensions, LayoutAnimation, Platform, View } from 'react-native';
-import Animated, { FadeInDown, FadeOutUp } from 'react-native-reanimated';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { SVG_Z } from '../../components/intro';
-import { WelcomeNotice } from '../../components/intro/welcome';
-import { Button } from '../../components/ui/button';
-import { PressableButton } from '../../components/ui/pressable';
-import Seperator from '../../components/ui/seperator';
-import { SvgView } from '../../components/ui/svg';
-import { BouncingView } from '../../components/ui/transitions/bouncing-view';
-import Heading from '../../components/ui/typography/heading';
-import Paragraph from '../../components/ui/typography/paragraph';
-import { DDS } from '../../services/device-detection';
-import { presentSheet, ToastEvent } from '../../services/event-manager';
-import SettingsService from '../../services/settings';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { getElevation } from '../../utils';
-import umami from '../../common/analytics';
-import { SIZE } from '../../utils/size';
-import BiometicService from '../../services/biometrics';
-import { useUserStore } from '../../stores/use-user-store';
+import React, { useState } from "react";
+import { Dimensions, LayoutAnimation, Platform, View } from "react-native";
+import Animated, { FadeInDown, FadeOutUp } from "react-native-reanimated";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { SVG_Z } from "../../components/intro";
+import { WelcomeNotice } from "../../components/intro/welcome";
+import { Button } from "../../components/ui/button";
+import { PressableButton } from "../../components/ui/pressable";
+import Seperator from "../../components/ui/seperator";
+import { SvgView } from "../../components/ui/svg";
+import { BouncingView } from "../../components/ui/transitions/bouncing-view";
+import Heading from "../../components/ui/typography/heading";
+import Paragraph from "../../components/ui/typography/paragraph";
+import { DDS } from "../../services/device-detection";
+import { presentSheet, ToastEvent } from "../../services/event-manager";
+import SettingsService from "../../services/settings";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import { getElevation } from "../../utils";
+import umami from "../../common/analytics";
+import { SIZE } from "../../utils/size";
+import BiometicService from "../../services/biometrics";
+import { useUserStore } from "../../stores/use-user-store";
const AppLock = ({ navigation, route }) => {
- const colors = useThemeStore(state => state.colors);
- const appLockMode = useSettingStore(state => state.settings.appLockMode);
+ const colors = useThemeStore((state) => state.colors);
+ const appLockMode = useSettingStore((state) => state.settings.appLockMode);
const [step, setStep] = useState(0);
const welcome = route?.params?.welcome;
const modes = [
{
- title: 'No privacy',
- value: 'none',
- desc: 'Your notes are always unlocked. Anyone who has access to your phone can read them.',
+ title: "No privacy",
+ value: "none",
+ desc: "Your notes are always unlocked. Anyone who has access to your phone can read them.",
activeColor: colors.errorText
},
{
- title: 'Medium privacy',
- value: 'launch',
- desc: 'Your notes are locked when you exit the app but remain unlocked when you switch to other apps or background.',
+ title: "Medium privacy",
+ value: "launch",
+ desc: "Your notes are locked when you exit the app but remain unlocked when you switch to other apps or background.",
activeColor: colors.accent
},
{
- title: 'Maximum privacy (Recommended)',
- value: 'background',
+ title: "Maximum privacy (Recommended)",
+ value: "background",
desc: `Your notes are locked immediately when you switch to other apps or background. ${
- Platform.OS === 'ios'
- ? 'App contents are hidden in app switcher'
- : 'Screenshots are disabled and app contents are hidden in app switcher.'
+ Platform.OS === "ios"
+ ? "App contents are hidden in app switcher"
+ : "Screenshots are disabled and app contents are hidden in app switcher."
}`,
activeColor: colors.accent
}
@@ -59,25 +59,25 @@ const AppLock = ({ navigation, route }) => {
exiting={!welcome ? undefined : FadeOutUp}
entering={!welcome ? undefined : FadeInDown}
style={{
- justifyContent: !welcome ? undefined : 'center',
- height: !welcome ? undefined : '100%',
- width: !welcome ? undefined : '100%'
+ justifyContent: !welcome ? undefined : "center",
+ height: !welcome ? undefined : "100%",
+ width: !welcome ? undefined : "100%"
}}
>
{step === 0 ? (
<>
{
color={colors.border}
size={100}
style={{
- position: 'absolute',
+ position: "absolute",
right: 0,
top: 6
}}
@@ -93,14 +93,14 @@ const AppLock = ({ navigation, route }) => {
Protect your notes
@@ -112,53 +112,60 @@ const AppLock = ({ navigation, route }) => {
- {modes.map(item => (
+ {modes.map((item) => (
{
if (
!(await BiometicService.isBiometryAvailable()) &&
!useUserStore.getState().user
) {
ToastEvent.show({
- heading: 'Biometrics not enrolled',
- type: 'error',
+ heading: "Biometrics not enrolled",
+ type: "error",
message:
- 'To use app lock, you must enable biometrics such as Fingerprint lock or Face ID on your phone or create an account.'
+ "To use app lock, you must enable biometrics such as Fingerprint lock or Face ID on your phone or create an account."
});
return;
}
SettingsService.set({ appLockMode: item.value });
}}
customStyle={{
- justifyContent: 'flex-start',
- alignItems: 'flex-start',
+ justifyContent: "flex-start",
+ alignItems: "flex-start",
paddingHorizontal: 12,
paddingVertical: 12,
marginTop: 0,
marginBottom: 12,
borderWidth: 1,
- borderColor: appLockMode === item.value ? item.activeColor : colors.nav
+ borderColor:
+ appLockMode === item.value ? item.activeColor : colors.nav
}}
style={{
marginBottom: 10
}}
>
{item.title}
{item.desc}
@@ -176,16 +183,16 @@ const AppLock = ({ navigation, route }) => {
...LayoutAnimation.Presets.linear,
delete: {
duration: 50,
- property: 'opacity',
- type: 'linear'
+ property: "opacity",
+ type: "linear"
}
});
- umami.pageView('/privacymode', '/welcome');
+ umami.pageView("/privacymode", "/welcome");
setStep(1);
}}
style={{
paddingHorizontal: 24,
- alignSelf: 'center',
+ alignSelf: "center",
borderRadius: 100,
...getElevation(5),
marginTop: 30
@@ -203,7 +210,7 @@ const AppLock = ({ navigation, route }) => {
{welcome ? (
{
duration={3000}
>
@@ -222,7 +229,7 @@ const AppLock = ({ navigation, route }) => {
);
};
-AppLock.present = async isWelcome => {
+AppLock.present = async (isWelcome) => {
presentSheet({
component: ,
disableClosing: isWelcome
diff --git a/apps/mobile/app/screens/settings/appearance.js b/apps/mobile/app/screens/settings/appearance.js
index 982a20abc..cc152b494 100644
--- a/apps/mobile/app/screens/settings/appearance.js
+++ b/apps/mobile/app/screens/settings/appearance.js
@@ -1,32 +1,36 @@
-import React, { useRef, useState } from 'react';
-import { View } from 'react-native';
-import { ScrollView } from 'react-native-gesture-handler';
-import Menu, { MenuItem } from 'react-native-reanimated-material-menu';
-import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { PressableButton } from '../../components/ui/pressable';
-import Paragraph from '../../components/ui/typography/paragraph';
-import { DDS } from '../../services/device-detection';
-import { ToastEvent } from '../../services/event-manager';
-import PremiumService from '../../services/premium';
-import SettingsService from '../../services/settings';
-import { useSettingStore } from '../../stores/use-setting-store';
-import { useThemeStore } from '../../stores/use-theme-store';
-import { hexToRGBA, RGB_Linear_Shade, switchAccentColor } from '../../utils/color-scheme/utils';
-import { MenuItemsList } from '../../utils/constants';
-import { pv, SIZE } from '../../utils/size';
+import React, { useRef, useState } from "react";
+import { View } from "react-native";
+import { ScrollView } from "react-native-gesture-handler";
+import Menu, { MenuItem } from "react-native-reanimated-material-menu";
+import Icon from "react-native-vector-icons/MaterialCommunityIcons";
+import { PressableButton } from "../../components/ui/pressable";
+import Paragraph from "../../components/ui/typography/paragraph";
+import { DDS } from "../../services/device-detection";
+import { ToastEvent } from "../../services/event-manager";
+import PremiumService from "../../services/premium";
+import SettingsService from "../../services/settings";
+import { useSettingStore } from "../../stores/use-setting-store";
+import { useThemeStore } from "../../stores/use-theme-store";
+import {
+ hexToRGBA,
+ RGB_Linear_Shade,
+ switchAccentColor
+} from "../../utils/color-scheme/utils";
+import { MenuItemsList } from "../../utils/constants";
+import { pv, SIZE } from "../../utils/size";
export const HomagePageSelector = () => {
- const colors = useThemeStore(state => state.colors);
- const settings = useSettingStore(state => state.settings);
+ const colors = useThemeStore((state) => state.colors);
+ const settings = useSettingStore((state) => state.settings);
const menuRef = useRef();
const [width, setWidth] = useState(0);
return (
{
+ onLayout={(event) => {
setWidth(event.nativeEvent.layout.width);
}}
style={{
- width: '100%'
+ width: "100%"
}}
>