1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Added back support for alarms

This commit is contained in:
Laurent Cozic 2020-10-14 12:56:27 +01:00
parent 040261abfa
commit cc889182b6
40 changed files with 112 additions and 38 deletions

View File

@ -5,6 +5,12 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<!-- RN-NOTIFICATION -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- /RN-NOTIFICATION -->
<application
android:name=".MainApplication"
android:label="@string/app_name"
@ -12,6 +18,37 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme">
<!-- RN-NOTIFICATION -->
<receiver
android:name="com.emekalites.react.alarm.notification.AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="ACTION_DISMISS" />
<action android:name="ACTION_SNOOZE" />
</intent-filter>
</receiver>
<receiver
android:name="com.emekalites.react.alarm.notification.AlarmDismissReceiver"
android:enabled="true"
android:exported="true" />
<receiver
android:name="com.emekalites.react.alarm.notification.AlarmBootReceiver"
android:directBootAware="true"
android:enabled="false"
android:exported="true">
<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" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- /RN-NOTIFICATION -->
<activity
android:name=".MainActivity"
android:label="@string/app_name"

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 921 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,3 +1,4 @@
<resources>
<string name="app_name">Joplin</string>
<string name="default_notification_channel_id">net.cozic.joplin.notification</string>
</resources>

View File

