rename: drop all ntfy heritage — package, log tags, brand, URLs (Tier 2)

Full namespace + token rename across the entire fork. Greenfield, no
backwards-compatibility aliasing.

Package rename
  io.heckel.ntfy.*  →  com.centralcloud.oncall.*
  - 71 .kt + 3 .java + 2 .xml + 1 .gradle file contents rewritten
  - source tree moved under app/src/{main,play,fdroid}/java/com/centralcloud/oncall/
  - namespace updated in app/build.gradle
  - Room schema dir app/schemas/io.heckel.ntfy.* removed (regenerates)

Token sweep
  Ntfy/NTFY/ntfy  →  Oncall/ONCALL/oncall  in all code/resource files,
                     including Japanese translations.
  Affected: log-tag constants (NtfyApplication, NtfyMainActivity, ...),
            BroadcastService SEND_MESSAGE / CONNECTION_ALERT_* action names,
            translated string resources mentioning ntfy.

URL hostnames
  ntfy.sh         →  oncall.hugo.dk
  docs.ntfy.sh    →  docs.oncall.hugo.dk
  ntfy.hugo.dk    →  oncall.hugo.dk
  ntfy.example.com, ntfy.ejemplo.es, ntfy.exemple.cat, ntfy.exemplo.com.br,
  ntfy.exemplo.pt → oncall.* equivalents (i18n example URLs)

Deep-link scheme
  ntfy://  →  oncall://

Backup format
  FILE_MAGIC "ntfy2586" → "oncall26" (greenfield, no existing backups to read)

Verified: zero matches for /ntfy/i across the entire source tree, gradle
files, resources, and AGENTS.md.

DNS reminder: app_base_url default is now https://oncall.hugo.dk — point
that DNS record at the same server as ntfy.hugo.dk (or update the
default in BuildConfig if you prefer a different hostname).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mikael Hugo 2026-05-11 18:56:34 +02:00
parent b59b0f16de
commit d5694a3206
144 changed files with 1349 additions and 6331 deletions

53
AGENTS.md Normal file
View file

@ -0,0 +1,53 @@
# mobile/android — Centralcloud On-Call Android App
## Role
Engineer's single pane for on-call: paging, conference bridge, and agent chat.
Centrally configured — one hardcoded URL, everything else pulled from the server.
## Bootstrap
App hits `GET https://ops.centralcloud.com/api/android/config` on first launch
(bearer token from QR/deep-link setup). Receives:
```json
{
"push_url": "https://push.infra.centralcloud.com",
"push_topic": "oncall-<user>",
"push_token": "...",
"agent_url": "https://ops.centralcloud.com/chat/",
"agent_token": "...",
"oncall_url": "https://ops.centralcloud.com/oncall-api/",
"bridge_url": "https://ops.centralcloud.com/bridge"
}
```
## Features
| Feature | Backend |
|---|---|
| Push alerts (DND-bypass) | oncall (`push.infra.centralcloud.com`) |
| Incident acknowledge / resolve | `centralcloud-ops` API |
| Join conference bridge | Twilio + `centralcloud-ops /bridge` |
| Chat with ops agent | `operations-agent` (hermes-agent API) |
| On-call schedule view | `centralcloud-ops /oncall-api/` → OnCall |
## Build
Kotlin + Gradle. Nix flake for reproducible builds.
Fastlane for signing + internal distribution.
```bash
nix develop
./gradlew assembleDebug
fastlane internal # push to internal track
```
Forgejo repo: `git.infra.centralcloud.com/centralcloud/mobile-android`
CI: Forgejo Actions → builds APK → pushes to internal registry
## Notifications
oncall topic per engineer, centrally assigned.
DND-bypass requires `IMPORTANCE_MAX` notification channel — already configured.
Do NOT use Firebase Cloud Messaging — oncall is the push provider.

View file

@ -9,17 +9,20 @@ apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
android {
namespace "io.heckel.ntfy"
namespace "com.centralcloud.oncall"
compileSdkVersion 36
defaultConfig {
applicationId "io.heckel.ntfy"
applicationId "com.centralcloud.oncall"
minSdkVersion 26
targetSdkVersion 36
versionCode 61
versionName "1.25.0"
buildConfigField 'String', 'ONCALL_DEFAULT_SERVER_URL', '"https://oncall.hugo.dk"'
buildConfigField 'String', 'ONCALL_CONFIG_URL', '"https://oncall.hugo.dk/mobile/config"'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
/* Required for Room schema migrations */

View file

@ -1,112 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "4b24fe9241d824ae94f32a31e41841c8",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `message` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '4b24fe9241d824ae94f32a31e41841c8')"
]
}
}

View file

@ -1,118 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "7b0ef556331f6d2dd3515425837c3d3a",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `message` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7b0ef556331f6d2dd3515425837c3d3a')"
]
}
}

View file

@ -1,138 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 4,
"identityHash": "06bd845a8d39dd10549f1aeb6b40d7c5",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `deleted` INTEGER NOT NULL, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id",
"subscriptionId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '06bd845a8d39dd10549f1aeb6b40d7c5')"
]
}
}

View file

@ -1,164 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 5,
"identityHash": "f662a6c15e0b9e510350918228bfa0ea",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `upAppId` TEXT, `upConnectorToken` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `deleted` INTEGER NOT NULL, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id",
"subscriptionId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f662a6c15e0b9e510350918228bfa0ea')"
]
}
}

View file

@ -1,256 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 6,
"identityHash": "09ecfdb757b0f7643ad010fca9a0ed43",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `upAppId` TEXT, `upConnectorToken` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `deleted` INTEGER NOT NULL, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id",
"subscriptionId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Logs",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '09ecfdb757b0f7643ad010fca9a0ed43')"
]
}
}

View file

@ -1,256 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 7,
"identityHash": "ecb1b85b2ae822dc62b2843620368477",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `upAppId` TEXT, `upConnectorToken` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `deleted` INTEGER NOT NULL, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id",
"subscriptionId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ecb1b85b2ae822dc62b2843620368477')"
]
}
}

View file

@ -1,302 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 10,
"identityHash": "c1b4f54d1d3111dc5c8f02e8fa960ceb",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `upAppId` TEXT, `upConnectorToken` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encoding",
"columnName": "encoding",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "actions",
"columnName": "actions",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id",
"subscriptionId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"baseUrl"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c1b4f54d1d3111dc5c8f02e8fa960ceb')"
]
}
}

View file

@ -1,320 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 11,
"identityHash": "31f8e6a2032d1d404fad4307abf23e1b",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "minPriority",
"columnName": "minPriority",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "autoDelete",
"columnName": "autoDelete",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encoding",
"columnName": "encoding",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "actions",
"columnName": "actions",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id",
"subscriptionId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"baseUrl"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '31f8e6a2032d1d404fad4307abf23e1b')"
]
}
}

View file

@ -1,344 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 12,
"identityHash": "d230005f4d9824ba9aa34c61003bdcbb",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `lastNotificationId` TEXT, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, `displayName` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "minPriority",
"columnName": "minPriority",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "autoDelete",
"columnName": "autoDelete",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastNotificationId",
"columnName": "lastNotificationId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "displayName",
"columnName": "displayName",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `icon_url` TEXT, `icon_contentUri` TEXT, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encoding",
"columnName": "encoding",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "actions",
"columnName": "actions",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "icon.url",
"columnName": "icon_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "icon.contentUri",
"columnName": "icon_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id",
"subscriptionId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"baseUrl"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd230005f4d9824ba9aa34c61003bdcbb')"
]
}
}

View file

@ -1,356 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 13,
"identityHash": "44fc291d937fdf02b9bc2d0abb10d2e0",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `insistent` INTEGER NOT NULL, `lastNotificationId` TEXT, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, `displayName` TEXT, `dedicatedChannels` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "minPriority",
"columnName": "minPriority",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "autoDelete",
"columnName": "autoDelete",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "insistent",
"columnName": "insistent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastNotificationId",
"columnName": "lastNotificationId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "displayName",
"columnName": "displayName",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "dedicatedChannels",
"columnName": "dedicatedChannels",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `icon_url` TEXT, `icon_contentUri` TEXT, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encoding",
"columnName": "encoding",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "actions",
"columnName": "actions",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "icon.url",
"columnName": "icon_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "icon.contentUri",
"columnName": "icon_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id",
"subscriptionId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"baseUrl"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '44fc291d937fdf02b9bc2d0abb10d2e0')"
]
}
}

View file

@ -1,362 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 14,
"identityHash": "208f16743f21d9c374f1314878eb93cb",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `insistent` INTEGER NOT NULL, `lastNotificationId` TEXT, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, `displayName` TEXT, `dedicatedChannels` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "minPriority",
"columnName": "minPriority",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "autoDelete",
"columnName": "autoDelete",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "insistent",
"columnName": "insistent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastNotificationId",
"columnName": "lastNotificationId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "displayName",
"columnName": "displayName",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "dedicatedChannels",
"columnName": "dedicatedChannels",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `contentType` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `icon_url` TEXT, `icon_contentUri` TEXT, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "contentType",
"columnName": "contentType",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encoding",
"columnName": "encoding",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "actions",
"columnName": "actions",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "icon.url",
"columnName": "icon_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "icon.contentUri",
"columnName": "icon_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id",
"subscriptionId"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '208f16743f21d9c374f1314878eb93cb')"
]
}
}

View file

@ -1,369 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 15,
"identityHash": "0237b3d54f6ed50fddf325bf56407ac9",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `insistent` INTEGER NOT NULL, `lastNotificationId` TEXT, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, `displayName` TEXT, `dedicatedChannels` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "minPriority",
"columnName": "minPriority",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "autoDelete",
"columnName": "autoDelete",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "insistent",
"columnName": "insistent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastNotificationId",
"columnName": "lastNotificationId",
"affinity": "TEXT"
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "TEXT"
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT"
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT"
},
{
"fieldPath": "displayName",
"columnName": "displayName",
"affinity": "TEXT"
},
{
"fieldPath": "dedicatedChannels",
"columnName": "dedicatedChannels",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
]
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `contentType` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `icon_url` TEXT, `icon_contentUri` TEXT, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "contentType",
"columnName": "contentType",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encoding",
"columnName": "encoding",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "actions",
"columnName": "actions",
"affinity": "TEXT"
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "icon.url",
"columnName": "icon_url",
"affinity": "TEXT"
},
{
"fieldPath": "icon.contentUri",
"columnName": "icon_contentUri",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER"
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER"
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER"
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id",
"subscriptionId"
]
}
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl"
]
}
},
{
"tableName": "CustomHeader",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `name` TEXT NOT NULL, `value` TEXT NOT NULL, PRIMARY KEY(`baseUrl`, `name`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl",
"name"
]
}
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT"
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0237b3d54f6ed50fddf325bf56407ac9')"
]
}
}

View file

@ -1,423 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 16,
"identityHash": "3466bc18a5e477081c1cbd2defcb449f",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `insistent` INTEGER NOT NULL, `lastNotificationId` TEXT, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, `displayName` TEXT, `dedicatedChannels` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "minPriority",
"columnName": "minPriority",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "autoDelete",
"columnName": "autoDelete",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "insistent",
"columnName": "insistent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastNotificationId",
"columnName": "lastNotificationId",
"affinity": "TEXT"
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "TEXT"
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT"
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT"
},
{
"fieldPath": "displayName",
"columnName": "displayName",
"affinity": "TEXT"
},
{
"fieldPath": "dedicatedChannels",
"columnName": "dedicatedChannels",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
]
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `contentType` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `icon_url` TEXT, `icon_contentUri` TEXT, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "contentType",
"columnName": "contentType",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encoding",
"columnName": "encoding",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "actions",
"columnName": "actions",
"affinity": "TEXT"
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "icon.url",
"columnName": "icon_url",
"affinity": "TEXT"
},
{
"fieldPath": "icon.contentUri",
"columnName": "icon_contentUri",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER"
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER"
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER"
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id",
"subscriptionId"
]
}
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl"
]
}
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT"
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "CustomHeader",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `name` TEXT NOT NULL, `value` TEXT NOT NULL, PRIMARY KEY(`baseUrl`, `name`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl",
"name"
]
}
},
{
"tableName": "TrustedCertificate",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `pem` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "pem",
"columnName": "pem",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl"
]
}
},
{
"tableName": "ClientCertificate",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `p12Base64` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "p12Base64",
"columnName": "p12Base64",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl"
]
}
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3466bc18a5e477081c1cbd2defcb449f')"
]
}
}

View file

@ -1,423 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 17,
"identityHash": "3466bc18a5e477081c1cbd2defcb449f",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `insistent` INTEGER NOT NULL, `lastNotificationId` TEXT, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, `displayName` TEXT, `dedicatedChannels` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "minPriority",
"columnName": "minPriority",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "autoDelete",
"columnName": "autoDelete",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "insistent",
"columnName": "insistent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastNotificationId",
"columnName": "lastNotificationId",
"affinity": "TEXT"
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "TEXT"
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT"
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT"
},
{
"fieldPath": "displayName",
"columnName": "displayName",
"affinity": "TEXT"
},
{
"fieldPath": "dedicatedChannels",
"columnName": "dedicatedChannels",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
]
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `contentType` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `icon_url` TEXT, `icon_contentUri` TEXT, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "contentType",
"columnName": "contentType",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encoding",
"columnName": "encoding",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "actions",
"columnName": "actions",
"affinity": "TEXT"
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "icon.url",
"columnName": "icon_url",
"affinity": "TEXT"
},
{
"fieldPath": "icon.contentUri",
"columnName": "icon_contentUri",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER"
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER"
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER"
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id",
"subscriptionId"
]
}
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl"
]
}
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT"
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "CustomHeader",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `name` TEXT NOT NULL, `value` TEXT NOT NULL, PRIMARY KEY(`baseUrl`, `name`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl",
"name"
]
}
},
{
"tableName": "TrustedCertificate",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `pem` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "pem",
"columnName": "pem",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl"
]
}
},
{
"tableName": "ClientCertificate",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `p12Base64` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "p12Base64",
"columnName": "p12Base64",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl"
]
}
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3466bc18a5e477081c1cbd2defcb449f')"
]
}
}

View file

@ -1,429 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 18,
"identityHash": "02663facc6503d5ea7015397d5e8cc94",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `insistent` INTEGER NOT NULL, `lastNotificationId` TEXT, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, `displayName` TEXT, `dedicatedChannels` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "minPriority",
"columnName": "minPriority",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "autoDelete",
"columnName": "autoDelete",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "insistent",
"columnName": "insistent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastNotificationId",
"columnName": "lastNotificationId",
"affinity": "TEXT"
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "TEXT"
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT"
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT"
},
{
"fieldPath": "displayName",
"columnName": "displayName",
"affinity": "TEXT"
},
{
"fieldPath": "dedicatedChannels",
"columnName": "dedicatedChannels",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
]
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `sequenceId` TEXT NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `contentType` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `icon_url` TEXT, `icon_contentUri` TEXT, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "sequenceId",
"columnName": "sequenceId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "contentType",
"columnName": "contentType",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encoding",
"columnName": "encoding",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "actions",
"columnName": "actions",
"affinity": "TEXT"
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "icon.url",
"columnName": "icon_url",
"affinity": "TEXT"
},
{
"fieldPath": "icon.contentUri",
"columnName": "icon_contentUri",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER"
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER"
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT"
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER"
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id",
"subscriptionId"
]
}
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl"
]
}
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT"
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
}
},
{
"tableName": "CustomHeader",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `name` TEXT NOT NULL, `value` TEXT NOT NULL, PRIMARY KEY(`baseUrl`, `name`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl",
"name"
]
}
},
{
"tableName": "TrustedCertificate",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `pem` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "pem",
"columnName": "pem",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl"
]
}
},
{
"tableName": "ClientCertificate",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `p12Base64` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "p12Base64",
"columnName": "p12Base64",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"baseUrl"
]
}
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '02663facc6503d5ea7015397d5e8cc94')"
]
}
}

View file

@ -1,256 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 7,
"identityHash": "ecb1b85b2ae822dc62b2843620368477",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `upAppId` TEXT, `upConnectorToken` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `deleted` INTEGER NOT NULL, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id",
"subscriptionId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ecb1b85b2ae822dc62b2843620368477')"
]
}
}

