Compare commits

...

7 Commits

Author SHA1 Message Date
ammarahm-ed
7f69c5b268 mobile: reset badge count when entering from bg to fg 2023-01-18 10:06:28 +05:00
ammarahm-ed
215a692139 misc: fix changelog 2023-01-17 18:39:47 +05:00
Abdullah Atta
f1b986cef9 desktop: show app name on notifications in windows 2023-01-17 17:39:05 +05:00
ammarahm-ed
da0f86c006 mobile: release 2.4.1 2023-01-17 17:23:53 +05:00
ammarahm-ed
0a4e84b376 mobile: add background fetch ios 2023-01-17 17:12:08 +05:00
ammarahm-ed
f1f8a35ea5 mobile: add background sync 2023-01-17 17:12:08 +05:00
Ammar Ahmed
1ffb6b3c57 mobile: fix incorrect note loaded when (#1704)
note is very large
2023-01-17 17:08:59 +05:00
26 changed files with 329 additions and 100 deletions

View File

@@ -25,10 +25,7 @@ import { enabled } from "react-native-privacy-snapshot";
import { DatabaseLogger, db, loadDatabase } from "../../common/database";
import { useAppState } from "../../hooks/use-app-state";
import BiometricService from "../../services/biometrics";
import {
eSendEvent,
presentSheet
} from "../../services/event-manager";
import { eSendEvent, presentSheet } from "../../services/event-manager";
import { setRateAppMessage } from "../../services/message";
import PremiumService from "../../services/premium";
import SettingsService from "../../services/settings";
@@ -55,6 +52,8 @@ import Paragraph from "../ui/typography/paragraph";
import { Walkthrough } from "../walkthroughs";
import Config from "react-native-config";
import { getGithubVersion } from "../../utils/github-version";
import notifee from "@notifee/react-native";
const Launcher = React.memo(
function Launcher() {
@@ -133,6 +132,7 @@ const Launcher = React.memo(
eSendEvent("session_expired");
return;
}
notifee.setBadgeCount(0);
await useMessageStore.getState().setAnnouncement();
if (NewFeature.present()) return;
if (await checkAppUpdateAvailable()) return;

View File

@@ -19,25 +19,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { FeatureType } from "./components/sheets/new-feature";
export const features: FeatureType[] = [
{
title: "Cross platform Reminders 🔔",
body: "Finally reminders are here. You can set reminders on notes or independently. Go to Side Menu > Reminders to set your first reminder!"
},
{
title: "Multi-factor auth by default",
body: "Multi-factor auth is enabled by default for all users to improve login security."
},
{
title: "Change account email",
body: "Now you can go to Settings > Account Settings to change your email."
},
{
title: "Sync settings",
body: "Added options to disable sync, auto-sync & real-time sync from settings."
},
{
title: "Improved PDF exports styling",
body: "Tables, checklists, codeblocks, quotes are now properly formatted in PDF exports."
}
];
export const features: FeatureType[] = [];

View File

@@ -69,6 +69,7 @@ import { clearAppState } from "../screens/editor/tiptap/utils";
import { tabBarRef } from "../utils/global-refs";
import BackupService from "../services/backup";
import { sleep } from "../utils/time";
import notifee from "@notifee/react-native";
const SodiumEventEmitter = new NativeEventEmitter(NativeModules.Sodium);
export const useAppEvents = () => {
@@ -444,6 +445,7 @@ export const useAppEvents = () => {
const onAppStateChanged = useCallback(
async (state) => {
if (state === "active") {
notifee.setBadgeCount(0);
updateStatusBarColor();
if (
SettingsService.get().appLockMode !== "background" &&

View File

@@ -28,13 +28,14 @@ import { Button } from "../../components/ui/button";
import { IconButton } from "../../components/ui/icon-button";
import Paragraph from "../../components/ui/typography/paragraph";
import useGlobalSafeAreaInsets from "../../hooks/use-global-safe-area-insets";
import { DDS } from "../../services/device-detection";
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent
} from "../../services/event-manager";
import { useThemeStore } from "../../stores/use-theme-store";
import { eClearEditor, eOnLoadNote } from "../../utils/events";
import { eClearEditor } from "../../utils/events";
import { SIZE } from "../../utils/size";
import { editorState } from "./tiptap/utils";
const EditorOverlay = ({ editorId = "", editor }) => {
@@ -64,13 +65,8 @@ const EditorOverlay = ({ editorId = "", editor }) => {
opacity.value = 1;
translateValue.value = 0;
timers.current.error = setTimeout(() => {
if (_loading) {
let note = _loading;
note.forced = true;
eSendEvent(eOnLoadNote + editorId, note);
}
setError(true);
}, 4000);
}, 15 * 1000);
} else {
clearTimers();
setTimeout(() => {
@@ -85,7 +81,7 @@ const EditorOverlay = ({ editorId = "", editor }) => {
}, 100);
}
},
[editorId, opacity, translateValue]
[opacity, translateValue]
);
useEffect(() => {
@@ -144,15 +140,19 @@ const EditorOverlay = ({ editorId = "", editor }) => {
paddingRight: 12
}}
>
<IconButton
onPress={() => {
eSendEvent(eClearEditor);
opacity.value = 0;
translateValue.value = 6000;
}}
name="arrow-left"
color={colors.pri}
/>
{DDS.isTablet() ? (
<View />
) : (
<IconButton
onPress={() => {
eSendEvent(eClearEditor);
opacity.value = 0;
translateValue.value = 6000;
}}
name="arrow-left"
color={colors.pri}
/>
)}
<View
style={{

View File

@@ -112,7 +112,7 @@ export const useEditor = (
(show: boolean, data = { type: "new" }) => {
eSendEvent(
"loadingNote" + editorId,
show ? currentNote.current || data : false
show ? data || currentNote.current : false
);
},
[editorId]

View File

@@ -0,0 +1,121 @@
/*
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 BackgroundFetch from "react-native-background-fetch";
import { DatabaseLogger, db } from "../common/database";
import { AppState, AppRegistry } from "react-native";
import Notifications from "./notifications";
import SettingsService from "./settings";
let backgroundFetchStarted = false;
async function start() {
if (backgroundFetchStarted) return;
backgroundFetchStarted = true;
// BackgroundFetch event handler.
const onEvent = async (taskId: string) => {
console.log("[BackgroundFetch] task: ", taskId, AppState.currentState);
// Do your background work...
await onBackgroundSyncStarted();
// IMPORTANT: You must signal to the OS that your task is complete.
BackgroundFetch.finish(taskId);
};
// Timeout callback is executed when your Task has exceeded its allowed running-time.
// You must stop what you're doing immediately BackgroundFetch.finish(taskId)
const onTimeout = async (taskId: string) => {
console.warn("[BackgroundFetch] TIMEOUT: ", taskId);
BackgroundFetch.finish(taskId);
};
// Initialize BackgroundFetch only once when component mounts.
const status = await BackgroundFetch.configure(
{
minimumFetchInterval: 15,
enableHeadless: true,
startOnBoot: true,
stopOnTerminate: false,
requiredNetworkType: BackgroundFetch.NETWORK_TYPE_ANY
},
onEvent,
onTimeout
);
DatabaseLogger.info(`[BackgroundFetch] configure status: ${status}`);
console.log(`[BackgroundFetch] configure status: ${status}`);
}
const task = async (event: { taskId: string; timeout: boolean }) => {
// Get task id from event {}:
const taskId = event.taskId;
const isTimeout = event.timeout; // <-- true when your background-time has expired.
if (isTimeout) {
console.log("[BackgroundFetch] Headless TIMEOUT:", taskId);
BackgroundFetch.finish(taskId);
return;
}
console.log(
"[BackgroundFetch HeadlessTask] start: ",
taskId,
AppState.currentState
);
await onBackgroundSyncStarted();
BackgroundFetch.finish(taskId);
};
BackgroundFetch.registerHeadlessTask(task);
async function onBackgroundSyncStarted() {
try {
console.log("Background Sync", "start");
await db.init();
const user = await db.user?.getUser();
if (user) {
await db.sync(true, false);
}
await Notifications.setupReminders();
console.log("Background Sync", "end");
} catch (e) {
DatabaseLogger.error(e as Error);
console.log("Background Sync Error", (e as Error).message);
}
}
const onBoot = async () => {
try {
console.log("BOOT TASK STARTED");
await db.init();
await Notifications.setupReminders();
SettingsService.init();
if (SettingsService.get().notifNotes) {
Notifications.pinQuickNote(false);
}
console.log("BOOT TASK COMPLETE");
} catch (e) {
console.log(e);
}
};
AppRegistry.registerHeadlessTask(
"com.streetwriters.notesnook.BOOT_TASK",
() => {
return onBoot;
}
);
export const BackgroundSync = {
start
};

View File

@@ -97,6 +97,7 @@ const onEvent = async ({ type, detail }: Event) => {
return;
}
if (type === EventType.PRESS) {
notifee.decrementBadgeCount();
if (notification?.data?.type === "quickNote") return;
editorState().movedAway = false;
MMKV.removeItem("appState");
@@ -125,8 +126,11 @@ const onEvent = async ({ type, detail }: Event) => {
}
if (type === EventType.ACTION_PRESS) {
notifee.decrementBadgeCount();
switch (pressAction?.id) {
case "REMINDER_SNOOZE": {
await db.init();
await db.notes?.init();
const reminder = db.reminders?.reminder(
notification?.id?.split("_")[0]
);
@@ -145,6 +149,8 @@ const onEvent = async ({ type, detail }: Event) => {
break;
}
case "REMINDER_DISABLE": {
await db.init();
await db.notes?.init();
const reminder = db.reminders?.reminder(
notification?.id?.split("_")[0]
);
@@ -160,6 +166,8 @@ const onEvent = async ({ type, detail }: Event) => {
break;
}
case "UNPIN": {
await db.init();
await db.notes?.init();
remove(notification?.id as string);
const reminder = db.reminders?.reminder(
notification?.id?.split("_")[0]
@@ -254,21 +262,25 @@ async function scheduleNotification(
try {
const { title, description, priority } = reminder;
await clearAllPendingTriggersForId(reminder.id);
await remove(reminder.id);
if (reminder.disabled) return;
if (reminder.disabled) {
remove(reminder.id);
return;
}
const triggers = await getTriggers(reminder);
console.log(triggers);
if (!triggers && reminder.mode === "permanent") {
displayNotification({
id: reminder.id,
title: title,
message: description || "",
ongoing: true,
subtitle: description || "",
actions: ["UNPIN"]
});
if (reminder.mode === "permanent") {
const notifications = await get();
const pinned = notifications.findIndex((i) => i.id === reminder.id) > -1;
if (!pinned) {
displayNotification({
id: reminder.id,
title: title,
message: description || "",
ongoing: true,
subtitle: description || "",
actions: ["UNPIN"]
});
}
return;
}
await setupIOSCategories();
@@ -320,6 +332,7 @@ async function scheduleNotification(
id: "default",
mainComponent: "notesnook"
},
badgeCount: 1,
actions: androidActions,
sound: notificationSound?.url,
style: !description
@@ -332,6 +345,7 @@ async function scheduleNotification(
ios: {
interruptionLevel: "active",
criticalVolume: 1.0,
badgeCount: 1,
critical:
reminder.priority === "silent" || reminder.priority === "urgent"
? false
@@ -370,7 +384,8 @@ async function getChannelId(id: "silent" | "vibrate" | "urgent" | "default") {
case "default":
return await notifee.createChannel({
id: "com.streetwriters.notesnook",
name: "Default"
name: "Default",
vibration: false
});
case "silent":
return await notifee.createChannel({
@@ -419,6 +434,7 @@ async function displayNotification({
id?: string;
}) {
if (!(await checkAndRequestPermissions())) return;
try {
await notifee.displayNotification({
id: id,
@@ -430,6 +446,7 @@ async function displayNotification({
},
android: {
ongoing: ongoing,
smallIcon: "ic_stat_name",
localOnly: true,
channelId: await getChannelId("default"),
autoCancel: false,
@@ -733,6 +750,9 @@ async function setupReminders(checkNeedsScheduling = false) {
const triggers = await notifee.getTriggerNotifications();
for (const reminder of reminders) {
if (reminder.mode === "permanent") {
await scheduleNotification(reminder);
}
const pending = triggers.filter((t) =>
t.notification.id?.startsWith(reminder.id)
);

View File

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

View File

@@ -54,4 +54,7 @@
# Wix
-keep class org.apache.commons.lang3.** { *; }
-keep class org.apache.commons.io.** { *; }
-keep class org.apache.commons.io.** { *; }
# Background fetch
-keep class com.transistorsoft.rnbackgroundfetch.HeadlessTask { *; }

View File

@@ -130,6 +130,8 @@
android:stopWithTask="false" />
<service android:name="com.asterinet.react.bgactions.RNBackgroundActionsTask" />
<service android:name="com.streetwriters.notesnook.BootTaskService" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
@@ -150,22 +152,13 @@
android:resource="@xml/file_viewer_provider_paths" />
</provider>
<!-- Change the value to true to enable pop-up for in foreground on receiving remote notifications (for prevent duplicating while showing local notifications set this to false) -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground"
android:value="false"/>
<!-- Change the resource name to your App's accent color - or any other color you want -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
android:resource="@android:color/white"/> <!-- or @android:color/{name} to use a standard color -->
<receiver android:exported="true" android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
<receiver android:exported="true" android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
<receiver android:exported="true" android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
<receiver android:exported="true" android:name=".BootRecieverService" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
</application>

View File

@@ -0,0 +1,48 @@
package com.streetwriters.notesnook;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.app.ActivityManager;
import com.facebook.react.HeadlessJsTaskService;
import java.util.List;
public class BootRecieverService extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (!isAppOnForeground((context))) {
/**
We will start our service and send extra info about
network connections
**/
Intent serviceIntent = new Intent(context, BootTaskService.class);
context.startService(serviceIntent);
HeadlessJsTaskService.acquireWakeLockNow(context);
}
}
private boolean isAppOnForeground(Context context) {
/**
We need to check if app is in foreground otherwise the app will crash.
http://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not
**/
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses =
activityManager.getRunningAppProcesses();
if (appProcesses == null) {
return false;
}
final String packageName = context.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance ==
ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
appProcess.processName.equals(packageName)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,20 @@
package com.streetwriters.notesnook;
import android.content.Intent;
import com.facebook.react.HeadlessJsTaskService;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
import javax.annotation.Nullable;
public class BootTaskService extends HeadlessJsTaskService {
@Override
protected @Nullable HeadlessJsTaskConfig getTaskConfig(Intent intent) {
return new HeadlessJsTaskConfig(
"com.streetwriters.notesnook.BOOT_TASK",
Arguments.createMap(),
30000, // timeout for the task
false // optional: defines whether or not the task is allowed in foreground. Default is false
);
}
}

View File

@@ -69,5 +69,8 @@ allprojects {
maven { url 'https://www.jitpack.io' }
maven {
url("${project(':react-native-background-fetch').projectDir}/libs")
}
}
}

View File

@@ -1,8 +1,6 @@
- Cross platform Reminders 🔔
- Multi-factor auth is enabled by default for all users to improve login security
- Now you can change account email from Settings -> Account Settings -> Change email
- Added options to disable sync, auto-sync & real-time sync from settings.
- Improved PDF exports styling
- Many bug fixes and improvements
- Added background sync support
- Fix new features sheet showing on every launch
- Fix permanent reminders removed on rebooting device
- Fixed unable to unpin/disable reminders from notifications
Thank you for using Notesnook!

View File

@@ -8,6 +8,8 @@ import Config from 'react-native-config';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import appJson from './app.json';
import Notifications from '../app/services/notifications';
import {BackgroundSync} from '../app/services/background-sync';
const appName = appJson.name;
if (Config.isTesting) {
Date.prototype.toLocaleString = () => 'XX-XX-XX';
@@ -20,6 +22,7 @@ if (__DEV__) {
LogBox.ignoreAllLogs();
}
let NotesnookShare;
BackgroundSync.start();
Notifications.init();
let QuickNoteIOS;

View File

@@ -29,6 +29,7 @@
65AA857E25E6DDEC00772A01 /* NotesWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65AA857D25E6DDEC00772A01 /* NotesWidget.swift */; };
65AA858025E6DDEE00772A01 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 65AA857F25E6DDEE00772A01 /* Assets.xcassets */; };
65AA858425E6DDEE00772A01 /* NotesWidgetExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 65AA857725E6DDEC00772A01 /* NotesWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
65B450AD2976AF0C00EA090B /* RNBackgroundFetch+AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 65B450AC2976AF0B00EA090B /* RNBackgroundFetch+AppDelegate.m */; };
65B5014425A672B200E2D264 /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 65B5014325A672B200E2D264 /* ShareViewController.m */; };
65B5014725A672B200E2D264 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65B5014525A672B200E2D264 /* MainInterface.storyboard */; };
65B5014B25A672B200E2D264 /* Make Note.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 65B5014025A672B200E2D264 /* Make Note.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
@@ -122,6 +123,7 @@
65AA857D25E6DDEC00772A01 /* NotesWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesWidget.swift; sourceTree = "<group>"; };
65AA857F25E6DDEE00772A01 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
65AA858125E6DDEE00772A01 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
65B450AC2976AF0B00EA090B /* RNBackgroundFetch+AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "RNBackgroundFetch+AppDelegate.m"; path = "../../node_modules/react-native-background-fetch/ios/RNBackgroundFetch/RNBackgroundFetch+AppDelegate.m"; sourceTree = "<group>"; };
65B5014025A672B200E2D264 /* Make Note.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Make Note.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
65B5014325A672B200E2D264 /* ShareViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShareViewController.m; sourceTree = "<group>"; };
65B5014625A672B200E2D264 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
@@ -221,6 +223,7 @@
13B07FAE1A68108700A75B9A /* Notesnook */ = {
isa = PBXGroup;
children = (
65B450AC2976AF0B00EA090B /* RNBackgroundFetch+AppDelegate.m */,
6593E4A2281C345400492C50 /* AppDelegate.mm */,
6529A13D279BC4C70048D4A8 /* BootSplash.storyboard */,
659BE46625E11A5100E05671 /* notesnook-text.png */,
@@ -941,6 +944,7 @@
65E0340B257B9FF100793428 /* File.swift in Sources */,
6593E4A3281C345400492C50 /* AppDelegate.mm in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
65B450AD2976AF0C00EA090B /* RNBackgroundFetch+AppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1083,7 +1087,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2023;
CURRENT_PROJECT_VERSION = 2024;
DEVELOPMENT_TEAM = 53CWBG3QUC;
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1157,7 +1161,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.4.0;
MARKETING_VERSION = 2.4.1;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -1187,7 +1191,7 @@
CODE_SIGN_ENTITLEMENTS = Notesnook/Notesnook.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 2023;
CURRENT_PROJECT_VERSION = 2024;
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
@@ -1260,7 +1264,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.4.0;
MARKETING_VERSION = 2.4.1;
ONLY_ACTIVE_ARCH = NO;
OTHER_LDFLAGS = (
"$(inherited)",
@@ -1418,7 +1422,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2023;
CURRENT_PROJECT_VERSION = 2024;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1430,7 +1434,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.4.0;
MARKETING_VERSION = 2.4.1;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
@@ -1460,7 +1464,7 @@
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2023;
CURRENT_PROJECT_VERSION = 2024;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1472,7 +1476,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.4.0;
MARKETING_VERSION = 2.4.1;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.notewidget;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1501,7 +1505,7 @@
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2023;
CURRENT_PROJECT_VERSION = 2024;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1575,7 +1579,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.4.0;
MARKETING_VERSION = 2.4.1;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
@@ -1605,7 +1609,7 @@
CODE_SIGN_IDENTITY = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2023;
CURRENT_PROJECT_VERSION = 2024;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 53CWBG3QUC;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
@@ -1679,7 +1683,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.4.0;
MARKETING_VERSION = 2.4.1;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
PRODUCT_NAME = "$(TARGET_NAME)";

View File

@@ -7,6 +7,7 @@
#import <React/RCTAppSetupUtils.h>
#import <React/RCTLinkingManager.h>
#import "RNShortcuts.h"
#import <TSBackgroundFetch/TSBackgroundFetch.h>
#if RCT_NEW_ARCH_ENABLED
#import <React/CoreModulesPlugins.h>
@@ -62,6 +63,7 @@ RCTBridge *bridge;
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
[[TSBackgroundFetch sharedInstance] didFinishLaunching];
return YES;
}

View File

@@ -4,6 +4,7 @@
<dict>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.transistorsoft.fetch</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array>
<key>CFBundleDevelopmentRegion</key>

View File

@@ -345,6 +345,8 @@ PODS:
- React-Core
- rn-fetch-blob (0.12.0):
- React-Core
- RNBackgroundFetch (4.1.7):
- React-Core
- RNBootSplash (4.3.2):
- React-Core
- RNCCheckbox (0.5.12):
@@ -481,6 +483,7 @@ DEPENDENCIES:
- ReactCommon/turbomodule/core (from `../../node_modules/react-native/ReactCommon`)
- rn-extensions-share (from `../../node_modules/rn-extensions-share`)
- rn-fetch-blob (from `../../node_modules/rn-fetch-blob`)
- RNBackgroundFetch (from `../../node_modules/react-native-background-fetch`)
- RNBootSplash (from `../../node_modules/react-native-bootsplash`)
- "RNCCheckbox (from `../../node_modules/@react-native-community/checkbox`)"
- "RNCClipboard (from `../../node_modules/@react-native-clipboard/clipboard`)"
@@ -622,6 +625,8 @@ EXTERNAL SOURCES:
:path: "../../node_modules/rn-extensions-share"
rn-fetch-blob:
:path: "../../node_modules/rn-fetch-blob"
RNBackgroundFetch:
:path: "../../node_modules/react-native-background-fetch"
RNBootSplash:
:path: "../../node_modules/react-native-bootsplash"
RNCCheckbox:
@@ -736,6 +741,7 @@ SPEC CHECKSUMS:
ReactCommon: 1e783348b9aa73ae68236271df972ba898560a95
rn-extensions-share: 3f0ecce20dfbca1f0358deb4ebfb9ee121a6d92a
rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba
RNBackgroundFetch: 13fbe7b23d4a082eac8caa7b08c5bcbeabd92f79
RNBootSplash: 5f346163977573d6b2aeba1b25df9d2245c0d73c
RNCCheckbox: ed1b4ca295475b41e7251ebae046360a703b6eb5
RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd

View File

@@ -56,7 +56,8 @@
"react-native-modal-datetime-picker":"14.0.0",
"@react-native-community/datetimepicker":"6.6.0",
"react-native-date-picker": "4.2.6",
"react-native-notification-sounds": "0.5.5"
"react-native-notification-sounds": "0.5.5",
"react-native-background-fetch": "4.1.7"
},
"devDependencies": {
"@babel/core": "^7.12.9",

View File

@@ -1,8 +1,6 @@
- Cross platform Reminders 🔔
- Multi-factor auth is enabled by default for all users to improve login security
- Now you can change account email from Settings -> Account Settings -> Change email
- Added options to disable sync, auto-sync & real-time sync from settings.
- Improved PDF exports styling
- Many bug fixes and improvements
- Added background sync support
- Fix new features sheet showing on every launch
- Fix permanent reminders removed on rebooting device
- Fixed unable to unpin/disable reminders from notifications
Thank you for using Notesnook!

View File

@@ -1,12 +1,12 @@
{
"name": "@notesnook/mobile",
"version": "2.3.0",
"version": "2.4.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@notesnook/mobile",
"version": "2.3.0",
"version": "2.4.0",
"license": "GPL-3.0-or-later",
"workspaces": [
"native/",
@@ -78,6 +78,7 @@
"react": "18.0.0",
"react-native": "0.69.7",
"react-native-background-actions": "^2.6.6",
"react-native-background-fetch": "4.1.7",
"react-native-begin-background-task": "https://github.com/blockfirm/react-native-begin-background-task.git",
"react-native-bootsplash": "^4.1.4",
"react-native-config": "^1.4.6",
@@ -17976,6 +17977,11 @@
"react-native": ">=0.47.0"
}
},
"node_modules/react-native-background-fetch": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/react-native-background-fetch/-/react-native-background-fetch-4.1.7.tgz",
"integrity": "sha512-dFY/AOZbEH+ldwZvq/UhhWI5+dyBYL1Xo5wqy6u5DLH+ef8jLIrwKQRmfLAWiP5BtZe6ktA55HM19X39qHoKEQ=="
},
"node_modules/react-native-begin-background-task": {
"version": "0.1.0",
"resolved": "git+ssh://git@github.com/blockfirm/react-native-begin-background-task.git#c2aa793249db6cc6298a812905f955a99b864e78",
@@ -24359,6 +24365,7 @@
"react-native": "0.69.7",
"react-native-actions-shortcuts": "^1.0.1",
"react-native-background-actions": "^2.6.6",
"react-native-background-fetch": "4.1.7",
"react-native-begin-background-task": "https://github.com/blockfirm/react-native-begin-background-task.git",
"react-native-bootsplash": "^4.1.4",
"react-native-bundle-visualizer": "^3.1.1",
@@ -34852,6 +34859,11 @@
"eventemitter3": "^4.0.7"
}
},
"react-native-background-fetch": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/react-native-background-fetch/-/react-native-background-fetch-4.1.7.tgz",
"integrity": "sha512-dFY/AOZbEH+ldwZvq/UhhWI5+dyBYL1Xo5wqy6u5DLH+ef8jLIrwKQRmfLAWiP5BtZe6ktA55HM19X39qHoKEQ=="
},
"react-native-begin-background-task": {
"version": "git+ssh://git@github.com/blockfirm/react-native-begin-background-task.git#c2aa793249db6cc6298a812905f955a99b864e78",
"from": "react-native-begin-background-task@https://github.com/blockfirm/react-native-begin-background-task.git"

View File

@@ -1,6 +1,6 @@
{
"name": "@notesnook/mobile",
"version": "2.4.0",
"version": "2.4.1",
"private": true,
"license": "GPL-3.0-or-later",
"workspaces": [

View File

@@ -45,6 +45,10 @@ if (!MAC_APP_STORE && !app.requestSingleInstanceLock()) {
app.exit();
}
if (process.platform === "win32") {
app.setAppUserModelId(app.name);
}
/**
* @type {BrowserWindow}
*/

View File

@@ -2,7 +2,12 @@
- Multi-factor auth is enabled by default for all users to improve login security
- Now you can change account email from Settings -> Account Settings -> Change email
- Added options to disable sync, auto-sync & real-time sync from settings.
- Improved PDF exports styling
- Improved PDF exports styling- Added background sync support
- Fix new features sheet showing on every launch
- Fix permanent reminders removed on rebooting device
- Fixed unable to unpin/disable reminders from notifications
Thank you for using Notesnook!
- Many bug fixes and improvements
Thank you for using Notesnook!

View File

@@ -0,0 +1,6 @@
- Added background sync support
- Fix new features sheet showing on every launch
- Fix permanent reminders removed on rebooting device
- Fixed unable to unpin/disable reminders from notifications
Thank you for using Notesnook!