mobile: release v3.3.6

This commit is contained in:
Ammar Ahmed
2025-10-23 21:39:20 +05:00
parent 19d90fa221
commit 8900a6b080
26 changed files with 95 additions and 123 deletions

View File

@@ -47,6 +47,11 @@ jobs:
- name: Install Detox CLI
run: npm install detox-cli --global
- name: Check for typescript errors
run: |
cd apps/mobile
npx tsc --noEmit
- name: Detox build
run: |
yarn build:android

View File

@@ -73,6 +73,12 @@ jobs:
- name: CCache Stats Before Build
run: ccache -sv
- name: Check for typescript errors
run: |
npm run tx mobile:build
cd apps/mobile
npx tsc --noEmit
- name: Build unsigned app bundle
run: yarn release:android:bundle

View File

@@ -73,6 +73,12 @@ jobs:
- name: CCache Stats Before Build
run: ccache -sv
- name: Check for typescript errors
run: |
npm run tx mobile:build
cd apps/mobile
npx tsc --noEmit
- name: Build unsigned app bundle
run: yarn release:android:bundle

View File

@@ -64,6 +64,12 @@ jobs:
bundle install
RCT_NEW_ARCH_ENABLED=0 bundle exec pod install
- name: Check for typescript errors
run: |
npm run tx mobile:build
cd apps/mobile
npx tsc --noEmit
- name: CCache Stats Before Build
run: ccache -sv

View File