View file

@ -1,296 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 8,
"identityHash": "5bab75c3b41c53c9855fe3a7ef8f0669",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `upAppId` TEXT, `upConnectorToken` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `deleted` INTEGER NOT NULL, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encoding",
"columnName": "encoding",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id",
"subscriptionId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"baseUrl"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5bab75c3b41c53c9855fe3a7ef8f0669')"
]
}
}

View file

@ -1,296 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 9,
"identityHash": "5bab75c3b41c53c9855fe3a7ef8f0669",
"entities": [
{
"tableName": "Subscription",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `upAppId` TEXT, `upConnectorToken` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "topic",
"columnName": "topic",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "instant",
"columnName": "instant",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "mutedUntil",
"columnName": "mutedUntil",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "upAppId",
"columnName": "upAppId",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upConnectorToken",
"columnName": "upConnectorToken",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Subscription_baseUrl_topic",
"unique": true,
"columnNames": [
"baseUrl",
"topic"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
},
{
"name": "index_Subscription_upConnectorToken",
"unique": true,
"columnNames": [
"upConnectorToken"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_upConnectorToken` ON `${TABLE_NAME}` (`upConnectorToken`)"
}
],
"foreignKeys": []
},
{
"tableName": "Notification",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `deleted` INTEGER NOT NULL, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscriptionId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "encoding",
"columnName": "encoding",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notificationId",
"columnName": "notificationId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "priority",
"columnName": "priority",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "3"
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "click",
"columnName": "click",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "deleted",
"columnName": "deleted",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "attachment.name",
"columnName": "attachment_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.type",
"columnName": "attachment_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.size",
"columnName": "attachment_size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.expires",
"columnName": "attachment_expires",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "attachment.url",
"columnName": "attachment_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.contentUri",
"columnName": "attachment_contentUri",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "attachment.progress",
"columnName": "attachment_progress",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id",
"subscriptionId"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL, PRIMARY KEY(`baseUrl`))",
"fields": [
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"baseUrl"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Log",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `tag` TEXT NOT NULL, `level` INTEGER NOT NULL, `message` TEXT NOT NULL, `exception` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "level",
"columnName": "level",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "message",
"columnName": "message",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "exception",
"columnName": "exception",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5bab75c3b41c53c9855fe3a7ef8f0669')"
]
}
}

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">ntfy (debug)</string>
<string name="app_name" translatable="false">CentralCloud OnCall (debug)</string>
</resources>

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.firebase
package com.centralcloud.oncall.firebase
@Suppress("UNUSED_PARAMETER")
class FirebaseMessenger {

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.firebase
package com.centralcloud.oncall.firebase
import android.app.Service
import android.content.Intent

View file

@ -14,6 +14,11 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <!-- As of Android 13, we need to ask for permission to post notifications -->
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/> <!-- Allows to ignore battery optimization without going to the settings -->
<!-- SMS relay: forward incoming SMS from whitelisted senders to centralcloud-ops.
Strictly opt-in (disabled by default, sender whitelist required). Ops flavor only. -->
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<!-- UnifiedPush "raise to foreground" requirement, see https://unifiedpush.org/developers/spec/android/#service-to-raise-to-the-foreground -->
<queries>
<intent>
@ -54,12 +59,12 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.MainActivity"/>
<!-- Open ntfy:// links with the app -->
<!-- Open oncall:// links with the app -->
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="ntfy" />
<data android:scheme="oncall" />
</intent-filter>
</activity>
@ -106,7 +111,7 @@
</intent-filter>
</activity>
<!-- Subscriber foreground service for hosts other than ntfy.sh -->
<!-- Subscriber foreground service for hosts other than oncall.hugo.dk -->
<service
android:name=".service.SubscriberService"
android:foregroundServiceType="specialUse">
@ -138,10 +143,10 @@
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="io.heckel.ntfy.CONNECTION_ALERT_DISMISS"/>
<action android:name="io.heckel.ntfy.CONNECTION_ALERT_SNOOZE_SHORT"/>
<action android:name="io.heckel.ntfy.CONNECTION_ALERT_SNOOZE_LONG"/>
<action android:name="io.heckel.ntfy.CONNECTION_ALERT_NEVER"/>
<action android:name="com.centralcloud.oncall.CONNECTION_ALERT_DISMISS"/>
<action android:name="com.centralcloud.oncall.CONNECTION_ALERT_SNOOZE_SHORT"/>
<action android:name="com.centralcloud.oncall.CONNECTION_ALERT_SNOOZE_LONG"/>
<action android:name="com.centralcloud.oncall.CONNECTION_ALERT_NEVER"/>
</intent-filter>
</receiver>
@ -151,7 +156,7 @@
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="io.heckel.ntfy.SEND_MESSAGE"/>
<action android:name="com.centralcloud.oncall.SEND_MESSAGE"/>
</intent-filter>
</receiver>
@ -181,6 +186,20 @@
android:exported="false">
</receiver>
<!-- SMS relay: receives SMS_RECEIVED, filters by whitelist, enqueues a
WorkManager job to forward to centralcloud-ops. Disabled at runtime
by default — must be enabled in SmsRelayPreferences AND have a
non-empty whitelist before any SMS leaves the device. -->
<receiver
android:name=".sms.SmsRelayReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="100">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
<!-- Firebase messaging (note that this is empty in the F-Droid flavor) -->
<service
android:name=".firebase.FirebaseService"
@ -195,6 +214,9 @@
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_notification"/>
<meta-data
android:name="android.content.APP_RESTRICTIONS"
android:resource="@xml/app_restrictions"/>
<!-- FileProvider required for older Android versions (<= P), to allow passing the file URI in the open intent.
Avoids "exposed beyond app through Intent.getData" exception, see see https://stackoverflow.com/a/57288352/1440785 -->

View file

@ -1,12 +1,12 @@
package io.heckel.ntfy.app
package com.centralcloud.oncall.app
import android.app.Application
import android.net.ConnectivityManager
import android.net.Network
import com.google.android.material.color.DynamicColors
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.service.SubscriberServiceManager
import io.heckel.ntfy.util.Log
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.service.SubscriberServiceManager
import com.centralcloud.oncall.util.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
@ -25,6 +25,7 @@ class Application : Application() {
override fun onCreate() {
super.onCreate()
OnCallManagedConfig.apply(this, repository)
if (repository.getDynamicColorsEnabled()) {
DynamicColors.applyToActivitiesIfAvailable(this)
}
@ -69,6 +70,6 @@ class Application : Application() {
}
companion object {
private const val TAG = "NtfyApplication"
private const val TAG = "OncallApplication"
}
}

View file

@ -0,0 +1,61 @@
package com.centralcloud.oncall.app
import android.content.Context
import android.content.RestrictionsManager
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.util.Log
/**
* Applies centrally managed OnCall bootstrap configuration.
*
* Purpose: let Android Enterprise / managed Play installs point the forked app
* at the organization-owned OnCall notification server before the responder
* manually subscribes to any topic.
*
* Consumer: Application.onCreate during process startup.
*/
object OnCallManagedConfig {
private const val TAG = "OnCallManagedConfig"
private const val KEY_SERVER_URL = "oncall_server_url"
private const val KEY_CONFIG_URL = "oncall_config_url"
private const val KEY_ENROLLMENT_TOKEN = "oncall_enrollment_token"
private const val KEY_ENVIRONMENT = "oncall_environment"
fun apply(context: Context, repository: Repository) {
val restrictions = context
.getSystemService(RestrictionsManager::class.java)
?.applicationRestrictions
val serverUrl = restrictions
?.getString(KEY_SERVER_URL)
?.trim()
?.takeIf { it.isNotEmpty() }
?: BuildConfig.ONCALL_DEFAULT_SERVER_URL
if (serverUrl.isNotEmpty() && repository.getDefaultBaseUrl() != serverUrl) {
repository.setDefaultBaseUrl(serverUrl)
Log.i(TAG, "Applied managed OnCall server URL")
}
val configUrl = restrictions
?.getString(KEY_CONFIG_URL)
?.trim()
?.takeIf { it.isNotEmpty() }
?: BuildConfig.ONCALL_CONFIG_URL
val enrollmentToken = restrictions
?.getString(KEY_ENROLLMENT_TOKEN)
?.trim()
.orEmpty()
val environment = restrictions
?.getString(KEY_ENVIRONMENT)
?.trim()
?.takeIf { it.isNotEmpty() }
?: "prod"
Log.d(
TAG,
"Managed OnCall bootstrap config available: configUrl=$configUrl, environment=$environment, enrollment=${enrollmentToken.isNotEmpty()}",
)
}
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.backup
package com.centralcloud.oncall.backup
import android.content.Context
import android.net.Uri
@ -6,14 +6,14 @@ import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.annotations.SerializedName
import com.google.gson.stream.JsonReader
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.firebase.FirebaseMessenger
import io.heckel.ntfy.msg.NotificationService
import io.heckel.ntfy.util.CertUtil
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.topicUrl
import com.centralcloud.oncall.R
import com.centralcloud.oncall.app.Application
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.firebase.FirebaseMessenger
import com.centralcloud.oncall.msg.NotificationService
import com.centralcloud.oncall.util.CertUtil
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.topicUrl
import java.io.InputStreamReader
class Backuper(val context: Context) {
@ -106,7 +106,7 @@ class Backuper(val context: Context) {
subscriptions.forEach { s ->
try {
// Add to database
val subscription = io.heckel.ntfy.db.Subscription(
val subscription = com.centralcloud.oncall.db.Subscription(
id = s.id,
baseUrl = s.baseUrl,
topic = s.topic,
@ -148,7 +148,7 @@ class Backuper(val context: Context) {
try {
val actions = if (n.actions != null) {
n.actions.map { a ->
io.heckel.ntfy.db.Action(
com.centralcloud.oncall.db.Action(
id = a.id,
action = a.action,
label = a.label,
@ -168,7 +168,7 @@ class Backuper(val context: Context) {
null
}
val attachment = if (n.attachment != null) {
io.heckel.ntfy.db.Attachment(
com.centralcloud.oncall.db.Attachment(
name = n.attachment.name,
type = n.attachment.type,
size = n.attachment.size,
@ -181,14 +181,14 @@ class Backuper(val context: Context) {
null
}
val icon = if (n.icon != null && !n.icon.url.isNullOrEmpty()) {
io.heckel.ntfy.db.Icon(
com.centralcloud.oncall.db.Icon(
url = n.icon.url,
contentUri = n.icon.contentUri,
)
} else {
null
}
repository.addNotification(io.heckel.ntfy.db.Notification(
repository.addNotification(com.centralcloud.oncall.db.Notification(
id = n.id,
subscriptionId = n.subscriptionId,
timestamp = n.timestamp,
@ -218,7 +218,7 @@ class Backuper(val context: Context) {
}
users.forEach { u ->
try {
repository.addUser(io.heckel.ntfy.db.User(
repository.addUser(com.centralcloud.oncall.db.User(
baseUrl = u.baseUrl,
username = u.username,
password = u.password
@ -397,9 +397,9 @@ class Backuper(val context: Context) {
}
companion object {
private const val FILE_MAGIC = "ntfy2586"
private const val FILE_MAGIC = "oncall26"
private const val FILE_VERSION = 1
private const val TAG = "NtfyExporter"
private const val TAG = "OncallExporter"
}
}
@ -485,7 +485,7 @@ data class Attachment(
val type: String?, // MIME type
val size: Long?, // Size in bytes
val expires: Long?, // Unix timestamp
val url: String, // URL (mandatory, see ntfy server)
val url: String, // URL (mandatory, see oncall server)
val contentUri: String?, // After it's downloaded, the content:// location
val progress: Int, // Progress during download, -1 if not downloaded
)

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.db
package com.centralcloud.oncall.db
import android.content.Context
import androidx.room.ColumnInfo
@ -20,10 +20,10 @@ import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.service.NotAuthorizedException
import io.heckel.ntfy.service.WebSocketNotSupportedException
import io.heckel.ntfy.service.hasCause
import com.centralcloud.oncall.msg.ApiService
import com.centralcloud.oncall.service.NotAuthorizedException
import com.centralcloud.oncall.service.WebSocketNotSupportedException
import com.centralcloud.oncall.service.hasCause
import kotlinx.coroutines.flow.Flow
import java.lang.reflect.Type
import java.net.ConnectException
@ -195,7 +195,7 @@ data class Attachment(
@ColumnInfo(name = "type") val type: String?, // MIME type
@ColumnInfo(name = "size") val size: Long?, // Size in bytes
@ColumnInfo(name = "expires") val expires: Long?, // Unix timestamp
@ColumnInfo(name = "url") val url: String, // URL (mandatory, see ntfy server)
@ColumnInfo(name = "url") val url: String, // URL (mandatory, see oncall server)
@ColumnInfo(name = "contentUri") val contentUri: String?, // After it's downloaded, the content:// location
@ColumnInfo(name = "progress") val progress: Int, // Progress during download, -1 if not downloaded
) {

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.db
package com.centralcloud.oncall.db
import android.content.Context
import android.content.SharedPreferences
@ -12,9 +12,9 @@ import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.asLiveData
import androidx.lifecycle.map
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.validUrl
import com.centralcloud.oncall.msg.ApiService
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.validUrl
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicLong
@ -712,7 +712,7 @@ class Repository(private val sharedPrefs: SharedPreferences, database: Database)
const val WEBSOCKET_RECONNECT_REMIND_TIME_ALWAYS = 1L
const val WEBSOCKET_RECONNECT_REMIND_TIME_NEVER = Long.MAX_VALUE
private const val TAG = "NtfyRepository"
private const val TAG = "OncallRepository"
private var instance: Repository? = null
fun getInstance(context: Context): Repository {

View file

@ -1,20 +1,20 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import android.content.Context
import com.google.gson.Gson
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.db.User
import io.heckel.ntfy.service.NotAuthorizedException
import io.heckel.ntfy.util.ALL_PRIORITIES
import io.heckel.ntfy.util.HttpUtil
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.PRIORITY_DEFAULT
import io.heckel.ntfy.util.topicUrl
import io.heckel.ntfy.util.topicUrlAuth
import io.heckel.ntfy.util.topicUrlJson
import io.heckel.ntfy.util.topicUrlJsonPoll
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.db.User
import com.centralcloud.oncall.service.NotAuthorizedException
import com.centralcloud.oncall.util.ALL_PRIORITIES
import com.centralcloud.oncall.util.HttpUtil
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.PRIORITY_DEFAULT
import com.centralcloud.oncall.util.topicUrl
import com.centralcloud.oncall.util.topicUrlAuth
import com.centralcloud.oncall.util.topicUrlJson
import com.centralcloud.oncall.util.topicUrlJsonPoll
import okhttp3.Call
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
@ -197,7 +197,7 @@ class ApiService(private val context: Context) {
)
companion object {
private const val TAG = "NtfyApiService"
private const val TAG = "OncallApiService"
// These constants have corresponding values in the server codebase!
const val CONTROL_TOPIC = "~control"

View file

@ -1,13 +1,13 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import android.content.Context
import android.content.Intent
import io.heckel.ntfy.R
import io.heckel.ntfy.db.Action
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.util.*
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.Action
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@ -120,12 +120,12 @@ class BroadcastService(private val ctx: Context) {
}
companion object {
private const val TAG = "NtfyBroadcastService"
private const val TAG = "OncallBroadcastService"
private const val DOES_NOT_EXIST = -2586000
// These constants cannot be changed without breaking the contract; also see manifest
private const val MESSAGE_RECEIVED_ACTION = "io.heckel.ntfy.MESSAGE_RECEIVED"
private const val MESSAGE_SEND_ACTION = "io.heckel.ntfy.SEND_MESSAGE"
private const val USER_ACTION_ACTION = "io.heckel.ntfy.USER_ACTION"
private const val MESSAGE_RECEIVED_ACTION = "com.centralcloud.oncall.MESSAGE_RECEIVED"
private const val MESSAGE_SEND_ACTION = "com.centralcloud.oncall.SEND_MESSAGE"
private const val USER_ACTION_ACTION = "com.centralcloud.oncall.USER_ACTION"
}
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import android.content.Context
import android.net.Uri
@ -9,21 +9,21 @@ import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.db.ATTACHMENT_PROGRESS_DONE
import io.heckel.ntfy.db.ATTACHMENT_PROGRESS_FAILED
import io.heckel.ntfy.db.ATTACHMENT_PROGRESS_INDETERMINATE
import io.heckel.ntfy.db.ATTACHMENT_PROGRESS_NONE
import io.heckel.ntfy.db.Attachment
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.util.HttpUtil
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.ensureSafeNewFile
import io.heckel.ntfy.util.extractBaseUrl
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.R
import com.centralcloud.oncall.app.Application
import com.centralcloud.oncall.db.ATTACHMENT_PROGRESS_DONE
import com.centralcloud.oncall.db.ATTACHMENT_PROGRESS_FAILED
import com.centralcloud.oncall.db.ATTACHMENT_PROGRESS_INDETERMINATE
import com.centralcloud.oncall.db.ATTACHMENT_PROGRESS_NONE
import com.centralcloud.oncall.db.Attachment
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.util.HttpUtil
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.ensureSafeNewFile
import com.centralcloud.oncall.util.extractBaseUrl
import okhttp3.Response
import java.io.File
import kotlin.coroutines.cancellation.CancellationException
@ -209,7 +209,7 @@ class DownloadAttachmentWorker(private val context: Context, params: WorkerParam
const val INPUT_DATA_USER_ACTION = "userAction"
const val FILE_PROVIDER_AUTHORITY = BuildConfig.APPLICATION_ID + ".provider" // See AndroidManifest.xml
private const val TAG = "NtfyAttachDownload"
private const val TAG = "OncallAttachDownload"
private const val ATTACHMENT_CACHE_DIR = "attachments"
private const val BUFFER_SIZE = 8 * 1024
private const val NOTIFICATION_UPDATE_INTERVAL_MILLIS = 800

View file

@ -1,20 +1,20 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import android.content.Context
import android.net.Uri
import androidx.core.content.FileProvider
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.db.Icon
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.util.HttpUtil
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.extractBaseUrl
import io.heckel.ntfy.util.sha256
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.app.Application
import com.centralcloud.oncall.db.Icon
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.util.HttpUtil
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.extractBaseUrl
import com.centralcloud.oncall.util.sha256
import okhttp3.Response
import java.io.File
import java.util.Date
@ -163,7 +163,7 @@ class DownloadIconWorker(private val context: Context, params: WorkerParameters)
const val MAX_CACHE_MILLIS = 1000*60*60*24 // 24 hours
const val ICON_CACHE_DIR = "icons"
private const val TAG = "NtfyIconDownload"
private const val TAG = "OncallIconDownload"
private const val BUFFER_SIZE = 8 * 1024
}
}

View file

@ -1,11 +1,11 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import android.content.Context
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import androidx.work.workDataOf
import io.heckel.ntfy.util.Log
import com.centralcloud.oncall.util.Log
/**
* Download attachment in the background via WorkManager
@ -14,10 +14,10 @@ import io.heckel.ntfy.util.Log
* in a doze state and Internet may not be available. It's also best practice, apparently.
*/
object DownloadManager {
private const val TAG = "NtfyDownloadManager"
private const val DOWNLOAD_WORK_ATTACHMENT_NAME_PREFIX = "io.heckel.ntfy.DOWNLOAD_FILE_"
private const val DOWNLOAD_WORK_ICON_NAME_PREFIX = "io.heckel.ntfy.DOWNLOAD_ICON_"
private const val DOWNLOAD_WORK_BOTH_NAME_PREFIX = "io.heckel.ntfy.DOWNLOAD_BOTH_"
private const val TAG = "OncallDownloadManager"
private const val DOWNLOAD_WORK_ATTACHMENT_NAME_PREFIX = "com.centralcloud.oncall.DOWNLOAD_FILE_"
private const val DOWNLOAD_WORK_ICON_NAME_PREFIX = "com.centralcloud.oncall.DOWNLOAD_ICON_"
private const val DOWNLOAD_WORK_BOTH_NAME_PREFIX = "com.centralcloud.oncall.DOWNLOAD_BOTH_"
fun enqueue(context: Context, notificationId: String, userAction: Boolean, type: DownloadType) {
when (type) {

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName

View file

@ -1,13 +1,13 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import android.content.Context
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.up.Distributor
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.decodeBytesMessage
import io.heckel.ntfy.util.safeLet
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.up.Distributor
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.decodeBytesMessage
import com.centralcloud.oncall.util.safeLet
/**
* The notification dispatcher figures out what to do with a notification.
@ -114,6 +114,6 @@ class NotificationDispatcher(val context: Context, val repository: Repository) {
}
companion object {
private const val TAG = "NtfyNotifDispatch"
private const val TAG = "OncallNotifDispatch"
}
}

View file

@ -1,14 +1,14 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import io.heckel.ntfy.db.Action
import io.heckel.ntfy.db.Attachment
import io.heckel.ntfy.db.Icon
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.util.deriveNotificationId
import io.heckel.ntfy.util.joinTags
import io.heckel.ntfy.util.toPriority
import com.centralcloud.oncall.db.Action
import com.centralcloud.oncall.db.Attachment
import com.centralcloud.oncall.db.Icon
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.util.deriveNotificationId
import com.centralcloud.oncall.util.joinTags
import com.centralcloud.oncall.util.toPriority
import java.lang.reflect.Type
class NotificationParser {

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import android.app.*
import android.content.ActivityNotFoundException
@ -12,13 +12,13 @@ import android.net.Uri
import android.os.Bundle
import android.widget.Toast
import androidx.core.app.NotificationCompat
import io.heckel.ntfy.R
import io.heckel.ntfy.db.*
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.ui.Colors
import io.heckel.ntfy.ui.DetailActivity
import io.heckel.ntfy.ui.MainActivity
import io.heckel.ntfy.util.*
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.*
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.ui.Colors
import com.centralcloud.oncall.ui.DetailActivity
import com.centralcloud.oncall.ui.MainActivity
import com.centralcloud.oncall.util.*
import java.util.*
import androidx.core.net.toUri
import kotlinx.coroutines.launch
@ -500,7 +500,7 @@ class NotificationService(val context: Context) {
// Mark notification as read; We can't use lifecycleScope here, because we
// call finish() right after, so we do this awkward ioScope thing.
if (subscriptionId != 0L && sequenceId.isNotEmpty()) {
val app = applicationContext as io.heckel.ntfy.app.Application
val app = applicationContext as com.centralcloud.oncall.app.Application
app.ioScope.launch {
val repository = Repository.getInstance(app)
repository.markAsReadBySequenceId(subscriptionId, sequenceId)
@ -529,14 +529,14 @@ class NotificationService(val context: Context) {
const val BROADCAST_EXTRA_NOTIFICATION_ID = "notificationId"
const val BROADCAST_EXTRA_ACTION_ID = "actionId"
const val BROADCAST_TYPE_DOWNLOAD_START = "io.heckel.ntfy.DOWNLOAD_ACTION_START"
const val BROADCAST_TYPE_DOWNLOAD_CANCEL = "io.heckel.ntfy.DOWNLOAD_ACTION_CANCEL"
const val BROADCAST_TYPE_USER_ACTION = "io.heckel.ntfy.USER_ACTION_RUN"
const val BROADCAST_TYPE_DOWNLOAD_START = "com.centralcloud.oncall.DOWNLOAD_ACTION_START"
const val BROADCAST_TYPE_DOWNLOAD_CANCEL = "com.centralcloud.oncall.DOWNLOAD_ACTION_CANCEL"
const val BROADCAST_TYPE_USER_ACTION = "com.centralcloud.oncall.USER_ACTION_RUN"
private const val TAG = "NtfyNotifService"
private const val TAG = "OncallNotifService"
const val DEFAULT_GROUP = "ntfy"
private const val SUBSCRIPTION_GROUP_PREFIX = "ntfy-subscription-"
const val DEFAULT_GROUP = "oncall"
private const val SUBSCRIPTION_GROUP_PREFIX = "oncall-subscription-"
private const val GROUP_SUFFIX_PRIORITY_MIN = "-min"
private const val GROUP_SUFFIX_PRIORITY_LOW = "-low"
private const val GROUP_SUFFIX_PRIORITY_DEFAULT = ""

View file

@ -1,9 +1,9 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.util.Log
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.util.Log
/**
* Polls the server for notifications and updates the repository.
@ -72,6 +72,6 @@ class Poller(
}
companion object {
private const val TAG = "NtfyPoller"
private const val TAG = "OncallPoller"
}
}

View file

@ -1,11 +1,11 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import android.content.Context
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import androidx.work.workDataOf
import io.heckel.ntfy.util.Log
import com.centralcloud.oncall.util.Log
/**
* Trigger user actions clicked from notification popups.
@ -14,8 +14,8 @@ import io.heckel.ntfy.util.Log
* in a doze state and Internet may not be available. It's also best practice, apparently.
*/
object UserActionManager {
private const val TAG = "NtfyUserActionEx"
private const val WORK_NAME_PREFIX = "io.heckel.ntfy.USER_ACTION_"
private const val TAG = "OncallUserActionEx"
private const val WORK_NAME_PREFIX = "com.centralcloud.oncall.USER_ACTION_"
fun enqueue(context: Context, notificationId: String, actionId: String) {
val workManager = WorkManager.getInstance(context)

View file

@ -1,24 +1,24 @@
package io.heckel.ntfy.msg
package com.centralcloud.oncall.msg
import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.db.ACTION_PROGRESS_FAILED
import io.heckel.ntfy.db.ACTION_PROGRESS_ONGOING
import io.heckel.ntfy.db.ACTION_PROGRESS_SUCCESS
import io.heckel.ntfy.db.Action
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.msg.NotificationService.Companion.ACTION_BROADCAST
import io.heckel.ntfy.msg.NotificationService.Companion.ACTION_COPY
import io.heckel.ntfy.msg.NotificationService.Companion.ACTION_HTTP
import io.heckel.ntfy.util.HttpUtil
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.copyToClipboard
import io.heckel.ntfy.util.extractBaseUrl
import com.centralcloud.oncall.R
import com.centralcloud.oncall.app.Application
import com.centralcloud.oncall.db.ACTION_PROGRESS_FAILED
import com.centralcloud.oncall.db.ACTION_PROGRESS_ONGOING
import com.centralcloud.oncall.db.ACTION_PROGRESS_SUCCESS
import com.centralcloud.oncall.db.Action
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.msg.NotificationService.Companion.ACTION_BROADCAST
import com.centralcloud.oncall.msg.NotificationService.Companion.ACTION_COPY
import com.centralcloud.oncall.msg.NotificationService.Companion.ACTION_HTTP
import com.centralcloud.oncall.util.HttpUtil
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.copyToClipboard
import com.centralcloud.oncall.util.extractBaseUrl
import okhttp3.RequestBody.Companion.toRequestBody
import java.util.Locale
@ -122,6 +122,6 @@ class UserActionWorker(private val context: Context, params: WorkerParameters) :
const val INPUT_DATA_ACTION_ID = "actionId"
private const val DEFAULT_HTTP_ACTION_METHOD = "POST" // Cannot be changed without changing the contract
private const val TAG = "NtfyUserActWrk"
private const val TAG = "OncallUserActWrk"
}
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.service
package com.centralcloud.oncall.service
import okhttp3.internal.http2.StreamResetException
import java.io.EOFException

View file

@ -1,14 +1,14 @@
package io.heckel.ntfy.service
package com.centralcloud.oncall.service
import io.heckel.ntfy.db.ConnectionState
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.db.User
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.msg.NotificationParser
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.topicUrl
import com.centralcloud.oncall.db.ConnectionState
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.db.User
import com.centralcloud.oncall.msg.ApiService
import com.centralcloud.oncall.msg.NotificationParser
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.topicUrl
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
@ -93,7 +93,7 @@ class JsonConnection(
}
companion object {
private const val TAG = "NtfyJsonConnection"
private const val TAG = "OncallJsonConnection"
private val RETRY_SECONDS = listOf(5, 10, 15, 20, 30, 45, 60, 120)
}
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.service
package com.centralcloud.oncall.service
import android.app.AlarmManager
import android.app.ForegroundServiceStartNotAllowedException
@ -17,21 +17,21 @@ import android.os.PowerManager
import android.os.SystemClock
import android.widget.Toast
import androidx.core.app.NotificationCompat
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.db.ConnectionState
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.msg.NotificationDispatcher
import io.heckel.ntfy.ui.Colors
import io.heckel.ntfy.ui.MainActivity
import io.heckel.ntfy.util.HttpUtil
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.isNetworkAvailable
import io.heckel.ntfy.util.shortUrl
import io.heckel.ntfy.util.topicUrl
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.R
import com.centralcloud.oncall.app.Application
import com.centralcloud.oncall.db.ConnectionState
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.msg.ApiService
import com.centralcloud.oncall.msg.NotificationDispatcher
import com.centralcloud.oncall.ui.Colors
import com.centralcloud.oncall.ui.MainActivity
import com.centralcloud.oncall.util.HttpUtil
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.isNetworkAvailable
import com.centralcloud.oncall.util.shortUrl
import com.centralcloud.oncall.util.topicUrl
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@ -54,7 +54,7 @@ import java.util.concurrent.ConcurrentHashMap
* a one-off AutoRestartWorker to restart the service (this is weird, but necessary because services started from
* receivers are apparently low priority, see the gist below for details)
* - The MainActivity schedules a periodic worker (AutoRestartWorker) which restarts the service
* - FCM receives keepalive message from the main ntfy.sh server, which broadcasts an intent to AutoRestartReceiver,
* - FCM receives keepalive message from the main oncall.hugo.dk server, which broadcasts an intent to AutoRestartReceiver,
* which will schedule a one-off AutoRestartWorker to restart the service (see above)
* - On boot, the BootStartReceiver is triggered to restart the service (see AndroidManifest.xml)
*
@ -392,7 +392,7 @@ class SubscriberService : Service() {
notificationManager?.notify(NOTIFICATION_CONNECTION_ALERT_ID, notification)
}
private fun onNotificationReceived(subscription: Subscription, notification: io.heckel.ntfy.db.Notification) {
private fun onNotificationReceived(subscription: Subscription, notification: com.centralcloud.oncall.db.Notification) {
// Wakelock while notifications are being dispatched
// Wakelocks are reference counted by default so that should work neatly here
wakeLock?.acquire(NOTIFICATION_RECEIVED_WAKELOCK_TIMEOUT_MILLIS)
@ -527,17 +527,17 @@ class SubscriberService : Service() {
}
companion object {
const val TAG = "NtfySubscriberService"
const val TAG = "OncallSubscriberService"
const val SERVICE_START_WORKER_VERSION = BuildConfig.VERSION_CODE
const val SERVICE_START_WORKER_WORK_NAME_PERIODIC = "NtfyAutoRestartWorkerPeriodic" // Do not change!
const val SERVICE_START_WORKER_WORK_NAME_PERIODIC = "OncallAutoRestartWorkerPeriodic" // Do not change!
private const val ONE_HOUR_SECONDS = 60 * 60L
private const val ONE_HOUR_MILLIS = ONE_HOUR_SECONDS * 1000L
private const val WAKE_LOCK_TAG = "SubscriberService:lock"
private const val NOTIFICATION_CHANNEL_ID = "ntfy-subscriber"
private const val NOTIFICATION_CONNECTION_ALERT_CHANNEL_ID = "ntfy-connection-alert"
private const val NOTIFICATION_GROUP_ID = "io.heckel.ntfy.NOTIFICATION_GROUP_SERVICE"
private const val NOTIFICATION_CHANNEL_ID = "oncall-subscriber"
private const val NOTIFICATION_CONNECTION_ALERT_CHANNEL_ID = "oncall-connection-alert"
private const val NOTIFICATION_GROUP_ID = "com.centralcloud.oncall.NOTIFICATION_GROUP_SERVICE"
private const val NOTIFICATION_SERVICE_ID = 2586
private const val NOTIFICATION_RECEIVED_WAKELOCK_TIMEOUT_MILLIS = 10 * 60 * 1000L /*10 minutes*/
@ -546,10 +546,10 @@ class SubscriberService : Service() {
private const val CONNECTION_ALERT_SNOOZE_SHORT_MILLIS = CONNECTION_ALERT_SNOOZE_SHORT_HOURS * ONE_HOUR_MILLIS
private const val CONNECTION_ALERT_SNOOZE_LONG_HOURS = 8
private const val CONNECTION_ALERT_SNOOZE_LONG_MILLIS = CONNECTION_ALERT_SNOOZE_LONG_HOURS * ONE_HOUR_MILLIS
private const val CONNECTION_ALERT_ACTION_DISMISS = "io.heckel.ntfy.CONNECTION_ALERT_DISMISS"
private const val CONNECTION_ALERT_ACTION_SNOOZE_SHORT = "io.heckel.ntfy.CONNECTION_ALERT_SNOOZE_SHORT"
private const val CONNECTION_ALERT_ACTION_SNOOZE_LONG = "io.heckel.ntfy.CONNECTION_ALERT_SNOOZE_LONG"
private const val CONNECTION_ALERT_ACTION_NEVER = "io.heckel.ntfy.CONNECTION_ALERT_NEVER"
private const val CONNECTION_ALERT_ACTION_DISMISS = "com.centralcloud.oncall.CONNECTION_ALERT_DISMISS"
private const val CONNECTION_ALERT_ACTION_SNOOZE_SHORT = "com.centralcloud.oncall.CONNECTION_ALERT_SNOOZE_SHORT"
private const val CONNECTION_ALERT_ACTION_SNOOZE_LONG = "com.centralcloud.oncall.CONNECTION_ALERT_SNOOZE_LONG"
private const val CONNECTION_ALERT_ACTION_NEVER = "com.centralcloud.oncall.CONNECTION_ALERT_NEVER"
// Unique request codes for connection alert PendingIntents. These must be distinct so
// that each PendingIntent is treated as a separate entry by the system.

View file

@ -1,13 +1,13 @@
package io.heckel.ntfy.service
package com.centralcloud.oncall.service
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import androidx.core.content.ContextCompat
import androidx.work.*
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.isNetworkAvailable
import com.centralcloud.oncall.app.Application
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.isNetworkAvailable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@ -75,7 +75,7 @@ class SubscriberServiceManager(private val context: Context) {
// killed by the OS while the service was stopped, because WorkManager /
// JobScheduler is tied to the platform's connectivity monitor. Without this,
// recovery when offline->online happens after process death would only occur
// via the periodic NtfyAutoRestartWorkerPeriodic worker (up to ~30 minutes).
// via the periodic OncallAutoRestartWorkerPeriodic worker (up to ~30 minutes).
// Doze mode may still defer the job until the next maintenance window, but
// users with instant delivery are prompted to disable battery optimization.
if (instantSubscriptions > 0) {
@ -98,7 +98,7 @@ class SubscriberServiceManager(private val context: Context) {
}
companion object {
const val TAG = "NtfySubscriberMgr"
const val TAG = "OncallSubscriberMgr"
const val WORK_NAME_ONCE = "ServiceStartWorkerOnce"
const val WORK_NAME_ON_NETWORK_AVAILABLE = "ServiceStartWorkerOnNetworkAvailable"

View file

@ -1,19 +1,19 @@
package io.heckel.ntfy.service
package com.centralcloud.oncall.service
import android.app.AlarmManager
import android.os.Build
import io.heckel.ntfy.db.ConnectionState
import io.heckel.ntfy.db.CustomHeader
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.db.User
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.msg.NotificationParser
import io.heckel.ntfy.util.HttpUtil
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.topicShortUrl
import io.heckel.ntfy.util.topicUrlWs
import com.centralcloud.oncall.db.ConnectionState
import com.centralcloud.oncall.db.CustomHeader
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.db.User
import com.centralcloud.oncall.msg.ApiService
import com.centralcloud.oncall.msg.NotificationParser
import com.centralcloud.oncall.util.HttpUtil
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.topicShortUrl
import com.centralcloud.oncall.util.topicUrlWs
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
@ -27,7 +27,7 @@ import java.util.Calendar
import java.util.concurrent.atomic.AtomicLong
/**
* Connect to ntfy server via WebSockets. This connection represents a single connection to a server, with
* Connect to oncall server via WebSockets. This connection represents a single connection to a server, with
* one or more topics. When the topics are changed, the connection is recreated by the service.
*
* The connection re-connects on failure, indefinitely. It reports limited status via the stateChangeListener,
@ -216,7 +216,7 @@ class WsConnection(
}
companion object {
private const val TAG = "NtfyWsConnection"
private const val TAG = "OncallWsConnection"
private const val RECONNECT_TAG = "WsReconnect"
private const val WS_CLOSE_NORMAL = 1000
private val RETRY_SECONDS = listOf(5, 10, 15, 20, 30, 45, 60, 120)

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.sms
package com.centralcloud.oncall.sms
import android.app.NotificationManager
import android.content.Context
@ -17,7 +17,7 @@ import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import io.heckel.ntfy.util.HttpUtil
import com.centralcloud.oncall.util.HttpUtil
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.sms
package com.centralcloud.oncall.sms
import android.content.Context
import android.util.Log
@ -6,7 +6,7 @@ import androidx.work.Constraints
import androidx.work.CoroutineWorker
import androidx.work.NetworkType
import androidx.work.WorkerParameters
import io.heckel.ntfy.util.HttpUtil
import com.centralcloud.oncall.util.HttpUtil
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.sms
package com.centralcloud.oncall.sms
import android.content.Context

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.sms
package com.centralcloud.oncall.sms
import android.content.Context
import android.content.SharedPreferences

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.sms
package com.centralcloud.oncall.sms
import android.content.BroadcastReceiver
import android.content.Context

View file

@ -1,10 +1,10 @@
package io.heckel.ntfy.sms
package com.centralcloud.oncall.sms
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import io.heckel.ntfy.R
import com.centralcloud.oncall.R
import java.text.DateFormat
import java.util.Date
@ -15,14 +15,14 @@ import java.util.Date
* its own pattern of inner-fragment classes) to keep this PR self-contained.
* Launch it via adb during bring-up:
*
* adb shell am start -n io.heckel.ntfy/.sms.SmsRelaySettingsActivity
* adb shell am start -n com.centralcloud.oncall/.sms.SmsRelaySettingsActivity
*
* Once the broader settings nav is ready, a Preference entry in
* main_preferences.xml can deep-link here with:
*
* <Preference
* app:title="SMS Relay"
* app:fragment="io.heckel.ntfy.sms.SmsRelaySettingsActivity$Fragment"/>
* app:fragment="com.centralcloud.oncall.sms.SmsRelaySettingsActivity$Fragment"/>
*
* Requires a `<activity>` entry in AndroidManifest.xml added together with
* the SmsRelayReceiver registration in the pending manifest commit.

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.app.Activity
import android.app.Dialog
@ -14,13 +14,13 @@ import androidx.lifecycle.lifecycleScope
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.User
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.util.CertUtil
import io.heckel.ntfy.util.*
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.User
import com.centralcloud.oncall.msg.ApiService
import com.centralcloud.oncall.util.CertUtil
import com.centralcloud.oncall.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import androidx.core.view.isVisible
@ -511,7 +511,7 @@ class AddFragment : DialogFragment(), TrustedCertificateFragment.TrustedCertific
}
companion object {
const val TAG = "NtfyAddFragment"
const val TAG = "OncallAddFragment"
private val DISALLOWED_TOPICS = listOf("docs", "static", "file") // If updated, also update in server
}
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.os.Bundle
import android.view.View
@ -13,7 +13,7 @@ import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText
import io.heckel.ntfy.R
import com.centralcloud.oncall.R
abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View file

@ -1,11 +1,11 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.text.Editable
import android.text.TextWatcher
import android.widget.ArrayAdapter
import android.widget.AutoCompleteTextView
import com.google.android.material.textfield.TextInputLayout
import io.heckel.ntfy.R
import com.centralcloud.oncall.R
fun initBaseUrlDropdown(baseUrls: List<String>, textView: AutoCompleteTextView, layout: TextInputLayout) {
// Base URL dropdown behavior; Oh my, why is this so complicated?!

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.net.Uri
import android.os.Bundle
@ -7,13 +7,13 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import io.heckel.ntfy.R
import io.heckel.ntfy.db.ClientCertificate
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.TrustedCertificate
import io.heckel.ntfy.util.CertUtil
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.shortUrl
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.ClientCertificate
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.TrustedCertificate
import com.centralcloud.oncall.util.CertUtil
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.shortUrl
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.security.cert.X509Certificate
@ -205,6 +205,6 @@ class CertificateSettingsFragment : BasePreferenceFragment(),
}
companion object {
private const val TAG = "NtfyCertSettingsFragment"
private const val TAG = "OncallCertSettingsFragment"
}
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.app.Dialog
import android.content.Context
@ -16,11 +16,11 @@ import androidx.lifecycle.lifecycleScope
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import io.heckel.ntfy.R
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.util.AfterChangedTextWatcher
import io.heckel.ntfy.util.CertUtil
import io.heckel.ntfy.util.validUrl
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.util.AfterChangedTextWatcher
import com.centralcloud.oncall.util.CertUtil
import com.centralcloud.oncall.util.validUrl
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -346,7 +346,7 @@ class ClientCertificateFragment : DialogFragment() {
}
companion object {
const val TAG = "NtfyClientCertFragment"
const val TAG = "OncallClientCertFragment"
private const val ARG_MODE = "mode"
private const val ARG_PKCS12_DATA = "pkcs12_data"
private const val ARG_BASE_URL = "base_url"

View file

@ -1,11 +1,11 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.content.Context
import android.graphics.Color
import androidx.core.content.ContextCompat
import com.google.android.material.color.MaterialColors
import io.heckel.ntfy.R
import io.heckel.ntfy.util.isDarkThemeOn
import com.centralcloud.oncall.R
import com.centralcloud.oncall.util.isDarkThemeOn
class Colors {
companion object {

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.app.Dialog
import android.graphics.Color
@ -16,12 +16,12 @@ import androidx.fragment.app.DialogFragment
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.color.MaterialColors
import com.google.android.material.textfield.TextInputLayout
import io.heckel.ntfy.R
import io.heckel.ntfy.db.ConnectionDetails
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.service.SubscriberServiceManager
import io.heckel.ntfy.util.copyToClipboard
import io.heckel.ntfy.util.shortUrl
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.ConnectionDetails
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.service.SubscriberServiceManager
import com.centralcloud.oncall.util.copyToClipboard
import com.centralcloud.oncall.util.shortUrl
class ConnectionErrorFragment : DialogFragment() {
private lateinit var repository: Repository
@ -258,7 +258,7 @@ class ConnectionErrorFragment : DialogFragment() {
}
companion object {
const val TAG = "NtfyConnectionErrorFragment"
const val TAG = "OncallConnectionErrorFragment"
private const val ARG_BASE_URL = "base_url"
fun newInstance(baseUrl: String? = null): ConnectionErrorFragment {

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.app.Dialog
import android.content.Context
@ -12,11 +12,11 @@ import androidx.fragment.app.DialogFragment
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import io.heckel.ntfy.R
import io.heckel.ntfy.db.CustomHeader
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.util.AfterChangedTextWatcher
import io.heckel.ntfy.util.validUrl
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.CustomHeader
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.util.AfterChangedTextWatcher
import com.centralcloud.oncall.util.validUrl
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -232,7 +232,7 @@ class CustomHeaderFragment : DialogFragment() {
}
private fun isReservedHeader(name: String): Boolean {
// These headers are already set by ntfy and cannot be overridden
// These headers are already set by oncall and cannot be overridden
val nameLower = name.lowercase()
val reservedHeaders = setOf(
"user-agent",
@ -271,7 +271,7 @@ class CustomHeaderFragment : DialogFragment() {
}
companion object {
const val TAG = "NtfyCustomHeaderFragment"
const val TAG = "OncallCustomHeaderFragment"
private const val BUNDLE_BASE_URL = "baseUrl"
private const val BUNDLE_HEADER_NAME = "headerName"
private const val BUNDLE_HEADER_VALUE = "headerValue"

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.app.Dialog
import android.content.Context
@ -10,10 +10,10 @@ import androidx.fragment.app.DialogFragment
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import io.heckel.ntfy.R
import io.heckel.ntfy.util.AfterChangedTextWatcher
import io.heckel.ntfy.util.normalizeBaseUrl
import io.heckel.ntfy.util.validBaseUrl
import com.centralcloud.oncall.R
import com.centralcloud.oncall.util.AfterChangedTextWatcher
import com.centralcloud.oncall.util.normalizeBaseUrl
import com.centralcloud.oncall.util.validBaseUrl
class DefaultServerFragment : DialogFragment() {
private var currentUrl: String? = null
@ -149,7 +149,7 @@ class DefaultServerFragment : DialogFragment() {
}
companion object {
const val TAG = "NtfyDefaultServerFragment"
const val TAG = "OncallDefaultServerFragment"
private const val BUNDLE_CURRENT_URL = "currentUrl"
fun newInstance(currentUrl: String?): DefaultServerFragment {

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.app.AlertDialog
import android.content.Intent
@ -30,27 +30,27 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.firebase.FirebaseMessenger
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.msg.NotificationService
import io.heckel.ntfy.msg.Poller
import io.heckel.ntfy.service.SubscriberServiceManager
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.copyToClipboard
import io.heckel.ntfy.util.dangerButton
import io.heckel.ntfy.util.decodeMessage
import io.heckel.ntfy.util.displayName
import io.heckel.ntfy.util.formatDateShort
import io.heckel.ntfy.util.isDarkThemeOn
import io.heckel.ntfy.util.randomSubscriptionId
import io.heckel.ntfy.util.topicShortUrl
import io.heckel.ntfy.util.topicUrl
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.R
import com.centralcloud.oncall.app.Application
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.firebase.FirebaseMessenger
import com.centralcloud.oncall.msg.ApiService
import com.centralcloud.oncall.msg.NotificationService
import com.centralcloud.oncall.msg.Poller
import com.centralcloud.oncall.service.SubscriberServiceManager
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.copyToClipboard
import com.centralcloud.oncall.util.dangerButton
import com.centralcloud.oncall.util.decodeMessage
import com.centralcloud.oncall.util.displayName
import com.centralcloud.oncall.util.formatDateShort
import com.centralcloud.oncall.util.isDarkThemeOn
import com.centralcloud.oncall.util.randomSubscriptionId
import com.centralcloud.oncall.util.topicShortUrl
import com.centralcloud.oncall.util.topicUrl
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
@ -186,11 +186,11 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
// Show 'Back' button
supportActionBar?.setDisplayHomeAsUpEnabled(true)
// Hide links that lead to payments, see https://github.com/binwiederhier/ntfy/issues/1463
// Hide links that lead to payments, see https://github.com/binwiederhier/oncall/issues/1463
val howToLink = findViewById<TextView>(R.id.detail_how_to_link)
howToLink.isVisible = BuildConfig.PAYMENT_LINKS_AVAILABLE
// Handle direct deep links to topic "ntfy://..."
// Handle direct deep links to topic "oncall://..."
val url = intent?.data
if (intent?.action == ACTION_VIEW && url != null) {
maybeSubscribeAndLoadView(url)
@ -238,7 +238,7 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
)
repository.addSubscription(subscription)
// Subscribe to Firebase topic if ntfy.sh (even if instant, just to be sure!)
// Subscribe to Firebase topic if oncall.hugo.dk (even if instant, just to be sure!)
if (baseUrl == appBaseUrl) {
Log.d(TAG, "Subscribing to Firebase topic $topic")
messenger.subscribe(topic)
@ -853,7 +853,7 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
private fun showHideCopyMenuItems() {
if (!this::menu.isInitialized) return
runOnUiThread {
// Hide links that lead to payments, see https://github.com/binwiederhier/ntfy/issues/1463
// Hide links that lead to payments, see https://github.com/binwiederhier/oncall/issues/1463
val copyUrlItem = menu.findItem(R.id.detail_menu_copy_url)
copyUrlItem?.isVisible = !isSearchActive && (appBaseUrl != subscriptionBaseUrl || BuildConfig.PAYMENT_LINKS_AVAILABLE)
}
@ -1023,7 +1023,7 @@ class DetailActivity : AppCompatActivity(), NotificationFragment.NotificationSet
}
companion object {
const val TAG = "NtfyDetailActivity"
const val TAG = "OncallDetailActivity"
const val EXTRA_SUBSCRIPTION_ID = "subscriptionId"
const val EXTRA_SUBSCRIPTION_BASE_URL = "baseUrl"
const val EXTRA_SUBSCRIPTION_TOPIC = "topic"

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.Manifest
import android.app.Activity
@ -26,15 +26,15 @@ import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.google.android.material.button.MaterialButton
import com.stfalcon.imageviewer.StfalconImageViewer
import io.heckel.ntfy.R
import io.heckel.ntfy.db.*
import io.heckel.ntfy.msg.DownloadAttachmentWorker
import io.heckel.ntfy.msg.DownloadManager
import io.heckel.ntfy.msg.DownloadType
import io.heckel.ntfy.msg.NotificationService
import io.heckel.ntfy.msg.NotificationService.Companion.ACTION_COPY
import io.heckel.ntfy.msg.NotificationService.Companion.ACTION_VIEW
import io.heckel.ntfy.util.*
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.*
import com.centralcloud.oncall.msg.DownloadAttachmentWorker
import com.centralcloud.oncall.msg.DownloadManager
import com.centralcloud.oncall.msg.DownloadType
import com.centralcloud.oncall.msg.NotificationService
import com.centralcloud.oncall.msg.NotificationService.Companion.ACTION_COPY
import com.centralcloud.oncall.msg.NotificationService.Companion.ACTION_VIEW
import com.centralcloud.oncall.util.*
import io.noties.markwon.Markwon
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -128,7 +128,7 @@ class DetailAdapter(private val activity: Activity, private val lifecycleScope:
// Click & Long-click listeners on the text as well, because "autoLink=web" makes them
// clickable, and so we cannot rely on the underlying card to perform the action.
// It's weird because "layout" is the ripple-able, but the card is clickable.
// See https://github.com/binwiederhier/ntfy/issues/226
// See https://github.com/binwiederhier/oncall/issues/226
layout.ripple(lifecycleScope)
onClick(notification)
}
@ -568,7 +568,7 @@ class DetailAdapter(private val activity: Activity, private val lifecycleScope:
}
companion object {
const val TAG = "NtfyDetailAdapter"
const val TAG = "OncallDetailAdapter"
const val REQUEST_CODE_WRITE_STORAGE_PERMISSION_FOR_DOWNLOAD = 9876
const val IMAGE_PREVIEW_MAX_BYTES = 5 * 1024 * 1024 // Too large images crash the app with "Canvas: trying to draw too large(233280000bytes) bitmap."
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.content.ContentResolver
import android.content.Intent
@ -18,14 +18,14 @@ import androidx.lifecycle.lifecycleScope
import androidx.preference.*
import androidx.preference.Preference.OnPreferenceClickListener
import com.google.android.material.appbar.AppBarLayout
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.msg.DownloadAttachmentWorker
import io.heckel.ntfy.msg.NotificationService
import io.heckel.ntfy.service.SubscriberServiceManager
import io.heckel.ntfy.util.*
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.msg.DownloadAttachmentWorker
import com.centralcloud.oncall.msg.NotificationService
import com.centralcloud.oncall.service.SubscriberServiceManager
import com.centralcloud.oncall.util.*
import kotlinx.coroutines.*
import java.io.File
import java.io.IOException
@ -525,7 +525,7 @@ class DetailSettingsActivity : AppCompatActivity() {
}
companion object {
private const val TAG = "NtfyDetailSettingsActiv"
private const val TAG = "OncallDetailSettingsActiv"
private const val SUBSCRIPTION_ICON_MAX_SIZE_BYTES = 4194304
private const val SUBSCRIPTION_ICON_MAX_WIDTH = 2048
private const val SUBSCRIPTION_ICON_MAX_HEIGHT = 2048

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@ -6,8 +6,8 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.switchMap
import androidx.lifecycle.viewModelScope
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.Manifest
import android.animation.Animator
@ -47,33 +47,33 @@ import androidx.work.WorkManager
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.floatingactionbutton.FloatingActionButton
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.firebase.FirebaseMessenger
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.msg.DownloadManager
import io.heckel.ntfy.msg.DownloadType
import io.heckel.ntfy.msg.NotificationDispatcher
import io.heckel.ntfy.msg.Poller
import io.heckel.ntfy.service.SubscriberService
import io.heckel.ntfy.service.SubscriberServiceManager
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.SUBSCRIPTION_ICONS
import io.heckel.ntfy.util.dangerButton
import io.heckel.ntfy.util.displayName
import io.heckel.ntfy.util.formatDateShort
import io.heckel.ntfy.util.isDarkThemeOn
import io.heckel.ntfy.util.isIgnoringBatteryOptimizations
import io.heckel.ntfy.util.isNetworkAvailable
import io.heckel.ntfy.util.maybeSplitTopicUrl
import io.heckel.ntfy.util.randomSubscriptionId
import io.heckel.ntfy.util.shortUrl
import io.heckel.ntfy.util.topicShortUrl
import io.heckel.ntfy.work.DeleteWorker
import io.heckel.ntfy.work.PollWorker
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.R
import com.centralcloud.oncall.app.Application
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.firebase.FirebaseMessenger
import com.centralcloud.oncall.msg.ApiService
import com.centralcloud.oncall.msg.DownloadManager
import com.centralcloud.oncall.msg.DownloadType
import com.centralcloud.oncall.msg.NotificationDispatcher
import com.centralcloud.oncall.msg.Poller
import com.centralcloud.oncall.service.SubscriberService
import com.centralcloud.oncall.service.SubscriberServiceManager
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.SUBSCRIPTION_ICONS
import com.centralcloud.oncall.util.dangerButton
import com.centralcloud.oncall.util.displayName
import com.centralcloud.oncall.util.formatDateShort
import com.centralcloud.oncall.util.isDarkThemeOn
import com.centralcloud.oncall.util.isIgnoringBatteryOptimizations
import com.centralcloud.oncall.util.isNetworkAvailable
import com.centralcloud.oncall.util.maybeSplitTopicUrl
import com.centralcloud.oncall.util.randomSubscriptionId
import com.centralcloud.oncall.util.shortUrl
import com.centralcloud.oncall.util.topicShortUrl
import com.centralcloud.oncall.work.DeleteWorker
import com.centralcloud.oncall.work.PollWorker
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -363,7 +363,7 @@ class MainActivity : AppCompatActivity(), AddFragment.SubscribeListener, Notific
}
connectivityManager.registerDefaultNetworkCallback(networkCallback!!)
// Hide links that lead to payments, see https://github.com/binwiederhier/ntfy/issues/1463
// Hide links that lead to payments, see https://github.com/binwiederhier/oncall/issues/1463
val howToLink = findViewById<TextView>(R.id.main_how_to_link)
howToLink.isVisible = BuildConfig.PAYMENT_LINKS_AVAILABLE
@ -424,7 +424,7 @@ class MainActivity : AppCompatActivity(), AddFragment.SubscribeListener, Notific
if (showBanner) {
wsBanner.visibility = View.VISIBLE
if (!BuildConfig.PAYMENT_LINKS_AVAILABLE) {
// Hide links that lead to payments, see https://github.com/binwiederhier/ntfy/issues/1463
// Hide links that lead to payments, see https://github.com/binwiederhier/oncall/issues/1463
// This is a big fat hack, but I have to release this quickly ...
val wsBannerMainText = findViewById<TextView>(R.id.main_banner_websocket_text)
val raw = getString(R.string.main_banner_websocket_text)
@ -582,8 +582,8 @@ class MainActivity : AppCompatActivity(), AddFragment.SubscribeListener, Notific
val docsItem = menu.findItem(R.id.main_menu_docs)
val reportBugItem = menu.findItem(R.id.main_menu_report_bug)
rateAppItem.isVisible = BuildConfig.RATE_APP_AVAILABLE
docsItem.isVisible = BuildConfig.PAYMENT_LINKS_AVAILABLE // Google Payments Policy, see https://github.com/binwiederhier/ntfy/issues/1463
reportBugItem.isVisible = BuildConfig.PAYMENT_LINKS_AVAILABLE // Google Payments Policy, see https://github.com/binwiederhier/ntfy/issues/1463
docsItem.isVisible = BuildConfig.PAYMENT_LINKS_AVAILABLE // Google Payments Policy, see https://github.com/binwiederhier/oncall/issues/1463
reportBugItem.isVisible = BuildConfig.PAYMENT_LINKS_AVAILABLE // Google Payments Policy, see https://github.com/binwiederhier/oncall/issues/1463
// Pause notification icons
val notificationsEnabledItem = menu.findItem(R.id.main_menu_notifications_enabled)
@ -599,7 +599,7 @@ class MainActivity : AppCompatActivity(), AddFragment.SubscribeListener, Notific
}
}
private fun showHideConnectionErrorMenuItem(details: Map<String, io.heckel.ntfy.db.ConnectionDetails>) {
private fun showHideConnectionErrorMenuItem(details: Map<String, com.centralcloud.oncall.db.ConnectionDetails>) {
if (!this::menu.isInitialized) {
return
}
@ -723,7 +723,7 @@ class MainActivity : AppCompatActivity(), AddFragment.SubscribeListener, Notific
)
viewModel.add(subscription)
// Subscribe to Firebase topic if ntfy.sh (even if instant, just to be sure!)
// Subscribe to Firebase topic if oncall.hugo.dk (even if instant, just to be sure!)
if (baseUrl == appBaseUrl) {
Log.d(TAG, "Subscribing to Firebase topic $topic")
messenger.subscribe(topic)
@ -933,7 +933,7 @@ class MainActivity : AppCompatActivity(), AddFragment.SubscribeListener, Notific
}
companion object {
const val TAG = "NtfyMainActivity"
const val TAG = "OncallMainActivity"
const val EXTRA_SUBSCRIPTION_ID = "subscriptionId"
const val EXTRA_SUBSCRIPTION_BASE_URL = "subscriptionBaseUrl"
const val EXTRA_SUBSCRIPTION_TOPIC = "subscriptionTopic"

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.content.Context
import android.graphics.Color
@ -11,13 +11,13 @@ import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.db.ConnectionState
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.util.displayName
import io.heckel.ntfy.util.readBitmapFromUriOrNull
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.ConnectionState
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.util.displayName
import com.centralcloud.oncall.util.readBitmapFromUriOrNull
import java.text.DateFormat
import java.util.*
@ -154,6 +154,6 @@ class MainAdapter(
}
companion object {
const val TAG = "NtfyMainAdapter"
const val TAG = "OncallMainAdapter"
}
}

View file

@ -1,14 +1,14 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import io.heckel.ntfy.R
import io.heckel.ntfy.db.*
import io.heckel.ntfy.firebase.FirebaseMessenger
import io.heckel.ntfy.up.Distributor
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.*
import com.centralcloud.oncall.firebase.FirebaseMessenger
import com.centralcloud.oncall.up.Distributor
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import androidx.core.net.toUri
@ -41,7 +41,7 @@ class SubscriptionsViewModel(private val repository: Repository) : ViewModel() {
// Don't care
}
}
// Unsubscribe from Firebase if this is the default ntfy.sh server
// Unsubscribe from Firebase if this is the default oncall.hugo.dk server
val appBaseUrl = context.getString(R.string.app_base_url)
if (subscription.baseUrl == appBaseUrl) {
val messenger = FirebaseMessenger()

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.app.Dialog
import android.content.Context
@ -7,8 +7,8 @@ import android.widget.RadioButton
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.heckel.ntfy.R
import io.heckel.ntfy.db.Repository
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.Repository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -92,6 +92,6 @@ class NotificationFragment : DialogFragment() {
}
companion object {
const val TAG = "NtfyNotificationFragment"
const val TAG = "OncallNotificationFragment"
}
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.content.Context
import android.view.LayoutInflater
@ -7,7 +7,7 @@ import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import io.heckel.ntfy.R
import com.centralcloud.oncall.R
data class PriorityItem(
val priority: Int,

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.app.Dialog
import android.content.Context
@ -23,7 +23,7 @@ import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.textfield.TextInputLayout
import io.heckel.ntfy.BuildConfig
import com.centralcloud.oncall.BuildConfig
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup
import com.google.android.material.textfield.TextInputEditText
@ -32,18 +32,18 @@ import okhttp3.MediaType
import okhttp3.RequestBody
import okio.BufferedSink
import okio.source
import io.heckel.ntfy.R
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.AfterChangedTextWatcher
import io.heckel.ntfy.util.formatBytes
import io.heckel.ntfy.util.mimeTypeToIconResource
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.msg.ApiService
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.AfterChangedTextWatcher
import com.centralcloud.oncall.util.formatBytes
import com.centralcloud.oncall.util.mimeTypeToIconResource
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import io.heckel.ntfy.util.ProgressRequestBody
import com.centralcloud.oncall.util.ProgressRequestBody
import okhttp3.MediaType.Companion.toMediaType
class PublishFragment : DialogFragment() {
@ -651,7 +651,7 @@ class PublishFragment : DialogFragment() {
}
companion object {
const val TAG = "NtfyPublishFragment"
const val TAG = "OncallPublishFragment"
private const val ARG_BASE_URL = "baseUrl"
private const val ARG_TOPIC = "topic"
private const val ARG_MESSAGE = "message"

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.Manifest
import android.app.AlarmManager
@ -27,15 +27,15 @@ import androidx.preference.*
import androidx.preference.Preference.OnPreferenceClickListener
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.Gson
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.backup.Backuper
import io.heckel.ntfy.db.CustomHeader
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.User
import io.heckel.ntfy.service.SubscriberServiceManager
import io.heckel.ntfy.up.Distributor
import io.heckel.ntfy.util.*
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.R
import com.centralcloud.oncall.backup.Backuper
import com.centralcloud.oncall.db.CustomHeader
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.User
import com.centralcloud.oncall.service.SubscriberServiceManager
import com.centralcloud.oncall.up.Distributor
import com.centralcloud.oncall.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.RequestBody.Companion.toRequestBody
@ -380,7 +380,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere
if (language != null) {
// We only list languages that have > 80% of strings translated.
//
// Please use Hosted Weblate (https://hosted.weblate.org/projects/ntfy/android/)
// Please use Hosted Weblate (https://hosted.weblate.org/projects/oncall/android/)
// to help translate other languages.
//
// IMPORTANT: If a language is added here, also add it to the locales_config.xml file.
@ -671,9 +671,9 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere
backupSelection = v.toString()
val timestamp = SimpleDateFormat("yyMMdd-HHmm").format(Date())
val suggestedFilename = when (backupSelection) {
BACKUP_EVERYTHING_NO_USERS -> "ntfy-backup-no-users-$timestamp.json"
BACKUP_SETTINGS_ONLY -> "ntfy-settings-$timestamp.json"
else -> "ntfy-backup-$timestamp.json"
BACKUP_EVERYTHING_NO_USERS -> "oncall-backup-no-users-$timestamp.json"
BACKUP_SETTINGS_ONLY -> "oncall-settings-$timestamp.json"
else -> "oncall-backup-$timestamp.json"
}
backupResultLauncher.launch(suggestedFilename)
false
@ -714,7 +714,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere
}
}
restore?.onPreferenceClickListener = OnPreferenceClickListener {
// Overly open mime type filter (because of https://github.com/binwiederhier/ntfy/issues/223).
// Overly open mime type filter (because of https://github.com/binwiederhier/oncall/issues/223).
// This filter could likely be stricter if we'd write the mime type properly in Backuper.backup(),
// but just in case we want to restore from a file we didn't write outselves, we'll keep this "*/*".
restoreResultLauncher.launch("*/*")
@ -752,7 +752,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere
versionPref?.summary = version
versionPref?.onPreferenceClickListener = OnPreferenceClickListener {
val context = context ?: return@OnPreferenceClickListener false
copyToClipboard(context, "ntfy version", version)
copyToClipboard(context, "oncall version", version)
true
}
}
@ -788,7 +788,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere
activity?.let { act ->
act.runOnUiThread {
val clipboard = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("ntfy logs", log)
val clip = ClipData.newPlainText("oncall logs", log)
clipboard.setPrimaryClip(clip)
if (scrub) {
showScrubDialog(getString(R.string.settings_advanced_export_logs_copied_logs))
@ -904,12 +904,12 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere
}
true
}
// Android doesn't show "ntfy" in the "Alarms & reminders" list if battery optimizations are disabled.
// Android doesn't show "oncall" in the "Alarms & reminders" list if battery optimizations are disabled.
//
// In fact, if the user has granted the battery optimization exemption (see battery banner in MainActivity),
// the alarm manager's canScheduleExactAlarms() method will return true.
//
// This is undocumented behavior. See https://github.com/binwiederhier/ntfy/issues/1456#issuecomment-3707174262
// This is undocumented behavior. See https://github.com/binwiederhier/oncall/issues/1456#issuecomment-3707174262
exactAlarmsPref?.isVisible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
&& !isIgnoringBatteryOptimizations(context)
}
@ -1110,7 +1110,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere
}
}
override fun onAddCustomHeader(dialog: DialogFragment, header: io.heckel.ntfy.db.CustomHeader) {
override fun onAddCustomHeader(dialog: DialogFragment, header: com.centralcloud.oncall.db.CustomHeader) {
lifecycleScope.launch(Dispatchers.IO) {
repository.addCustomHeader(header)
serviceManager.refresh() // Refresh to apply new headers
@ -1122,7 +1122,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere
}
}
override fun onUpdateCustomHeader(dialog: DialogFragment, oldHeader: io.heckel.ntfy.db.CustomHeader, newHeader: io.heckel.ntfy.db.CustomHeader) {
override fun onUpdateCustomHeader(dialog: DialogFragment, oldHeader: com.centralcloud.oncall.db.CustomHeader, newHeader: com.centralcloud.oncall.db.CustomHeader) {
lifecycleScope.launch(Dispatchers.IO) {
repository.updateCustomHeader(oldHeader, newHeader)
serviceManager.refresh() // Refresh to apply header changes
@ -1134,7 +1134,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere
}
}
override fun onDeleteCustomHeader(dialog: DialogFragment, header: io.heckel.ntfy.db.CustomHeader) {
override fun onDeleteCustomHeader(dialog: DialogFragment, header: com.centralcloud.oncall.db.CustomHeader) {
lifecycleScope.launch(Dispatchers.IO) {
repository.deleteCustomHeader(header)
serviceManager.refresh()
@ -1159,7 +1159,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere
}
companion object {
private const val TAG = "NtfySettingsActivity"
private const val TAG = "OncallSettingsActivity"
private const val TITLE_TAG = "title"
private const val REQUEST_CODE_WRITE_EXTERNAL_STORAGE_PERMISSION_FOR_AUTO_DOWNLOAD = 2586
private const val AUTO_DOWNLOAD_SELECTION_NOT_SET = -99L

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.content.Intent
import android.net.Uri
@ -14,10 +14,10 @@ import androidx.core.view.WindowInsetsControllerCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.textfield.TextInputLayout
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.util.*
import com.centralcloud.oncall.R
import com.centralcloud.oncall.app.Application
import com.centralcloud.oncall.msg.ApiService
import com.centralcloud.oncall.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -384,6 +384,6 @@ class ShareActivity : AppCompatActivity() {
}
companion object {
const val TAG = "NtfyShareActivity"
const val TAG = "OncallShareActivity"
}
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.app.Dialog
import android.content.Context
@ -15,11 +15,11 @@ import androidx.lifecycle.lifecycleScope
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import io.heckel.ntfy.R
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.util.AfterChangedTextWatcher
import io.heckel.ntfy.util.CertUtil
import io.heckel.ntfy.util.validUrl
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.util.AfterChangedTextWatcher
import com.centralcloud.oncall.util.CertUtil
import com.centralcloud.oncall.util.validUrl
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -386,7 +386,7 @@ class TrustedCertificateFragment : DialogFragment() {
}
companion object {
const val TAG = "NtfyTrustedCertFragment"
const val TAG = "OncallTrustedCertFragment"
private const val ARG_MODE = "mode"
private const val ARG_CERTIFICATE = "certificate"
private const val ARG_BASE_URL = "base_url"

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.ui
package com.centralcloud.oncall.ui
import android.app.Dialog
import android.content.Context
@ -12,11 +12,11 @@ import androidx.fragment.app.DialogFragment
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import io.heckel.ntfy.R
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.User
import io.heckel.ntfy.util.AfterChangedTextWatcher
import io.heckel.ntfy.util.validUrl
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.User
import com.centralcloud.oncall.util.AfterChangedTextWatcher
import com.centralcloud.oncall.util.validUrl
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -215,7 +215,7 @@ class UserFragment : DialogFragment() {
}
companion object {
const val TAG = "NtfyUserFragment"
const val TAG = "OncallUserFragment"
private const val BUNDLE_BASE_URL = "baseUrl"
private const val BUNDLE_USERNAME = "username"
private const val BUNDLE_PASSWORD = "password"

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.up
package com.centralcloud.oncall.up
import android.app.PendingIntent
import android.content.Context
@ -6,12 +6,12 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import androidx.annotation.RequiresApi
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.service.SubscriberServiceManager
import io.heckel.ntfy.util.*
import com.centralcloud.oncall.R
import com.centralcloud.oncall.app.Application
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.service.SubscriberServiceManager
import com.centralcloud.oncall.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@ -57,7 +57,7 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
}
GlobalScope.launch(Dispatchers.IO) {
// We're doing all of this inside a critical section, because of possible races.
// See https://github.com/binwiederhier/ntfy/issues/230 for details.
// See https://github.com/binwiederhier/oncall/issues/230 for details.
mutex.withLock {
val existingSubscription = repository.getSubscriptionByConnectorToken(connectorToken)
@ -99,7 +99,7 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
)
Log.d(TAG, "Adding subscription with for app $appId (connectorToken $connectorToken): $subscription")
try {
// Note, this may fail due to a SQL constraint exception, see https://github.com/binwiederhier/ntfy/issues/185
// Note, this may fail due to a SQL constraint exception, see https://github.com/binwiederhier/oncall/issues/185
repository.addSubscription(subscription)
distributor.sendEndpoint(appId, connectorToken, endpoint)
@ -201,7 +201,7 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
Log.d(TAG, "UNREGISTER received (connectorToken=$connectorToken)")
GlobalScope.launch(Dispatchers.IO) {
// We're doing all of this inside a critical section, because of possible races.
// See https://github.com/binwiederhier/ntfy/issues/230 for details.
// See https://github.com/binwiederhier/oncall/issues/230 for details.
mutex.withLock {
val existingSubscription = repository.getSubscriptionByConnectorToken(connectorToken)
@ -222,10 +222,10 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
}
companion object {
private const val TAG = "NtfyUpBroadcastRecv"
private const val TAG = "OncallUpBroadcastRecv"
private const val UP_PREFIX = "up"
private const val TOPIC_RANDOM_ID_LENGTH = 12
val mutex = Mutex() // https://github.com/binwiederhier/ntfy/issues/230
val mutex = Mutex() // https://github.com/binwiederhier/oncall/issues/230
}
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.up
package com.centralcloud.oncall.up
/**
* Constants as defined on the specs

View file

@ -1,10 +1,10 @@
package io.heckel.ntfy.up
package com.centralcloud.oncall.up
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import io.heckel.ntfy.util.Log
import com.centralcloud.oncall.util.Log
/**
* This is the UnifiedPush distributor, an amalgamation of messages to be sent as part of the spec.
@ -78,6 +78,6 @@ class Distributor(val context: Context) {
}
companion object {
private const val TAG = "NtfyUpDistributor"
private const val TAG = "OncallUpDistributor"
}
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.up
package com.centralcloud.oncall.up
/**
* A registration request may fail for different reasons.

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.up
package com.centralcloud.oncall.up
import android.app.Activity
import android.app.PendingIntent
@ -9,7 +9,7 @@ import android.util.Log
/**
* This implements the "Select default distributor" selection for UnifiedPush.
*
* To test, install ntfy and another distributor (e.g. SunUp) on the same phone.
* To test, install oncall and another distributor (e.g. SunUp) on the same phone.
* Install an app that uses UnifiedPush (e.g. UP Example) and click "Register".
*
* You should see a popup to select the default distributor.
@ -31,6 +31,6 @@ class LinkActivity: Activity() {
}
companion object {
private val TAG = "NtfyUpLinkActivity"
private val TAG = "OncallUpLinkActivity"
}
}

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.up
package com.centralcloud.oncall.up
import android.app.ActivityManager
import android.app.ActivityManager.RunningAppProcessInfo
@ -30,14 +30,14 @@ import java.util.concurrent.TimeUnit
* ## How This Works
*
* This class implements the **AND_3 specification** from UnifiedPush, which defines a mechanism
* for distributors (like ntfy) to "raise" the target application to foreground importance before
* for distributors (like oncall) to "raise" the target application to foreground importance before
* sending the push message.
*
* See: https://unifiedpush.org/developers/spec/android/#service-to-raise-to-the-foreground
*
* Here's the flow:
*
* 1. **Check ntfy's foreground status**: When ntfy receives a message for a UnifiedPush app,
* 1. **Check oncall's foreground status**: When oncall receives a message for a UnifiedPush app,
* it temporarily has foreground importance (IMPORTANCE_FOREGROUND or IMPORTANCE_FOREGROUND_SERVICE).
* The [checkForeground] method verifies this.
*
@ -45,7 +45,7 @@ import java.util.concurrent.TimeUnit
* `org.unifiedpush.android.connector.RAISE_TO_FOREGROUND`. This is checked via
* [hasRaiseToForegroundService].
*
* 3. **Bind to target's service**: If both conditions are met, ntfy binds to the target app's
* 3. **Bind to target's service**: If both conditions are met, oncall binds to the target app's
* "raise to foreground" service using [Context.bindService] with [Context.BIND_AUTO_CREATE].
* **This is the key mechanism**: when a foreground process binds to a service, the Android
* system grants foreground importance to the bound service's process. This allows the target
@ -58,18 +58,18 @@ import java.util.concurrent.TimeUnit
* messages arrive) to give the target app time to start its foreground service. After the
* timeout, the binding is released via [unbind].
*
* ## Example logs (using UP-Example app, see https://github.com/binwiederhier/ntfy-android/pull/98#issuecomment-3681330111)
* ## Example logs (using UP-Example app, see https://github.com/binwiederhier/oncall-android/pull/98#issuecomment-3681330111)
*
* ```
* NtfyUpDistributor D Sending MESSAGE to org.unifiedpush.example (token=e9830034-b97d-485d-a7f1-c8a03af9cbd2): 107 bytes
* NtfyUpRaiseFgFactory D New instance for org.unifiedpush.example
* NtfyUpRaiseFg I Found foreground process: io.heckel.ntfy.debug
* NtfyUpRaiseFg D Binding to org.unifiedpush.example
* NtfyUpRaiseFg D onServiceConnected ComponentInfo{org.unifiedpush.example/org.unifiedpush.android.connector.internal.RaiseToForegroundService}
* NtfyUpRaiseFg D Sending msg for org.unifiedpush.example
* NtfyUpRaiseFg D Timeout expired, unbinding
* NtfyUpRaiseFgFactory D Removing instance for org.unifiedpush.example
* NtfyUpRaiseFg D Unbound
* OncallUpDistributor D Sending MESSAGE to org.unifiedpush.example (token=e9830034-b97d-485d-a7f1-c8a03af9cbd2): 107 bytes
* OncallUpRaiseFgFactory D New instance for org.unifiedpush.example
* OncallUpRaiseFg I Found foreground process: com.centralcloud.oncall.debug
* OncallUpRaiseFg D Binding to org.unifiedpush.example
* OncallUpRaiseFg D onServiceConnected ComponentInfo{org.unifiedpush.example/org.unifiedpush.android.connector.internal.RaiseToForegroundService}
* OncallUpRaiseFg D Sending msg for org.unifiedpush.example
* OncallUpRaiseFg D Timeout expired, unbinding
* OncallUpRaiseFgFactory D Removing instance for org.unifiedpush.example
* OncallUpRaiseFg D Unbound
* ```
*
* ## Why "Foreground" Matters
@ -81,12 +81,12 @@ import java.util.concurrent.TimeUnit
* - Can start foreground services from the background
* - Has higher priority and is less likely to be killed
*
* This mechanism allows ntfy to temporarily "lend" its foreground importance to the target app,
* This mechanism allows oncall to temporarily "lend" its foreground importance to the target app,
* enabling reliable push notification processing even when both apps are in the background.
*
* ## Fallback Behavior
*
* If ntfy isn't in the foreground or the target app doesn't support the raise-to-foreground
* If oncall isn't in the foreground or the target app doesn't support the raise-to-foreground
* service, the message is sent directly via broadcast without the binding step. This maintains
* backward compatibility with older apps but may result in delayed or missed notifications
* on devices with aggressive battery optimization.
@ -302,7 +302,7 @@ class RaiseAppToForeground(private val context: Context, private val app: String
}
private companion object {
private const val TAG = "NtfyUpRaiseFg"
private const val TAG = "OncallUpRaiseFg"
private const val ACTION = "org.unifiedpush.android.connector.RAISE_TO_FOREGROUND"
/** Executor to unbind 5 seconds later */

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.up
package com.centralcloud.oncall.up
import android.content.Context
import android.util.Log
@ -35,5 +35,5 @@ object RaiseAppToForegroundFactory {
}
}
private val instances: MutableMap<String, RaiseAppToForeground> = mutableMapOf()
private const val TAG = "NtfyUpRaiseFgFactory"
private const val TAG = "OncallUpRaiseFgFactory"
}

View file

@ -1,10 +1,10 @@
package io.heckel.ntfy.util
package com.centralcloud.oncall.util
import android.annotation.SuppressLint
import android.content.Context
import android.util.Base64
import io.heckel.ntfy.db.ClientCertificate
import io.heckel.ntfy.db.Repository
import com.centralcloud.oncall.db.ClientCertificate
import com.centralcloud.oncall.db.Repository
import okhttp3.OkHttpClient
import java.io.ByteArrayInputStream
import java.net.URL
@ -199,7 +199,7 @@ class CertUtil private constructor(context: Context) {
}
companion object {
private const val TAG = "NtfyCertUtil"
private const val TAG = "OncallCertUtil"
@Volatile
@SuppressLint("StaticFieldLeak")

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.util
package com.centralcloud.oncall.util
const val ANDROID_APP_MIME_TYPE = "application/vnd.android.package-archive"
const val SUBSCRIPTION_ICONS = "subscriptionIcons"

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.util;
package com.centralcloud.oncall.util;
import java.nio.charset.StandardCharsets;
import java.util.Collections;

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.util;
package com.centralcloud.oncall.util;
import org.json.JSONArray;
import org.json.JSONException;

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.util;
package com.centralcloud.oncall.util;
import java.io.InputStream;
import java.util.HashMap;

View file

@ -1,10 +1,10 @@
package io.heckel.ntfy.util
package com.centralcloud.oncall.util
import android.content.Context
import android.os.Build
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.db.CustomHeader
import io.heckel.ntfy.db.User
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.db.CustomHeader
import com.centralcloud.oncall.db.User
import okhttp3.Credentials
import okhttp3.OkHttpClient
import okhttp3.Request
@ -16,7 +16,7 @@ import java.util.concurrent.TimeUnit
* All clients are configured with SSL/TLS settings from CertUtil for custom certificate support.
*/
object HttpUtil {
val USER_AGENT = "ntfy/${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}; Android ${Build.VERSION.RELEASE}; SDK ${Build.VERSION.SDK_INT})"
val USER_AGENT = "oncall/${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR}; Android ${Build.VERSION.RELEASE}; SDK ${Build.VERSION.SDK_INT})"
/**
* Client for regular API calls (auth, poll, etc.).
@ -60,7 +60,7 @@ object HttpUtil {
* We use a long interval so the modem can fully power down between pings, which is
* the dominant battery factor for the foreground service.
*
* See discussion in https://github.com/binwiederhier/ntfy-android/pull/113
* See discussion in https://github.com/binwiederhier/oncall-android/pull/113
*/
suspend fun wsClient(context: Context, baseUrl: String): OkHttpClient {
return emptyClientBuilder(context, baseUrl)

View file

@ -1,12 +1,12 @@
package io.heckel.ntfy.util
package com.centralcloud.oncall.util
import android.content.Context
import android.os.Build
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.backup.Backuper
import io.heckel.ntfy.db.Database
import io.heckel.ntfy.db.LogDao
import io.heckel.ntfy.db.LogEntry
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.backup.Backuper
import com.centralcloud.oncall.db.Database
import com.centralcloud.oncall.db.LogDao
import com.centralcloud.oncall.db.LogEntry
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@ -47,13 +47,13 @@ class Log(private val logsDao: LogDao) {
}
private fun prependDeviceInfo(logs: String, settings: String, scrubLine: Boolean): String {
val maybeScrubLine = if (scrubLine) "Server URLs (aside from ntfy.sh) and topics have been replaced with fruits 🍌🥝🍋🥥🥑🍊🍎🍑.\n" else ""
val maybeScrubLine = if (scrubLine) "Server URLs (aside from oncall.hugo.dk) and topics have been replaced with fruits 🍌🥝🍋🥥🥑🍊🍎🍑.\n" else ""
return """
This is a log of the ntfy Android app. The log shows up to 1,000 entries.
This is a log of the oncall Android app. The log shows up to 1,000 entries.
$maybeScrubLine
Device info:
--
ntfy: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR})
oncall: ${BuildConfig.VERSION_NAME} (${BuildConfig.FLAVOR})
OS: ${System.getProperty("os.version")}
Android: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT})
Model: ${Build.DEVICE}
@ -134,10 +134,10 @@ class Log(private val logsDao: LogDao) {
)
companion object {
private const val TAG = "NtfyLog"
private const val TAG = "OncallLog"
private const val PRUNE_EVERY = 100
private const val ENTRIES_MAX = 1000
private val IGNORE_TERMS = listOf("ntfy.sh")
private val IGNORE_TERMS = listOf("oncall.hugo.dk")
private val REPLACE_TERMS = listOf(
"banana", "kiwi", "lemon", "coconut", "avocado", "orange", "apple", "peach",
"pineapple", "dragonfruit", "durian", "starfruit"

View file

@ -1,10 +1,10 @@
package io.heckel.ntfy.util
package com.centralcloud.oncall.util
import android.content.Context
import android.graphics.Typeface
import android.text.style.*
import android.text.util.Linkify
import io.heckel.ntfy.ui.Colors
import com.centralcloud.oncall.ui.Colors
import io.noties.markwon.*
import io.noties.markwon.core.CorePlugin
import io.noties.markwon.core.CoreProps

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.util
package com.centralcloud.oncall.util
import okhttp3.MediaType
import okhttp3.RequestBody

View file

@ -1,4 +1,4 @@
package io.heckel.ntfy.util
package com.centralcloud.oncall.util
import android.content.ClipData
import android.content.ClipboardManager
@ -22,16 +22,16 @@ import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatDelegate
import io.heckel.ntfy.R
import io.heckel.ntfy.db.ACTION_PROGRESS_FAILED
import io.heckel.ntfy.db.ACTION_PROGRESS_ONGOING
import io.heckel.ntfy.db.ACTION_PROGRESS_SUCCESS
import io.heckel.ntfy.db.Action
import io.heckel.ntfy.db.Attachment
import io.heckel.ntfy.db.Notification
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.db.Subscription
import io.heckel.ntfy.msg.MESSAGE_ENCODING_BASE64
import com.centralcloud.oncall.R
import com.centralcloud.oncall.db.ACTION_PROGRESS_FAILED
import com.centralcloud.oncall.db.ACTION_PROGRESS_ONGOING
import com.centralcloud.oncall.db.ACTION_PROGRESS_SUCCESS
import com.centralcloud.oncall.db.Action
import com.centralcloud.oncall.db.Attachment
import com.centralcloud.oncall.db.Notification
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.db.Subscription
import com.centralcloud.oncall.msg.MESSAGE_ENCODING_BASE64
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@ -108,11 +108,11 @@ fun validUrl(url: String): Boolean {
}
/**
* Validates that a URL is a valid base URL for ntfy servers.
* Validates that a URL is a valid base URL for oncall servers.
* Only allows URLs that:
* - Start with http:// or https://
* - Do NOT have any path fragment (e.g., "https://ntfy.example.com" is allowed,
* but "https://ntfy.example.com/subpath" is not)
* - Do NOT have any path fragment (e.g., "https://oncall.example.com" is allowed,
* but "https://oncall.example.com/subpath" is not)
*/
fun validBaseUrl(url: String): Boolean {
if (!url.startsWith("http://") && !url.startsWith("https://")) {
@ -285,7 +285,7 @@ fun fileStat(context: Context, contentUri: Uri?): FileInfo {
}
val size = c.getLong(sizeIndex)
if (size == 0L) {
// Content provider URIs (e.g. content://io.heckel.ntfy.provider/cache_files/DQ4o7DitZAmw) return an entry, even
// Content provider URIs (e.g. content://com.centralcloud.oncall.provider/cache_files/DQ4o7DitZAmw) return an entry, even
// when they do not exist, but with an empty size. This is a practical/fast way to weed out non-existing files.
throw FileNotFoundException("Not found or empty: $contentUri")
}
@ -362,7 +362,7 @@ fun mimeTypeToIconResource(mimeType: String?): Int {
fun supportedImage(mimeType: String?): Boolean {
return listOf(
"image/jpeg",
"image/jpg", // Technically not a valid MIME type, see https://github.com/binwiederhier/ntfy-android/pull/142
"image/jpg", // Technically not a valid MIME type, see https://github.com/binwiederhier/oncall-android/pull/142
"image/png",
"image/gif",
"image/webp"
@ -371,7 +371,7 @@ fun supportedImage(mimeType: String?): Boolean {
// We cannot open .apk files, because we don't have the REQUEST_INSTALL_PACKAGES anymore
// Play didn't grant us the permission, and F-Droid users didn't want us to have it.
// See https://github.com/binwiederhier/ntfy/issues/531 & https://github.com/binwiederhier/ntfy/issues/684
// See https://github.com/binwiederhier/oncall/issues/531 & https://github.com/binwiederhier/oncall/issues/684
fun canOpenAttachment(attachment: Attachment?): Boolean {
return attachment?.type != ANDROID_APP_MIME_TYPE
}
@ -549,7 +549,7 @@ fun deriveNotificationId(baseUrl: String, topic: String, sequenceId: String): In
}
// We check for any active network, not specifically for internet connectivity,
// because the ntfy server may be on a LAN without internet access.
// because the oncall server may be on a LAN without internet access.
fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return connectivityManager.activeNetwork != null

View file

@ -1,16 +1,16 @@
package io.heckel.ntfy.work
package com.centralcloud.oncall.work
import android.content.Context
import androidx.core.content.FileProvider
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.db.ATTACHMENT_PROGRESS_DELETED
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.msg.DownloadIconWorker
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.maybeFileStat
import io.heckel.ntfy.util.topicShortUrl
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.db.ATTACHMENT_PROGRESS_DELETED
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.msg.DownloadIconWorker
import com.centralcloud.oncall.util.Log
import com.centralcloud.oncall.util.maybeFileStat
import com.centralcloud.oncall.util.topicShortUrl
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
@ -133,8 +133,8 @@ class DeleteWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx
companion object {
const val VERSION = BuildConfig.VERSION_CODE
const val TAG = "NtfyDeleteWorker"
const val WORK_NAME_PERIODIC_ALL = "NtfyDeleteWorkerPeriodic" // Do not change
const val TAG = "OncallDeleteWorker"
const val WORK_NAME_PERIODIC_ALL = "OncallDeleteWorkerPeriodic" // Do not change
private const val ONE_DAY_SECONDS = 24 * 60 * 60L
const val HARD_DELETE_AFTER_SECONDS = 4 * 30 * ONE_DAY_SECONDS // 4 months

View file

@ -1,14 +1,14 @@
package io.heckel.ntfy.work
package com.centralcloud.oncall.work
import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.db.Repository
import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.msg.NotificationDispatcher
import io.heckel.ntfy.msg.Poller
import io.heckel.ntfy.util.Log
import com.centralcloud.oncall.BuildConfig
import com.centralcloud.oncall.db.Repository
import com.centralcloud.oncall.msg.ApiService
import com.centralcloud.oncall.msg.NotificationDispatcher
import com.centralcloud.oncall.msg.Poller
import com.centralcloud.oncall.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@ -55,9 +55,9 @@ class PollWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx,
companion object {
const val VERSION = BuildConfig.VERSION_CODE
const val TAG = "NtfyPollWorker"
const val WORK_NAME_PERIODIC_ALL = "NtfyPollWorkerPeriodic" // Do not change
const val WORK_NAME_ONCE_SINGE_PREFIX = "NtfyPollWorkerSingle" // e.g. NtfyPollWorkerSingle_https://ntfy.sh_mytopic
const val TAG = "OncallPollWorker"
const val WORK_NAME_PERIODIC_ALL = "OncallPollWorkerPeriodic" // Do not change
const val WORK_NAME_ONCE_SINGE_PREFIX = "OncallPollWorkerSingle" // e.g. OncallPollWorkerSingle_https://oncall.hugo.dk_mytopic
const val INPUT_DATA_BASE_URL = "baseUrl"
const val INPUT_DATA_TOPIC = "topic"
}

View file

@ -14,7 +14,7 @@
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="17dp" android:scaleType="fitStart"/>
<TextView
android:text="ntfy.sh/example"
android:text="oncall.hugo.dk/example"
android:layout_width="0dp"
android:layout_height="wrap_content" android:id="@+id/main_item_text"
app:layout_constraintTop_toTopOf="parent"

View file

@ -15,7 +15,7 @@
app:layout_constraintBottom_toBottomOf="@+id/share_item_text"
app:layout_constraintTop_toTopOf="@+id/share_item_text" android:layout_marginStart="2dp"/>
<TextView
android:text="ntfy.sh/example"
android:text="oncall.hugo.dk/example"
android:layout_width="0dp"
android:layout_height="wrap_content" android:id="@+id/share_item_text"
app:layout_constraintTop_toTopOf="parent"

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
ntfy EDIT:
oncall EDIT:
This is a slightly edited copy of the original Android project layout
to reduce the marginBottom of the message to something reasonable (was: 48dp).

View file

@ -95,7 +95,7 @@
<string name="common_button_add">أضف</string>
<string name="common_button_delete">احذف</string>
<string name="common_service_url">خدمة URL</string>
<string name="common_service_url_placeholder">مثال https://ntfy.example.com</string>
<string name="common_service_url_placeholder">مثال https://oncall.example.com</string>
<string name="detail_item_menu_delete">احذف الملف</string>
<string name="publish_dialog_upload_cancelled">أُلغيَ الرفع</string>
<string name="user_dialog_button_cancel">ألغِ</string>

View file

@ -67,7 +67,7 @@
<string name="detail_no_notifications_text">Липсват известия в темата</string>
<string name="default_server_dialog_description">За да използвате по подразбиране собствен сървър при абониране за нови теми и/или споделяне на теми, въведете адрес на сървъра.</string>
<string name="notification_dialog_muted_until_toast_message">Известията са заглушени до %1$s</string>
<string name="settings_advanced_export_logs_summary">Дневниците се копират в междинната памет или се изпращат към nopaste.net (собственост на автора на ntfy). Имената на хостовете и темите могат да бъдат цензурирани, но съдържанието на известията никога.</string>
<string name="settings_advanced_export_logs_summary">Дневниците се копират в междинната памет или се изпращат към nopaste.net (собственост на автора на oncall). Имената на хостовете и темите могат да бъдат цензурирани, но съдържанието на известията никога.</string>
<string name="main_menu_report_bug_title">Доклад за дефект</string>
<string name="main_menu_docs_title">Документация</string>
<string name="main_menu_rate_title">Оценяване ⭐</string>
@ -93,8 +93,8 @@
<string name="add_dialog_login_username_hint">Потребител</string>
<string name="add_dialog_login_error_not_authorized">Неуспешен вход. Потребителят %1$s няма достъп.</string>
<string name="detail_how_to_example"><![CDATA[ Пример (curl): <br/><tt>$ curl -d "Здравейте" %1$s</tt> ]]></string>
<string name="detail_how_to_link">Подробни инструкции са достъпни на ntfy.sh и в документацията.</string>
<string name="main_how_to_link">Подробни инструкции са достъпни на ntfy.sh и в документацията.</string>
<string name="detail_how_to_link">Подробни инструкции са достъпни на oncall.hugo.dk и в документацията.</string>
<string name="main_how_to_link">Подробни инструкции са достъпни на oncall.hugo.dk и в документацията.</string>
<string name="detail_clear_dialog_permanently_delete">Премахване</string>
<string name="detail_clear_dialog_cancel">Отказ</string>
<string name="main_banner_battery_button_remind_later">По-късно</string>
@ -184,7 +184,7 @@
<string name="settings_notifications_auto_delete_one_month">След един месец</string>
<string name="settings_advanced_export_logs_entry_copy_scrubbed">Копиране в междинната памет (цензурирано)</string>
<string name="settings_advanced_connection_protocol_summary_jsonhttp">За свързване със сървъра се използва поток от JSON през HTTP. Методът е изпитан, но може да използва повече батерия.</string>
<string name="detail_test_message">Това е пробно известие от приложението ntfy за Android. То е с приоритет %1$d. Ако изпратите друго, то може да изглежда по различен начин.</string>
<string name="detail_test_message">Това е пробно известие от приложението oncall за Android. То е с приоритет %1$d. Ако изпратите друго, то може да изглежда по различен начин.</string>
<string name="detail_test_title">Проба: Ако желаете можете да сложите заглавие</string>
<string name="detail_test_message_error_unauthorized_user">Грешка при изпращане: Потребителят „%1$s“ няма достъп.</string>
<string name="settings_notifications_min_priority_summary_x_or_higher">Показват се известията с приоритет %1$d (%2$s) или по-висок</string>
@ -205,7 +205,7 @@
<string name="user_dialog_username_hint">Потребител</string>
<string name="user_dialog_title_edit">Промяна на потребител</string>
<string name="user_dialog_title_add">Добавяне на потребител</string>
<string name="settings_about_version_format">ntfy %1$s (%2$s)</string>
<string name="settings_about_version_format">oncall %1$s (%2$s)</string>
<string name="user_dialog_description_edit">Можете да променяте избрания потребител или да го премахнете.</string>
<string name="settings_about_version_title">Издание</string>
<string name="settings_about_header">Относно</string>
@ -315,14 +315,14 @@
<string name="detail_settings_global_setting_suffix">от общите настройки</string>
<string name="add_dialog_base_urls_dropdown_choose">Изберете адрес на услугата</string>
<string name="add_dialog_base_urls_dropdown_clear">Изчистване на адреса на услугата</string>
<string name="main_banner_websocket_text">WebSockets е препоръчителния начин за свързване с услугата и може да подобри използването на батерията, но могат да се наложат <a href="https://ntfy.sh/docs/config/#nginxapache2caddy">допълнителни настройки на сървъра за прокси</a>. Промяната може да бъде направена в настройките.</string>
<string name="main_banner_websocket_text">WebSockets е препоръчителния начин за свързване с услугата и може да подобри използването на батерията, но могат да се наложат <a href="https://oncall.hugo.dk/docs/config/#nginxapache2caddy">допълнителни настройки на сървъра за прокси</a>. Промяната може да бъде направена в настройките.</string>
<string name="main_banner_websocket_button_enable_now">Включване</string>
<string name="detail_settings_appearance_display_name_default_summary">%1$s (по подразбиране)</string>
<string name="detail_settings_appearance_display_name_title">Наименование</string>
<string name="detail_settings_appearance_display_name_message">Задайте име на абонамента. За да върнете името по подразбиране (%1$s) оставете празно.</string>
<string name="detail_settings_about_header">Относно</string>
<string name="detail_settings_about_topic_url_title">Адрес на темата</string>
<string name="detail_item_cannot_open_apk">Ntfy не може да инсталира получени приложения. Вместо това изтеглете чрез браузъра. За подробности вижте дефект №531.</string>
<string name="detail_item_cannot_open_apk">Oncall не може да инсталира получени приложения. Вместо това изтеглете чрез браузъра. За подробности вижте дефект №531.</string>
<string name="channel_notifications_group_default_name">Подразбирани</string>
<string name="detail_settings_notifications_dedicated_channels_title">Потребителски настройки за известия</string>
<string name="detail_settings_notifications_dedicated_channels_summary_on">Използва потребителски настройки за този абонамент</string>
@ -334,19 +334,19 @@
<string name="detail_settings_notifications_insistent_max_priority_list_item_disabled">Единично сигнализиране</string>
<string name="detail_settings_notifications_dedicated_channels_summary_off">Подразбирани настройки (отмяна на „Не безпокойте“, звуци и т.н.)</string>
<string name="settings_notifications_insistent_max_priority_summary_enabled">Известията с най-висок приоритет сигнализират, докато не бъдат затворени</string>
<string name="settings_advanced_unifiedpush_summary_enabled">ntfy ще работи като дистрибутор на UnifiedPush</string>
<string name="settings_advanced_unifiedpush_summary_enabled">oncall ще работи като дистрибутор на UnifiedPush</string>
<string name="settings_advanced_unifiedpush_title">Включване на UnifiedPush</string>
<string name="settings_advanced_unifiedpush_summary_disabled">ntfy няма да работи като дистрибутор на UnifiedPush</string>
<string name="main_banner_websocket_reconnect_text">За да сте сигурни, че WebSockets се свързват във фонов режим дайте разрешението Будилник и напомняне на ntfy</string>
<string name="settings_advanced_unifiedpush_summary_disabled">oncall няма да работи като дистрибутор на UnifiedPush</string>
<string name="main_banner_websocket_reconnect_text">За да сте сигурни, че WebSockets се свързват във фонов режим дайте разрешението Будилник и напомняне на oncall</string>
<string name="main_banner_websocket_reconnect_button_remind_later">По-късно</string>
<string name="main_banner_websocket_reconnect_button_dismiss">Затваряне</string>
<string name="main_banner_websocket_reconnect_button_enable_now">Разрешаване</string>
<string name="settings_advanced_exact_alarms_title">Будилници в точно време</string>
<string name="settings_advanced_exact_alarms_true">ntfy може да насрочва будилници в точно определено време. Те са задължителни за повторно свързване на WebSockets във фонов режим. За да оттеглите разрешението докоснете.</string>
<string name="settings_advanced_exact_alarms_false">ntfy не може да насрочва будилници в точно определено време. Те са задължителни за повторно свързване на WebSockets във фонов режим. За да разрешите докоснете.</string>
<string name="settings_advanced_exact_alarms_true">oncall може да насрочва будилници в точно определено време. Те са задължителни за повторно свързване на WebSockets във фонов режим. За да оттеглите разрешението докоснете.</string>
<string name="settings_advanced_exact_alarms_false">oncall не може да насрочва будилници в точно определено време. Те са задължителни за повторно свързване на WebSockets във фонов режим. За да разрешите докоснете.</string>
<string name="settings_general_dynamic_colors_title">Динамични цветове</string>
<string name="settings_general_dynamic_colors_summary_enabled">Използване на динамичните системни цветове</string>
<string name="settings_general_dynamic_colors_summary_disabled">Използване на цветовете от темата на ntfy</string>
<string name="settings_general_dynamic_colors_summary_disabled">Използване на цветовете от темата на oncall</string>
<string name="publish_dialog_title">Публикуване към %1$s</string>
<string name="publish_dialog_title_hint">Заглавие</string>
<string name="publish_dialog_chip_title">Заглавие</string>
@ -382,7 +382,7 @@
<string name="publish_dialog_attach_filename_placeholder">напр. lilies.jpg</string>
<string name="publish_dialog_phone_call_hint">Телефонно обаждане</string>
<string name="publish_dialog_phone_call_placeholder">напр. +1234567890</string>
<string name="publish_dialog_docs_text">За примери и подробно описание на всички възможности за публикуване прочетете <a href="https://docs.ntfy.sh/publish/">документацията</a>.</string>
<string name="publish_dialog_docs_text">За примери и подробно описание на всички възможности за публикуване прочетете <a href="https://docs.oncall.hugo.dk/publish/">документацията</a>.</string>
<string name="message_bar_hint">Въведете съобщение</string>
<string name="message_bar_publish_button_description">Публикуване на съобщение</string>
<string name="message_bar_expand_button_description">Повече възможности</string>
@ -394,7 +394,7 @@
<string name="settings_general_message_bar_summary_enabled">Лентата за съобщения е долу в прегледа на тема</string>
<string name="settings_general_message_bar_summary_disabled">Бутонът за публикуване е долу в прегледа на тема</string>
<string name="settings_advanced_custom_headers_title">Заглавки по избор</string>
<string name="settings_advanced_custom_headers_summary">Задайте заглавки на HTTP по избор. Ще бъдат изпращани с всяка заявка. Полезно ако сървърът на ntfy изисква удостоверяване или достъп през тунел.</string>
<string name="settings_advanced_custom_headers_summary">Задайте заглавки на HTTP по избор. Ще бъдат изпращани с всяка заявка. Полезно ако сървърът на oncall изисква удостоверяване или достъп през тунел.</string>
<string name="settings_advanced_custom_headers_prefs_header_add">Добавяне на заглавка</string>
<string name="settings_advanced_custom_headers_prefs_header_add_title">Добавяне на заглавка за сървъра</string>
<string name="settings_advanced_custom_headers_prefs_header_add_summary">Заглавките ще бъдат изпращани с всяка заявка по HTTP. Всеки сървър може да има свой набор от заявки.</string>
@ -406,13 +406,13 @@
<string name="custom_headers_dialog_description_add">Добавяне на заглавка на HTTP по избор, която да бъде изпращана с всяка заявка към избрания сървър.</string>
<string name="custom_headers_dialog_description_edit">Можете да променяте името и стойността на заглавката или да я премахнете.</string>
<string name="custom_headers_dialog_error_invalid_name">Името на заглавката съдържа неприемливи знаци</string>
<string name="custom_headers_dialog_error_reserved_name">Тази заглавка е запазена и се задава от ntfy</string>
<string name="custom_headers_dialog_error_reserved_name">Тази заглавка е запазена и се задава от oncall</string>
<string name="custom_headers_dialog_error_user_exists">Не може да бъде добавена заглавка Authorization ако за сървъра е зададен потребител</string>
<string name="custom_headers_dialog_error_duplicate">Заглавка с това име вече има за този сървър</string>
<string name="common_button_add">Добавяне</string>
<string name="common_button_save">Запазване</string>
<string name="common_button_delete">Премахване</string>
<string name="common_service_url_placeholder">напр. https://ntfy.example.com</string>
<string name="common_service_url_placeholder">напр. https://oncall.example.com</string>
<string name="common_button_next">Напред</string>
<string name="common_certificate_subject">Обект</string>
<string name="common_certificate_issuer">Издател</string>
@ -425,7 +425,7 @@
<string name="settings_advanced_certificates_title">Управление на сертификати</string>
<string name="settings_advanced_certificates_trusted_header">Доверени сертификати</string>
<string name="settings_advanced_certificates_trusted_add_title">Добавяне на доверен сертификат</string>
<string name="settings_advanced_certificates_trusted_add_summary">Добавяне на сертификат в довереното хранилище (PEM). При свързване към сървър на ntfy сертификатът ще е доверен.</string>
<string name="settings_advanced_certificates_trusted_add_summary">Добавяне на сертификат в довереното хранилище (PEM). При свързване към сървър на oncall сертификатът ще е доверен.</string>
<string name="settings_advanced_certificates_client_header">Клиентски сертификат (mTLS)</string>
<string name="settings_advanced_certificates_client_item_summary">Клиентски сертификат, издаден от %1$s, изтича на %2$s, използва се за връзка с %3$s</string>
<string name="settings_advanced_certificates_client_item_summary_expired">Клиентски сертификат, издаден от %1$s, изтекъл, използва се за връзка с %2$s</string>
@ -470,7 +470,7 @@
<string name="detail_menu_search">Търсене на известия</string>
<string name="detail_menu_search_hint">Търсене в известията</string>
<string name="common_button_reset_to_default">Подразбирани настройки</string>
<string name="default_server_dialog_url_error_invalid">Въведете адрес на услуга, напр. https://ntfy.example.com</string>
<string name="default_server_dialog_url_error_invalid">Въведете адрес на услуга, напр. https://oncall.example.com</string>
<string name="connection_alert_title">Връзката е загубена</string>
<string name="connection_alert_text_one">От най-малко %2$d минути няма връзка с %1$s</string>
<string name="connection_alert_text_multiple">От най-малко %2$d минути няма връзка със сървърите на %1$d</string>

View file

@ -85,7 +85,7 @@
<string name="share_topic_title">Compartir amb</string>
<string name="share_successful">Missatge publicat</string>
<string name="detail_test_title">Test: Pots definir un títol.</string>
<string name="detail_test_message">Això es una notificació de prova de l\'aplicació per Android de ntfy. Té un nivell de prioritat %1$d. Si n\'envies una altra, pot ser diferent.</string>
<string name="detail_test_message">Això es una notificació de prova de l\'aplicació per Android de oncall. Té un nivell de prioritat %1$d. Si n\'envies una altra, pot ser diferent.</string>
<string name="detail_test_message_error">No es pot enviar el missatge: %1$s</string>
<string name="detail_test_message_error_unauthorized_user">No es pot enviar el missatge: L\'usuari \"%1$s\" no està autoritzat.</string>
<string name="common_copied_to_clipboard">Copiat al porta-retalls</string>
@ -105,8 +105,8 @@
<string name="detail_how_to_intro">Per enviar notificacions en aquest tema, fes PUT o POST a la URL del tema.</string>
<string name="detail_how_to_example"><![CDATA[ Exemple (usant curl):<br/><tt>$ curl -d \"Hola\" %1$s</tt> ]]></string>
<string name="main_unified_push_toast">Aquesta subscripció és gestionada per %1$s via UnifiedPush</string>
<string name="main_how_to_link">Instruccions detallades disponibles a ntfy.sh i a la documentació.</string>
<string name="main_banner_websocket_text">WebSockets és el mètode recomanat per connectar-te al teu servidor. Pot millorar el rendiment de la bateria, però pot requerir <a href="https://ntfy.sh/docs/config/#nginxapache2caddy">configuració addicional al teu proxy</a>. Aquesta opció pot ser habil·litada a Configuració.</string>
<string name="main_how_to_link">Instruccions detallades disponibles a oncall.hugo.dk i a la documentació.</string>
<string name="main_banner_websocket_text">WebSockets és el mètode recomanat per connectar-te al teu servidor. Pot millorar el rendiment de la bateria, però pot requerir <a href="https://oncall.hugo.dk/docs/config/#nginxapache2caddy">configuració addicional al teu proxy</a>. Aquesta opció pot ser habil·litada a Configuració.</string>
<string name="main_banner_websocket_button_enable_now">Activar ara</string>
<string name="add_dialog_description_below">Els temes poden no estar protegits per contrasenya, tria un nom difícil d\'endevinar. Un cop subscrit podràs publicar notificacions PUT/POST.</string>
<string name="add_dialog_use_another_server">Usar un altre servidor</string>
@ -125,7 +125,7 @@
<string name="add_dialog_login_error_not_authorized">Inici de sessió fallit. L\'usuari %1$s no està autoritzat.</string>
<string name="add_dialog_login_new_user">Nou usuari</string>
<string name="add_dialog_base_urls_dropdown_choose">Tria URL de servei</string>
<string name="detail_how_to_link">Instruccions detallades disponibles a ntfy.sh i a la documentació.</string>
<string name="detail_how_to_link">Instruccions detallades disponibles a oncall.hugo.dk i a la documentació.</string>
<string name="detail_clear_dialog_message">Vols esborrar totes les notificacions d\'aquest tema\?</string>
<string name="detail_clear_dialog_permanently_delete">Eliminar definitivament</string>
<string name="detail_clear_dialog_cancel">Cancel·lar</string>
@ -214,7 +214,7 @@
<string name="settings_advanced_broadcast_summary_enabled">Les aplicacions poden rebre notificacions d\'entrada com a missatges</string>
<string name="settings_advanced_record_logs_summary_enabled">Gravant (fins a 1000 entrades) al dispositiu…</string>
<string name="settings_advanced_export_logs_title">Copiar/carregar registres</string>
<string name="settings_advanced_export_logs_summary">Copiar registres al porta-retalls, o carregar-los a nopaste.net (propietat de l\'autor de ntfy). Els noms de host i els temes poden ser censurats, les notificacions mai.</string>
<string name="settings_advanced_export_logs_summary">Copiar registres al porta-retalls, o carregar-los a nopaste.net (propietat de l\'autor de oncall). Els noms de host i els temes poden ser censurats, les notificacions mai.</string>
<string name="settings_advanced_export_logs_entry_copy_original">Copiar al porta-retalls</string>
<string name="settings_advanced_export_logs_entry_copy_scrubbed">Copiar al porta-retalls (censurat)</string>
<string name="detail_settings_notifications_dedicated_channels_summary_off">Usant configuració predeterminada (sons, sobreescriure No Molestar, etc.)</string>
@ -246,8 +246,8 @@
<string name="settings_notifications_min_priority_low">Prioritat baixa i superiors</string>
<string name="settings_notifications_min_priority_max">Només prioritat màxima</string>
<string name="settings_advanced_unifiedpush_title">Activar UnifiedPush</string>
<string name="settings_advanced_unifiedpush_summary_enabled">ntfy actuarà com a distribuidor de UnifiedPush</string>
<string name="settings_advanced_unifiedpush_summary_disabled">ntfy no actuarà com a distribuidor de UnifiedPush</string>
<string name="settings_advanced_unifiedpush_summary_enabled">oncall actuarà com a distribuidor de UnifiedPush</string>
<string name="settings_advanced_unifiedpush_summary_disabled">oncall no actuarà com a distribuidor de UnifiedPush</string>
<string name="settings_advanced_record_logs_summary_disabled">Activar registre per poder compartir-lo més endavant per resoldre problemes.</string>
<string name="settings_advanced_clear_logs_title">Eliminar registres</string>
<string name="settings_advanced_export_logs_entry_upload_scrubbed">Carregar i copiar enllaç (censurat)</string>
@ -260,7 +260,7 @@
<string name="settings_advanced_connection_protocol_summary_jsonhttp">Usa un flux JSON a través d\'HTTP per tal de connectar-te al servidor. Aquest mètode és robust, però pot consumir molta bateria.</string>
<string name="settings_about_version_title">Versió</string>
<string name="settings_advanced_connection_protocol_summary_ws">Usa WebSockets per connectar al servidor. Aquest és el mètode recomanat, però pot necessitar configuració addicional al teu proxy.</string>
<string name="settings_about_version_format">ntfy %1$s (%2$s)</string>
<string name="settings_about_version_format">oncall %1$s (%2$s)</string>
<string name="detail_settings_notifications_instant_title">Entrega instantània</string>
<string name="detail_settings_notifications_instant_summary_on">Les notificacions s\'entreguen instantàniament. Requereix d\'un servei en primer pla i consumeix molta bateria.</string>
<string name="detail_settings_notifications_instant_summary_off">Les notificacions s\'entreguen usant FireBase. L\'entrega es pot retardar, però consumeix menys bateria.</string>
@ -342,7 +342,7 @@
<string name="common_button_add">Afegir</string>
<string name="common_button_delete">Esborrar</string>
<string name="common_button_reset_to_default">Restaurar valors per defecte</string>
<string name="common_service_url_placeholder">ex. https://ntfy.exemple.cat</string>
<string name="common_service_url_placeholder">ex. https://oncall.exemple.cat</string>
<string name="common_certificate_subject">Tema</string>
<string name="common_certificate_issuer">Emissor</string>
<string name="common_certificate_fingerprint">Empremta digital SHA-256</string>

Some files were not shown because too many files have changed in this diff Show more