@ -264,7 +264,7 @@ class ScreenHeaderComponent extends React.PureComponent {
const renderUndoButton = () => {
return renderTopButton({
iconName: 'md-undo',
iconName: 'arrow-undo-circle-sharp',
onPress: this.props.onUndoButtonPress,
visible: this.props.showUndoButton,
disabled: this.props.undoButtonDisabled,
@ -273,7 +273,7 @@ class ScreenHeaderComponent extends React.PureComponent {
const renderRedoButton = () => {
return renderTopButton({
iconName: 'md-redo',
iconName: 'arrow-redo-circle-sharp',
onPress: this.props.onRedoButtonPress,
visible: this.props.showRedoButton,
});

View File

@ -2,7 +2,7 @@ const BaseModel = require('lib/BaseModel.js');
const Note = require('lib/models/Note.js');
export interface Notification {
id: string,
id: number,
noteId: string,
date: Date,
title: string,

View File

@ -1,48 +1,67 @@
import Logger from 'lib/Logger';
import { Notification } from 'lib/models/Alarm';
const PushNotification = require('react-native-push-notification');
const ReactNativeAN = require('react-native-alarm-notification').default;
export default class AlarmServiceDriver {
private PushNotification_:any = null;
private logger_:Logger;
PushNotificationHandler_() {
if (!this.PushNotification_) {
PushNotification.configure({
// (required) Called when a remote or local notification is opened or received
onNotification: function(notification:any) {
console.info('Notification was opened: ', notification);
// process the notification
},
popInitialNotification: true,
requestPermissions: true,
});
this.PushNotification_ = PushNotification;
constructor(logger:Logger) {
this.logger_ = logger;
}
return this.PushNotification_;
}
hasPersistentNotifications() {
public hasPersistentNotifications() {
return true;
}
notificationIsSet() {
public notificationIsSet() {
throw new Error('Available only for non-persistent alarms');
}
async clearNotification(id:any) {
return this.PushNotificationHandler_().cancelLocalNotifications({ id: `${id}` });
public async clearNotification(id:number) {
const alarm = await this.alarmByJoplinNotificationId(id);
if (!alarm) return;
this.logger_.info('AlarmServiceDriver: Deleting alarm:', alarm);
await ReactNativeAN.deleteAlarm(alarm.id);
}
async scheduleNotification(notification:Notification) {
const config = {
id: `${notification.id}`,
message: notification.title,
date: notification.date,
// Returns -1 if could not be found
private alarmJoplinAlarmId(alarm:any):number {
if (!alarm.data) return -1;
const m = alarm.data.match(/joplinNotificationId==>(\d+)/)
return m ? Number(m[1]) : -1;
}
private async alarmByJoplinNotificationId(joplinNotificationId:number) {
const alarms:any[] = await ReactNativeAN.getScheduledAlarms();
for (const alarm of alarms) {
const id = this.alarmJoplinAlarmId(alarm);
if (id === joplinNotificationId) return alarm;
}
this.logger_.warn('AlarmServiceDriver: Could not find alarm that matches Joplin notification ID. It could be because it has already been triggered:', joplinNotificationId);
return null;
}
public async scheduleNotification(notification:Notification) {
const alarmNotifData = {
title: notification.title,
message: notification.body ? notification.body : '-', // Required
channel: "net.cozic.joplin.notification",
small_icon: "ic_launcher",
color: 'white',
data: { joplinNotificationId: notification.id + '' },
};
this.PushNotificationHandler_().localNotificationSchedule(config);
// ReactNativeAN expects a string as a date and it seems this utility
// function converts it to the right format.
const fireDate = ReactNativeAN.parseDate(notification.date);
const alarm = await ReactNativeAN.scheduleAlarm({ ...alarmNotifData, fire_date: fireDate });
this.logger_.info('AlarmServiceDriver: Created new alarm:', alarm);
}
}

View File

@ -1,4 +1,5 @@
// import { Notification } from 'lib/models/Alarm';
// import Logger from 'lib/Logger';
// const PushNotificationIOS = require('@react-native-community/push-notification-ios').default;
// export default class AlarmServiceDriver {
@ -6,7 +7,8 @@
// private hasPermission_:boolean = null;
// private inAppNotificationHandler_:any = null;
// constructor() {
// constructor(logger:Logger) {
// this.logger_ = logger;
// PushNotificationIOS.addEventListener('localNotification', (instance:any) => {
// if (!this.inAppNotificationHandler_) return;

View File

@ -33,11 +33,11 @@ export default class AlarmServiceDriverNode {
return false;
}
notificationIsSet(id:string) {
notificationIsSet(id:number) {
return id in this.notifications_;
}
async clearNotification(id:string) {
async clearNotification(id:number) {
if (!this.notificationIsSet(id)) return;
shim.clearTimeout(this.notifications_[id].timeoutId);
delete this.notifications_[id];

View File

@ -10770,6 +10770,11 @@
"prop-types": "^15.5.10"
}
},
"react-native-alarm-notification": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/react-native-alarm-notification/-/react-native-alarm-notification-1.7.1.tgz",
"integrity": "sha512-cvfSqCCfw48NyeFTEL5WOF/tkeWLNI7X1mVoEQ/9aY+2fuBtkCfZUoJ7vvOOHeryPbDJrlDNpRWTi3erLphZ+w=="
},
"react-native-camera": {
"version": "3.40.0",
"resolved": "https://registry.npmjs.org/react-native-camera/-/react-native-camera-3.40.0.tgz",

View File

@ -57,6 +57,7 @@
"react-async": "^10.0.0",
"react-native": "0.63.3",
"react-native-action-button": "^2.8.5",
"react-native-alarm-notification": "^1.7.1",
"react-native-camera": "^3.40.0",
"react-native-device-info": "^6.2.0",
"react-native-dialogbox": "^0.6.10",

View File

@ -8,7 +8,7 @@ const { connect, Provider } = require('react-redux');
const { BackButtonService } = require('lib/services/back-button.js');
const NavService = require('lib/services/NavService.js');
const AlarmService = require('lib/services/AlarmService.js').default;
// const AlarmServiceDriver = require('lib/services/AlarmServiceDriver').default;
const AlarmServiceDriver = require('lib/services/AlarmServiceDriver').default;
const Alarm = require('lib/models/Alarm').default;
const { createStore, applyMiddleware } = require('redux');
const reduxSharedMiddleware = require('lib/components/shared/reduxSharedMiddleware');
@ -442,7 +442,7 @@ async function initialize(dispatch) {
Resource.fsDriver_ = fsDriver;
FileApiDriverLocal.fsDriver_ = fsDriver;
// AlarmService.setDriver(new AlarmServiceDriver());
AlarmService.setDriver(new AlarmServiceDriver(mainLogger));
AlarmService.setLogger(mainLogger);
try {

View File

@ -709,8 +709,7 @@
],
"spellright.documentTypes": [
"markdown",
"latex",
"plaintext"
"latex"
]
},
}