@@ -94,7 +94,9 @@ export async function encryptDatabaseKeyWithPassword(appLockPassword: string) {
}
export async function restoreDatabaseKeyToKeyChain(appLockPassword: string) {
const databaseKeyCipher: Cipher = CipherStorage.getMap(DB_KEY_CIPHER);
const databaseKeyCipher: Cipher = CipherStorage.getMap(
DB_KEY_CIPHER
) as Cipher;
const databaseKey = (await decrypt(
{
password: appLockPassword
@@ -135,7 +137,9 @@ export async function clearAppLockVerificationCipher() {
export async function validateAppLockPassword(appLockPassword: string) {
try {
const appLockCipher: Cipher = CipherStorage.getMap(APPLOCK_CIPHER);
const appLockCipher: Cipher = CipherStorage.getMap(
APPLOCK_CIPHER
) as Cipher;
if (!appLockCipher) return true;
const key = await Sodium.deriveKey(appLockPassword, appLockCipher.salt);
const decrypted = await decrypt(key, appLockCipher);
@@ -159,7 +163,9 @@ export function clearDatabaseKey() {
export async function getDatabaseKey(appLockPassword?: string) {
if (DB_KEY) return DB_KEY;
if (appLockPassword) {
const databaseKeyCipher: Cipher = CipherStorage.getMap("databaseKeyCipher");
const databaseKeyCipher: Cipher = CipherStorage.getMap(
"databaseKeyCipher"
) as Cipher;
const databaseKey = await decrypt(
{
password: appLockPassword
@@ -293,7 +299,7 @@ export async function deriveCryptoKey(data: SerializedKey) {
export async function getCryptoKey() {
try {
const keyCipher: Cipher = MMKV.getMap(USER_KEY_CIPHER);
const keyCipher: Cipher = MMKV.getMap(USER_KEY_CIPHER) as Cipher;
if (!keyCipher) {
DatabaseLogger.info("User key cipher is null");
return undefined;

View File

@@ -136,6 +136,12 @@ export const Storage: IStorage = {
clear(): Promise<void> {
return DefaultStorage.clear();
},
generateCryptoKeyPair() {
throw new Error("Not implemented");
},
decryptAsymmetric() {
throw new Error("Not implemented");
},
getAllKeys(): Promise<string[]> {
return DefaultStorage.getAllKeys();
},

View File

@@ -99,7 +99,7 @@ export const useLogin = (
callback && callback(false);
} catch (e) {
callback && callback(false);
if (e.message === "invalid_grant") {
if ((e as Error).message === "invalid_grant") {
eSendEvent(eCloseSimpleDialog, "two_factor_verify");
setLoading(false);
setStep(LoginSteps.emailAuth);

View File

@@ -35,29 +35,35 @@ import SheetProvider from "../sheet-provider";
import RateAppSheet from "../sheets/rate-app";
import RecoveryKeySheet from "../sheets/recovery-key";
import Progress from "../dialogs/progress";
import { useSettingStore } from "../../stores/use-setting-store";
const DialogProvider = () => {
const { colors } = useThemeColors();
const isAppLoading = useSettingStore((state) => state.isAppLoading);
return (
<>
<AppLockPassword />
<LoadingDialog />
<Dialog context="global" />
<AuthModal colors={colors} />
<MergeConflicts />
<RecoveryKeySheet colors={colors} />
<SheetProvider />
<SheetProvider context="sync_progress" />
<ResultDialog />
<VaultDialog colors={colors} />
<RateAppSheet />
<ImagePreview />
<AnnouncementDialog />
<SessionExpired />
<PDFPreview />
<JumpToSectionDialog />
<Dialog context="global" />
<Progress />
{isAppLoading ? null : (
<>
<MergeConflicts />
<RecoveryKeySheet colors={colors} />
<ResultDialog />
<VaultDialog colors={colors} />
<RateAppSheet />
<ImagePreview />
<AnnouncementDialog />
<SessionExpired />
<PDFPreview />
<JumpToSectionDialog />
</>
)}
</>
);
};

View File

@@ -41,7 +41,7 @@ export const openNotebook = (item: Notebook | BaseTrashItem<Notebook>) => {
positiveText: strings.restore(),
negativeText: strings.delete(),
positivePress: async () => {
if ((await db.trash.restore(item.id)) === false) return;
await db.trash.restore(item.id);
Navigation.queueRoutesForUpdate();
useSelectionStore.getState().setSelectionMode(undefined);
ToastManager.show({

View File

@@ -44,6 +44,7 @@ import Config from "react-native-config";
import * as RNIap from "react-native-iap";
import { SafeAreaView } from "react-native-safe-area-context";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
//@ts-ignore
import ToggleSwitch from "toggle-switch-react-native";
import {
ANDROID_POLICE_SVG,

View File

@@ -29,6 +29,7 @@ import {
View
} from "react-native";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
//@ts-ignore
import ToggleSwitch from "toggle-switch-react-native";
import { db } from "../../../common/database";
import { requestInAppReview } from "../../../services/app-review";

View File

@@ -1,67 +0,0 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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 { Product } from "@notesnook/core";
const skuInfos: { [name: string]: Product | undefined } = {};
export const usePricing = (period: "monthly" | "yearly") => {
const [current, setCurrent] = useState<{
period: string;
info?: Product;
product?: Subscription;
}>();
const getDefaultSku = (period: "monthly" | "yearly") => {
return period === "monthly"
? "com.streetwriters.notesnook.sub.mo"
: "com.streetwriters.notesnook.sub.yr";
};
useEffect(() => {
(async () => {
const skuInfo =
skuInfos[period] ||
(await db.pricing?.sku(
Platform.OS === "android" ? "android" : "ios",
period
));
skuInfos[period] = skuInfo;
const products = (await (
await PremiumService.loadProductsAndSubs()
).subs) as Subscription[];
let product = products.find((p) => p.productId === skuInfo?.sku);
if (!product)
product = products.find((p) => p.productId === getDefaultSku(period));
setCurrent({
info: skuInfo,
period,
product
});
})();
}, [period]);
return current;
};

View File

@@ -185,7 +185,7 @@ export default function DebugLogs() {
paragraph: strings.clearLogsConfirmation(currentLog.key),
negativeText: strings.cancel(),
positiveText: strings.clear(),
positivePress: () => {
positivePress: async () => {
const index = logs.findIndex((l) => (l.key = currentLog.key));
logManager?.delete(currentLog.key);
if (logs.length > 1) {

View File

@@ -26,18 +26,17 @@ import {
import React, { useEffect, useRef, useState } from "react";
import { ActivityIndicator, TextInput, View } from "react-native";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
//@ts-ignore
import { FeatureResult, useIsFeatureAvailable } from "@notesnook/common";
import { strings } from "@notesnook/intl";
//@ts-ignore
import ToggleSwitch from "toggle-switch-react-native";
import PaywallSheet from "../../components/sheets/paywall";
import AppIcon from "../../components/ui/AppIcon";
import { IconButton } from "../../components/ui/icon-button";
import Input from "../../components/ui/input";
import { Pressable } from "../../components/ui/pressable";
import Seperator from "../../components/ui/seperator";
import Heading from "../../components/ui/typography/heading";
import Paragraph from "../../components/ui/typography/paragraph";
import { ToastManager } from "../../services/event-manager";
import SettingsService from "../../services/settings";
import useNavigationStore from "../../stores/use-navigation-store";
import { SettingStore, useSettingStore } from "../../stores/use-setting-store";
@@ -45,7 +44,6 @@ import { AppFontSize } from "../../utils/size";
import { DefaultAppStyles } from "../../utils/styles";
import { components } from "./components";
import { RouteParams, SettingSection } from "./types";
import AppIcon from "../../components/ui/AppIcon";
const _SectionItem = ({ item }: { item: SettingSection }) => {
const { colors } = useThemeColors();

View File

@@ -32,6 +32,7 @@ import React from "react";
import { Appearance, Linking, Platform } from "react-native";
import { getVersion } from "react-native-device-info";
import * as RNIap from "react-native-iap";
//@ts-ignore
import { enabled } from "react-native-privacy-snapshot";
import ScreenGuardModule from "react-native-screenguard";
import { DatabaseLogger, db } from "../../common/database";

View File

@@ -580,7 +580,7 @@ function openSettingsDialog(context: string) {
positivePress:
Platform.OS === "ios"
? undefined
: () => {
: async () => {
resolve(true);
},
onClose: () => {

View File

@@ -124,7 +124,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled true
versionCode 3074
versionCode 3075
versionName getNpmVersion()
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'

View File

@@ -1,5 +1,3 @@
- Collapsible Headings
- Notesnook Circle
- Minor bug fixes and improvements
Thank you for using Notesnook!

View File

@@ -1091,7 +1091,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2153;
CURRENT_PROJECT_VERSION = 2154;
DEVELOPMENT_TEAM = 53CWBG3QUC;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1165,7 +1165,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 3.3.5;
MARKETING_VERSION = 3.3.6;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -1196,7 +1196,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 2153;
CURRENT_PROJECT_VERSION = 2154;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1270,7 +1270,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 3.3.5;
MARKETING_VERSION = 3.3.6;
ONLY_ACTIVE_ARCH = NO;
OTHER_LDFLAGS = (
"$(inherited)",
@@ -1429,7 +1429,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2153;
CURRENT_PROJECT_VERSION = 2154;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1441,7 +1441,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 3.3.5;
MARKETING_VERSION = 3.3.6;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
@@ -1472,7 +1472,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2153;
CURRENT_PROJECT_VERSION = 2154;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
@@ -1485,7 +1485,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 3.3.5;
MARKETING_VERSION = 3.3.6;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1515,7 +1515,7 @@
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2153;
CURRENT_PROJECT_VERSION = 2154;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1596,7 +1596,7 @@
"@executable_path/../../Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)";
MARKETING_VERSION = 3.3.5;
MARKETING_VERSION = 3.3.6;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
@@ -1627,7 +1627,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2153;
CURRENT_PROJECT_VERSION = 2154;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 53CWBG3QUC;
@@ -1709,7 +1709,7 @@
"@executable_path/../../Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift$(inherited)";
MARKETING_VERSION = 3.3.5;
MARKETING_VERSION = 3.3.6;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
PRODUCT_NAME = "$(TARGET_NAME)";

View File

@@ -72,10 +72,10 @@
"react-native-begin-background-task": "github:blockfirm/react-native-begin-background-task",
"react-native-privacy-snapshot": "github:standardnotes/react-native-privacy-snapshot",
"@ammarahmed/react-native-fingerprint-scanner": "^5.0.0",
"@ammarahmed/react-native-share-extension": "^2.9.0",
"react-native-pager-view": "^6.5.1",
"react-native-tab-view": "^4.0.2",
"react-native-orientation-locker": "^1.7.0"
"react-native-orientation-locker": "^1.7.0",
"@ammarahmed/react-native-share-extension": "^2.9.5"
},
"devDependencies": {
"@babel/core": "^7.27.1",

View File

@@ -1,12 +1,12 @@
{
"name": "@notesnook/mobile",
"version": "3.3.5",
"version": "3.3.6",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@notesnook/mobile",
"version": "3.3.5",
"version": "3.3.6",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"workspaces": [
@@ -28326,7 +28326,7 @@
"@ammarahmed/react-native-background-fetch": "^4.2.2",
"@ammarahmed/react-native-eventsource": "1.1.0",
"@ammarahmed/react-native-fingerprint-scanner": "^5.0.0",
"@ammarahmed/react-native-share-extension": "^2.9.0",
"@ammarahmed/react-native-share-extension": "^2.9.5",
"@ammarahmed/react-native-sodium": "^1.6.5",
"@bam.tech/react-native-image-resizer": "3.0.11",
"@callstack/repack": "~5.1.2",
@@ -28472,9 +28472,9 @@
}
},
"node_modules/@ammarahmed/react-native-share-extension": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/@ammarahmed/react-native-share-extension/-/react-native-share-extension-2.9.0.tgz",
"integrity": "sha512-iEkpJQFZL5/WDPh7iRCLZREANgaaAHthDsPaAYT6sI4wieQcHZMBAnfRMwBEnC0BZ0WVxbQZdzJYez+dmwpr2g==",
"version": "2.9.5",
"resolved": "https://registry.npmjs.org/@ammarahmed/react-native-share-extension/-/react-native-share-extension-2.9.5.tgz",
"integrity": "sha512-UTE8TSxkx+RFNgSJCCfD5FSdQ5IuMOsZzuuy0BVy46emRrpPw1fedJTtDbqyKrU8fwtKEIbzJWeQtjjRZlHxjQ==",
"license": "MIT",
"dependencies": {
"react-native": "^0.63.1"

View File

@@ -1,6 +1,6 @@
{
"name": "@notesnook/mobile",
"version": "3.3.5",
"version": "3.3.6",
"private": true,
"license": "GPL-3.0-or-later",
"workspaces": [
@@ -56,4 +56,4 @@
"react": "18.2.0",
"react-native": "0.77.2"
}
}
}

View File

@@ -68,11 +68,10 @@ export const useShareStore = create((set) => ({
let appendNote = MMKV.getString(StorageKeys.appendNote);
let selectedNotebooks = MMKV.getString(StorageKeys.selectedNotebooks);
let selectedTags = MMKV.getString(StorageKeys.selectedTag);
appendNote = JSON.parse(appendNote);
set({
appendNote: appendNote,
selectedNotebooks: selectedNotebooks ? JSON.parse(selectedNotebooks) : [],
selectedTag: selectedTags ? JSON.parse(selectedTags) : []
selectedTags: selectedTags ? JSON.parse(selectedTags) : []
});
},
selectedTags: [],

View File

@@ -15,10 +15,7 @@
"@notesnook/theme": ["../../packages/theme"],
"@types/react": ["./node_modules/@types/react"],
"react": ["./node_modules/react"]
},
"incremental": true,
"maxNodeModuleJsDepth": 5,
"downlevelIteration": true
}
},
"exclude": ["native", "e2e"]
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
- Minor bug fixes and improvements
Thank you for using Notesnook!