refactor(plugin): modernize plugin architecture and improve type definitions
- Update package.json with modern build tooling and dependencies - Streamline and enhance TypeScript definitions for better type safety - Reorganize plugin structure for better maintainability - Add comprehensive interface definitions for notification features - Implement proper build configuration with rollup - Update tsconfig.json for stricter type checking and ES2020 modules Breaking Changes: - Changed module structure to use ES modules - Updated interface definitions with stricter typing - Removed redundant notification options - Simplified API surface while maintaining core functionality Dependencies: - Upgrade @capacitor dependencies to v5.7.8 - Add rollup and typescript build tools - Update test framework configuration
This commit is contained in:
19
.eslintrc.json
Normal file
19
.eslintrc.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"env": {
|
||||
"node": true,
|
||||
"jest": true
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/explicit-function-return-type": "warn",
|
||||
"@typescript-eslint/no-explicit-any": "warn",
|
||||
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
|
||||
"no-console": ["warn", { "allow": ["warn", "error"] }]
|
||||
}
|
||||
}
|
||||
66
.gitignore
vendored
66
.gitignore
vendored
@@ -1,15 +1,61 @@
|
||||
dist/
|
||||
# Dependencies
|
||||
node_modules/
|
||||
.DS_Store
|
||||
Pods/
|
||||
*.iml
|
||||
npm-debug.log
|
||||
yarn-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# Build output
|
||||
dist/
|
||||
build/
|
||||
*.tsbuildinfo
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
build/
|
||||
*.tgz
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Ignore Gradle project-specific cache directory
|
||||
.gradle
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Ignore Gradle build output directory
|
||||
build
|
||||
# Android
|
||||
android/app/build/
|
||||
android/build/
|
||||
android/gradle/
|
||||
android/gradlew
|
||||
android/gradlew.bat
|
||||
android/.gradle/
|
||||
android/local.properties
|
||||
android/.idea/
|
||||
android/*.iml
|
||||
|
||||
# iOS
|
||||
ios/Pods/
|
||||
ios/build/
|
||||
ios/Podfile.lock
|
||||
ios/.xcode.env.local
|
||||
ios/DerivedData/
|
||||
ios/*.xcworkspace/
|
||||
ios/*.xcodeproj/*
|
||||
!ios/*.xcodeproj/project.pbxproj
|
||||
!ios/*.xcodeproj/xcshareddata/
|
||||
!ios/*.xcworkspace/contents.xcworkspacedata
|
||||
|
||||
# Testing
|
||||
coverage/
|
||||
.nyc_output/
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
|
||||
# Environment
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
.cache/
|
||||
|
||||
BIN
.gradle/8.13/checksums/checksums.lock
Normal file
BIN
.gradle/8.13/checksums/checksums.lock
Normal file
Binary file not shown.
BIN
.gradle/8.13/checksums/md5-checksums.bin
Normal file
BIN
.gradle/8.13/checksums/md5-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/8.13/checksums/sha1-checksums.bin
Normal file
BIN
.gradle/8.13/checksums/sha1-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/8.13/executionHistory/executionHistory.bin
Normal file
BIN
.gradle/8.13/executionHistory/executionHistory.bin
Normal file
Binary file not shown.
BIN
.gradle/8.13/executionHistory/executionHistory.lock
Normal file
BIN
.gradle/8.13/executionHistory/executionHistory.lock
Normal file
Binary file not shown.
BIN
.gradle/8.13/fileChanges/last-build.bin
Normal file
BIN
.gradle/8.13/fileChanges/last-build.bin
Normal file
Binary file not shown.
BIN
.gradle/8.13/fileHashes/fileHashes.bin
Normal file
BIN
.gradle/8.13/fileHashes/fileHashes.bin
Normal file
Binary file not shown.
BIN
.gradle/8.13/fileHashes/fileHashes.lock
Normal file
BIN
.gradle/8.13/fileHashes/fileHashes.lock
Normal file
Binary file not shown.
BIN
.gradle/8.13/fileHashes/resourceHashesCache.bin
Normal file
BIN
.gradle/8.13/fileHashes/resourceHashesCache.bin
Normal file
Binary file not shown.
0
.gradle/8.13/gc.properties
Normal file
0
.gradle/8.13/gc.properties
Normal file
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
Binary file not shown.
2
.gradle/buildOutputCleanup/cache.properties
Normal file
2
.gradle/buildOutputCleanup/cache.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
#Fri Mar 28 09:01:29 UTC 2025
|
||||
gradle.version=8.13
|
||||
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
_{<7B><>=lLg͒<67><CD92><EFBFBD>w<EFBFBD>xD=<3D><1E>H<1A><><EFBFBD><EFBFBD>z<>QbK6<>E<EFBFBD>+Il/b<><62>zj<1B><><0F><>B4<42><34><EFBFBD><EFBFBD>`S<><53>8<EFBFBD>Oo}]<5D><>y<EFBFBD>~<17><>u<EFBFBD>\<5C>t<EFBFBD>ĞqT<71>DVEq<45>G<EFBFBD>5<EFBFBD>b<EFBFBD>*r<><72>D<EFBFBD> <09>L<EFBFBD><4C>-d<64><7F>C<EFBFBD><43>1<EFBFBD><31>'<1C><07>K<EFBFBD><10><>%<25>e<EFBFBD><65>A'p<><70><EFBFBD><EFBFBD>9<>]jPor<6F>z<EFBFBD>T<EFBFBD><54>b_<62>OūxٙW<D999>6-<2D><17>V<>i<EFBFBD>y<EFBFBD>?<3F>ؐAB'<27><>z'<27><><EFBFBD><EFBFBD>P:<3A>B<EFBFBD><42><02>c<1B><><EFBFBD>\Q<>*<2A>2<EFBFBD><32>[<5B><>+ pTvmo<6D><07>ٿ<0E>AJ<41><14><><EFBFBD>yG<79>ؒ<EFBFBD>P@f<>k<EFBFBD><6B><18><>`%w <0F><>Wh<>\ӻn?<3F><>D⏭<44><E28FAD><EFBFBD>ł˂<C582><CB82><EFBFBD><EFBFBD><EFBFBD>ټD<D9BC>r]<5D><>9<EFBFBD><l<>X<>7<EFBFBD>4o<><0F><><EFBFBD>q?ξ<>e-<2D><>J<><4A>?<3F><>*
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
6c6d7154-1c12-44da-bab9-788cea5132b<32>
|
||||
@@ -0,0 +1 @@
|
||||
T<EFBFBD>lX卆^)~c<><63><EFBFBD><EFBFBD><13>D
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
^<5E>ꩫ<EFBFBD>ev<>a<EFBFBD>r<EFBFBD><72><EFBFBD><EFBFBD>+
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
96e7369f-9457-47f1-8304-05bf876b89f<39>
|
||||
@@ -0,0 +1 @@
|
||||
102cc785-1d0d-4dbb-a688-2153e21cdbf<62>
|
||||
@@ -0,0 +1 @@
|
||||
-
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
5dbbc9a7-8a29-4ae7-b3f0-33b5a5e5203<30>
|
||||
@@ -0,0 +1 @@
|
||||
f93c619e-5608-44c0-ae77-793c324d124<32>
|
||||
@@ -0,0 +1 @@
|
||||
0809f6f5-185b-4807-b8df-47cb0fd7076<37>
|
||||
@@ -0,0 +1,3 @@
|
||||
M<EFBFBD>4<EFBFBD>YG<EFBFBD>4#<23><><EFBFBD><EFBFBD>
|
||||
1z<>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
<02>U2 C<17><>'<27><><EFBFBD>?<3F><>s<EFBFBD><73>9Т<39>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
6277d4cb-02d2-4a97-aa8b-c333720dfd7<64>
|
||||
BIN
.gradle/configuration-cache/configuration-cache.lock
Normal file
BIN
.gradle/configuration-cache/configuration-cache.lock
Normal file
Binary file not shown.
@@ -0,0 +1 @@
|
||||
da5353e4-2da1-4b2a-8d76-9f7a80dfac3<63>
|
||||
@@ -0,0 +1 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>6<EFBFBD>ԩ&U<><55><EFBFBD>,<2C>bj<62><0E>a\<5C><><EFBFBD>JLne<6E><65><EFBFBD>kh<06>?<3F><10><>b<EFBFBD>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
E[<5B>$<24><>qQ<><51><EFBFBD><14>>b<>Ԃ<EFBFBD>X<>^C<>RK<18><> <09><>U<EFBFBD>pY<16><>hΖ<68><CE96>p<><70><EFBFBD><EFBFBD>*<2A>R<EFBFBD>ze<0B><>@dV<>e_WKy=T$<24><>_Wf<57><66>n<><1D><>!|<7C>R<EFBFBD><52>_<> <20>ɘ7<C998><0B><><EFBFBD>2<EFBFBD>w<EFBFBD>4|<7C>\<5C><>:<3A>}<7D>H<EFBFBD>-<><7F><EFBFBD><EFBFBD>y@2Q<><51>K<EFBFBD>Ȑ<EFBFBD>B@YT<59>
|
||||
yh<EFBFBD>G<EFBFBD>l<EFBFBD><EFBFBD>s<EFBFBD>e<13>,
|
||||
p<EFBFBD><EFBFBD><EFBFBD>e<EFBFBD>.<2E>Έ<0B><><<3C><>b<EFBFBD><62>
|
||||
T<EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.@<40><>";<3B>6<EFBFBD><36><<3C><><EFBFBD><EFBFBD><EFBFBD>Hܿ<48>z M1P}<7D><><EFBFBD>9s?<3F><>ו,<2C>'tG<><47>W<EFBFBD><57>:w<><77><EFBFBD>|ɪ<08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><15><><EFBFBD><EFBFBD><EFBFBD>=e<>2<>|<7C><>74<37>]<5D>C<0B><><EFBFBD><EFBFBD>]<5D><>dT)Bh<42><68><EFBFBD>Ufa<66>⌐5<E28C90><35><EFBFBD><EFBFBD>R)r<><72>)<29><><EFBFBD>KR<4B><52>F<EFBFBD><1F><><EFBFBD>cC<63>.h(ڹ<>A<EFBFBD><41>
|
||||
@@ -0,0 +1 @@
|
||||
f64db575-a480-4fdc-82c4-6fc81d961b4<62>
|
||||
@@ -0,0 +1 @@
|
||||
<EFBFBD><EFBFBD><0B><>R<08>P<-Op2<70>0<1C>X<EFBFBD>|
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
o<><6F><EFBFBD>m<EFBFBD>c-<02><><EFBFBD><EFBFBD><EFBFBD>u1<75>G
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
0
.gradle/configuration-cache/gc.properties
Normal file
0
.gradle/configuration-cache/gc.properties
Normal file
BIN
.gradle/file-system.probe
Normal file
BIN
.gradle/file-system.probe
Normal file
Binary file not shown.
0
.gradle/vcs-1/gc.properties
Normal file
0
.gradle/vcs-1/gc.properties
Normal file
10
.prettierrc
Normal file
10
.prettierrc
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"semi": true,
|
||||
"trailingComma": "es5",
|
||||
"singleQuote": true,
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
215
README.md
215
README.md
@@ -1,143 +1,146 @@
|
||||
# Daily Notification Plugin for Capacitor
|
||||
# Daily Notification Plugin
|
||||
|
||||
A Capacitor plugin for scheduling and managing daily notifications with advanced features and robust error handling.
|
||||
A Capacitor plugin for scheduling and managing daily notifications on Android devices.
|
||||
|
||||
## Features
|
||||
|
||||
- Schedule daily notifications with custom time and content
|
||||
- Support for different priority levels
|
||||
- Timezone-aware scheduling
|
||||
- Offline support with caching
|
||||
- Comprehensive permission handling
|
||||
- Automatic retry logic
|
||||
- Detailed notification status tracking
|
||||
- Configurable settings management
|
||||
- Schedule daily notifications with precise timing
|
||||
- Handle system state changes (battery, power, etc.)
|
||||
- Support for adaptive scheduling based on device state
|
||||
- Background task management
|
||||
- Battery optimization support
|
||||
- Rich logging system
|
||||
- Comprehensive error handling
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install daily-notification-plugin
|
||||
npx cap sync
|
||||
npm install @timesafari/daily-notification-plugin
|
||||
```
|
||||
|
||||
## iOS Setup
|
||||
|
||||
No additional setup required for iOS. The plugin automatically handles all necessary configurations.
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```typescript
|
||||
import { DailyNotification } from 'daily-notification-plugin';
|
||||
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
||||
|
||||
// Initialize the plugin
|
||||
const dailyNotification = new DailyNotification();
|
||||
|
||||
// Schedule a daily notification
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/updates',
|
||||
time: '09:00',
|
||||
title: 'Daily Update',
|
||||
body: 'Your daily update is ready'
|
||||
await dailyNotification.scheduleDailyNotification({
|
||||
sound: true,
|
||||
priority: 'default',
|
||||
timezone: 'UTC'
|
||||
});
|
||||
```
|
||||
|
||||
### Advanced Features
|
||||
// Get notification status
|
||||
const status = await dailyNotification.getNotificationStatus();
|
||||
|
||||
#### Custom Priority
|
||||
|
||||
```typescript
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/updates',
|
||||
time: '09:00',
|
||||
// Update settings
|
||||
await dailyNotification.updateSettings({
|
||||
sound: false,
|
||||
priority: 'high'
|
||||
});
|
||||
|
||||
// Cancel all notifications
|
||||
await dailyNotification.cancelAllNotifications();
|
||||
|
||||
// Get battery status
|
||||
const batteryStatus = await dailyNotification.getBatteryStatus();
|
||||
|
||||
// Request battery optimization exemption
|
||||
await dailyNotification.requestBatteryOptimizationExemption();
|
||||
```
|
||||
|
||||
#### Timezone Support
|
||||
## Configuration
|
||||
|
||||
```typescript
|
||||
await DailyNotification.scheduleDailyNotification({
|
||||
url: 'https://api.example.com/updates',
|
||||
time: '09:00',
|
||||
timezone: 'America/New_York'
|
||||
});
|
||||
### Android
|
||||
|
||||
Add the following permissions to your `AndroidManifest.xml`:
|
||||
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
||||
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
```
|
||||
|
||||
#### Check Notification Status
|
||||
## Development
|
||||
|
||||
```typescript
|
||||
const status = await DailyNotification.getNotificationStatus();
|
||||
console.log('Notification status:', status);
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 14 or later
|
||||
- Android Studio
|
||||
- Android SDK
|
||||
- Gradle
|
||||
|
||||
### Building
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Build the plugin
|
||||
npm run build
|
||||
|
||||
# Run tests
|
||||
npm test
|
||||
```
|
||||
|
||||
#### Update Settings
|
||||
### Project Structure
|
||||
|
||||
```typescript
|
||||
await DailyNotification.updateSettings({
|
||||
sound: true,
|
||||
priority: 'high',
|
||||
timezone: 'America/Los_Angeles'
|
||||
});
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
|
||||
### Methods
|
||||
|
||||
#### scheduleDailyNotification(options: ScheduleOptions)
|
||||
Schedule a new daily notification.
|
||||
|
||||
#### getLastNotification()
|
||||
Get information about the last delivered notification.
|
||||
|
||||
#### cancelAllNotifications()
|
||||
Cancel all pending notifications.
|
||||
|
||||
#### getNotificationStatus()
|
||||
Get current notification status and settings.
|
||||
|
||||
#### updateSettings(settings: NotificationSettings)
|
||||
Update notification settings.
|
||||
|
||||
#### checkPermissions()
|
||||
Check current notification permissions.
|
||||
|
||||
#### requestPermissions()
|
||||
Request notification permissions.
|
||||
|
||||
### Types
|
||||
|
||||
```typescript
|
||||
interface ScheduleOptions {
|
||||
url: string;
|
||||
time: string;
|
||||
title?: string;
|
||||
body?: string;
|
||||
sound?: boolean;
|
||||
priority?: 'high' | 'default' | 'low';
|
||||
timezone?: string;
|
||||
}
|
||||
|
||||
interface NotificationSettings {
|
||||
sound?: boolean;
|
||||
priority?: string;
|
||||
timezone?: string;
|
||||
}
|
||||
daily-notification-plugin/
|
||||
├── android/ # Android implementation
|
||||
│ ├── app/ # Main application module
|
||||
│ └── build.gradle # Root build configuration
|
||||
├── src/ # TypeScript source
|
||||
├── tests/ # Test files
|
||||
├── package.json # Package configuration
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
The plugin provides detailed error messages for various scenarios:
|
||||
- Invalid parameters
|
||||
- Permission issues
|
||||
- Scheduling failures
|
||||
- Invalid time formats
|
||||
- Invalid timezone identifiers
|
||||
- Invalid priority values
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our GitHub repository.
|
||||
1. Fork the repository
|
||||
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
||||
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
||||
4. Push to the branch (`git push origin feature/amazing-feature`)
|
||||
5. Open a Pull Request
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see LICENSE file for details
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
|
||||
## Author
|
||||
|
||||
Matthew Raymer
|
||||
|
||||
## Security
|
||||
|
||||
This plugin follows security best practices:
|
||||
|
||||
- Uses AndroidX for modern security features
|
||||
- Implements proper permission handling
|
||||
- Follows Android security guidelines
|
||||
- Uses secure storage for sensitive data
|
||||
- Implements proper error handling
|
||||
- Logs security-relevant events
|
||||
- Uses secure communication channels
|
||||
- Implements proper access control
|
||||
- Follows Android's security model
|
||||
- Uses secure defaults
|
||||
|
||||
## Changelog
|
||||
|
||||
### 1.0.0
|
||||
- Initial release
|
||||
- Basic notification scheduling
|
||||
- System state handling
|
||||
- Battery optimization support
|
||||
- Background task management
|
||||
- Rich logging system
|
||||
|
||||
0
android/Configure
Normal file
0
android/Configure
Normal file
@@ -1,15 +1,12 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'jacoco'
|
||||
|
||||
android {
|
||||
namespace "com.timesafari.dailynotification"
|
||||
compileSdkVersion 33
|
||||
buildToolsVersion "33.0.2"
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
defaultConfig {
|
||||
applicationId "com.timesafari.dailynotification"
|
||||
minSdkVersion 22
|
||||
targetSdkVersion 33
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
@@ -22,98 +19,27 @@ android {
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
testOptions {
|
||||
unitTests.all {
|
||||
useJUnitPlatform()
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven {
|
||||
url "${project.rootDir}/capacitor-cordova-android-plugins/src/main/libs"
|
||||
}
|
||||
maven {
|
||||
url "${project.rootDir}/libs"
|
||||
flatDir{
|
||||
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
|
||||
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
|
||||
implementation project(':capacitor-android')
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
||||
implementation project(':capacitor-cordova-android-plugins')
|
||||
|
||||
// Android SDK
|
||||
implementation 'com.android.support:support-v4:28.0.0'
|
||||
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||
implementation 'com.android.support:design:28.0.0'
|
||||
|
||||
// AndroidX Core
|
||||
implementation 'androidx.core:core:1.9.0'
|
||||
implementation 'androidx.core:core-ktx:1.12.0'
|
||||
|
||||
// AndroidX AppCompat
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
|
||||
// AndroidX Test
|
||||
testImplementation 'androidx.test:core:1.5.0'
|
||||
testImplementation 'androidx.test:runner:1.5.2'
|
||||
testImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
testImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
testImplementation 'androidx.test:rules:1.5.0'
|
||||
testImplementation 'androidx.test:core-ktx:1.5.0'
|
||||
|
||||
// JUnit
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.2'
|
||||
|
||||
// Mockito
|
||||
testImplementation 'org.mockito:mockito-core:4.5.1'
|
||||
testImplementation 'org.mockito:mockito-inline:4.5.1'
|
||||
|
||||
// AndroidX WorkManager
|
||||
implementation 'androidx.work:work-runtime:2.8.1'
|
||||
|
||||
// AndroidX Room (for local storage)
|
||||
implementation 'androidx.room:room-runtime:2.6.1'
|
||||
annotationProcessor 'androidx.room:room-compiler:2.6.1'
|
||||
|
||||
// AndroidX Lifecycle
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime:2.7.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-common-java8:2.7.0'
|
||||
|
||||
// AndroidX Security
|
||||
implementation 'androidx.security:security-crypto:1.1.0-alpha06'
|
||||
|
||||
// AndroidX Notification
|
||||
implementation 'androidx.media:media:1.7.0'
|
||||
|
||||
// AndroidX Broadcast
|
||||
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
|
||||
|
||||
// Capacitor dependencies
|
||||
implementation 'com.getcapacitor:capacitor:5.0.0'
|
||||
implementation 'com.getcapacitor:capacitor-android:5.0.0'
|
||||
|
||||
// Testing dependencies
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
androidTestImplementation 'androidx.test:runner:1.5.2'
|
||||
androidTestImplementation 'androidx.test:rules:1.5.0'
|
||||
androidTestImplementation 'org.mockito:mockito-android:4.5.1'
|
||||
}
|
||||
|
||||
apply from: 'capacitor.build.gradle'
|
||||
@@ -124,5 +50,5 @@ try {
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
}
|
||||
} catch(Exception e) {
|
||||
logger.warn("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
|
||||
logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
|
||||
}
|
||||
|
||||
@@ -9,6 +9,11 @@ android {
|
||||
|
||||
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
|
||||
dependencies {
|
||||
implementation project(':capacitor-android')
|
||||
implementation project(':capacitor-cordova-android-plugins')
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (hasProperty('postBuildExtras')) {
|
||||
postBuildExtras()
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
/home/matthew/projects/timesafari/daily-notification-plugin/android/app/src/androidTest/java/com/timesafari/dailynotification/DailyNotificationPluginTest.java
|
||||
@@ -1,104 +0,0 @@
|
||||
/**
|
||||
* DailyNotificationConfigTest.java
|
||||
* Daily Notification Plugin for Capacitor
|
||||
*
|
||||
* Tests for the DailyNotificationConfig
|
||||
*
|
||||
* Features:
|
||||
* - Unit tests
|
||||
* - Singleton pattern
|
||||
* - Configuration management
|
||||
* - Default values
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
*/
|
||||
|
||||
package com.timesafari.dailynotification;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DailyNotificationConfigTest {
|
||||
private DailyNotificationConfig config;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
config = DailyNotificationConfig.getInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingletonPattern() {
|
||||
DailyNotificationConfig config2 = DailyNotificationConfig.getInstance();
|
||||
assertSame("Config instances should be the same", config, config2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultValues() {
|
||||
assertEquals("Default max notifications should be 10", 10,
|
||||
config.getMaxNotificationsPerDay());
|
||||
assertEquals("Default timezone should be system default",
|
||||
TimeZone.getDefault(), config.getDefaultTimeZone());
|
||||
assertTrue("Default logging should be enabled", config.isLoggingEnabled());
|
||||
assertEquals("Default retention days should be 7", 7,
|
||||
config.getRetentionDays());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxNotificationsPerDay() {
|
||||
config.setMaxNotificationsPerDay(5);
|
||||
assertEquals("Max notifications should be 5", 5,
|
||||
config.getMaxNotificationsPerDay());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultTimeZone() {
|
||||
TimeZone newTimeZone = TimeZone.getTimeZone("America/New_York");
|
||||
config.setDefaultTimeZone(newTimeZone);
|
||||
assertEquals("Default timezone should be America/New_York",
|
||||
newTimeZone, config.getDefaultTimeZone());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoggingEnabled() {
|
||||
config.setLoggingEnabled(false);
|
||||
assertFalse("Logging should be disabled", config.isLoggingEnabled());
|
||||
|
||||
config.setLoggingEnabled(true);
|
||||
assertTrue("Logging should be enabled", config.isLoggingEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetentionDays() {
|
||||
config.setRetentionDays(14);
|
||||
assertEquals("Retention days should be 14", 14,
|
||||
config.getRetentionDays());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetToDefaults() {
|
||||
// Change values
|
||||
config.setMaxNotificationsPerDay(5);
|
||||
config.setDefaultTimeZone(TimeZone.getTimeZone("America/New_York"));
|
||||
config.setLoggingEnabled(false);
|
||||
config.setRetentionDays(14);
|
||||
|
||||
// Reset to defaults
|
||||
config.resetToDefaults();
|
||||
|
||||
// Verify defaults
|
||||
assertEquals("Max notifications should be reset to 10", 10,
|
||||
config.getMaxNotificationsPerDay());
|
||||
assertEquals("Default timezone should be reset to system default",
|
||||
TimeZone.getDefault(), config.getDefaultTimeZone());
|
||||
assertTrue("Logging should be reset to enabled", config.isLoggingEnabled());
|
||||
assertEquals("Retention days should be reset to 7", 7,
|
||||
config.getRetentionDays());
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
/**
|
||||
* DailyNotificationConstantsTest.java
|
||||
* Daily Notification Plugin for Capacitor
|
||||
*
|
||||
* Tests for the DailyNotificationConstants
|
||||
*
|
||||
* Features:
|
||||
* - Unit tests
|
||||
* - Constant validation
|
||||
* - Default values
|
||||
* - Error messages
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
*/
|
||||
|
||||
package com.timesafari.dailynotification;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DailyNotificationConstantsTest {
|
||||
|
||||
@Test
|
||||
public void testDefaultValues() {
|
||||
assertEquals("Default title should be 'Daily Notification'",
|
||||
"Daily Notification", DailyNotificationConstants.DEFAULT_TITLE);
|
||||
assertEquals("Default body should be 'Your daily update is ready'",
|
||||
"Your daily update is ready", DailyNotificationConstants.DEFAULT_BODY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotificationIdentifiers() {
|
||||
assertTrue("Notification ID prefix should start with 'daily-notification-'",
|
||||
DailyNotificationConstants.NOTIFICATION_ID_PREFIX.startsWith("daily-notification-"));
|
||||
assertEquals("Event name should be 'notification'",
|
||||
"notification", DailyNotificationConstants.EVENT_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSettingsKeys() {
|
||||
assertEquals("Sound setting key should be 'sound'",
|
||||
"sound", DailyNotificationConstants.Settings.SOUND);
|
||||
assertEquals("Priority setting key should be 'priority'",
|
||||
"priority", DailyNotificationConstants.Settings.PRIORITY);
|
||||
assertEquals("Timezone setting key should be 'timezone'",
|
||||
"timezone", DailyNotificationConstants.Settings.TIMEZONE);
|
||||
assertEquals("Retry count setting key should be 'retryCount'",
|
||||
"retryCount", DailyNotificationConstants.Settings.RETRY_COUNT);
|
||||
assertEquals("Retry interval setting key should be 'retryInterval'",
|
||||
"retryInterval", DailyNotificationConstants.Settings.RETRY_INTERVAL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSettingsDefaultValues() {
|
||||
assertTrue("Default sound should be true",
|
||||
DailyNotificationConstants.Settings.DEFAULT_SOUND);
|
||||
assertEquals("Default priority should be 'default'",
|
||||
"default", DailyNotificationConstants.Settings.DEFAULT_PRIORITY);
|
||||
assertEquals("Default retry count should be 3",
|
||||
3, DailyNotificationConstants.Settings.DEFAULT_RETRY_COUNT);
|
||||
assertEquals("Default retry interval should be 1000",
|
||||
1000, DailyNotificationConstants.Settings.DEFAULT_RETRY_INTERVAL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPluginMethodKeys() {
|
||||
assertEquals("URL key should be 'url'",
|
||||
"url", DailyNotificationConstants.Keys.URL);
|
||||
assertEquals("Time key should be 'time'",
|
||||
"time", DailyNotificationConstants.Keys.TIME);
|
||||
assertEquals("Title key should be 'title'",
|
||||
"title", DailyNotificationConstants.Keys.TITLE);
|
||||
assertEquals("Body key should be 'body'",
|
||||
"body", DailyNotificationConstants.Keys.BODY);
|
||||
assertEquals("Sound key should be 'sound'",
|
||||
"sound", DailyNotificationConstants.Keys.SOUND);
|
||||
assertEquals("Priority key should be 'priority'",
|
||||
"priority", DailyNotificationConstants.Keys.PRIORITY);
|
||||
assertEquals("Timezone key should be 'timezone'",
|
||||
"timezone", DailyNotificationConstants.Keys.TIMEZONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChannelSettings() {
|
||||
assertEquals("Channel ID should be 'daily_notification_channel'",
|
||||
"daily_notification_channel", DailyNotificationConstants.Channel.ID);
|
||||
assertEquals("Channel name should be 'Daily Notifications'",
|
||||
"Daily Notifications", DailyNotificationConstants.Channel.NAME);
|
||||
assertEquals("Channel description should be 'Daily notification updates'",
|
||||
"Daily notification updates", DailyNotificationConstants.Channel.DESCRIPTION);
|
||||
assertTrue("Channel should enable vibration",
|
||||
DailyNotificationConstants.Channel.ENABLE_VIBRATION);
|
||||
assertTrue("Channel should enable lights",
|
||||
DailyNotificationConstants.Channel.ENABLE_LIGHTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimeConstants() {
|
||||
assertEquals("Milliseconds per day should be 86400000",
|
||||
86400000, DailyNotificationConstants.Time.MILLIS_PER_DAY);
|
||||
assertEquals("Maximum hours should be 24",
|
||||
24, DailyNotificationConstants.Time.MAX_HOURS);
|
||||
assertEquals("Maximum minutes should be 60",
|
||||
60, DailyNotificationConstants.Time.MAX_MINUTES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorMessages() {
|
||||
assertEquals("Missing parameters error message should be correct",
|
||||
"Missing required parameters", DailyNotificationConstants.Errors.MISSING_PARAMS);
|
||||
assertEquals("Invalid time error message should be correct",
|
||||
"Invalid time format", DailyNotificationConstants.Errors.INVALID_TIME);
|
||||
assertEquals("Invalid timezone error message should be correct",
|
||||
"Invalid timezone", DailyNotificationConstants.Errors.INVALID_TIMEZONE);
|
||||
assertEquals("Invalid priority error message should be correct",
|
||||
"Invalid priority value", DailyNotificationConstants.Errors.INVALID_PRIORITY);
|
||||
assertEquals("Scheduling failed error message should be correct",
|
||||
"Failed to schedule notification", DailyNotificationConstants.Errors.SCHEDULING_FAILED);
|
||||
assertEquals("Permission denied error message should be correct",
|
||||
"Notification permission denied", DailyNotificationConstants.Errors.PERMISSION_DENIED);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user