mirror of
https://github.com/PranshulGG/WeatherMaster.git
synced 2026-10-21 18:43:03 -05:00
Merge branch 'main' into l10n_main
Signed-off-by: Pranshul <pranshul.devmain@gmail.com>
This commit is contained in:
24 files changed
+2444
-28
No files matched your search
@@ -0,0 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
github: [PranshulGG]
|
||||
ko_fi: pranshulgg
|
||||
liberapay: PranshulGG
|
||||
+15
-3
@@ -2,11 +2,11 @@
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 46,
|
||||
"identityHash": "b2ca5c75db987a1d27628fc45eac72bf",
|
||||
"identityHash": "fd66b7531bfe72f6bcac04b8fe26dc9e",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "weather_locations",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `country` TEXT NOT NULL, `lat` REAL NOT NULL, `lon` REAL NOT NULL, `timezone` TEXT NOT NULL, `source` TEXT NOT NULL, `state` TEXT, `isFavorite` INTEGER NOT NULL, `isPinned` INTEGER NOT NULL, `countryCode` TEXT, `isDefault` INTEGER NOT NULL, `isDeviceLocation` INTEGER NOT NULL, PRIMARY KEY(`id`))",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `country` TEXT NOT NULL, `lat` REAL NOT NULL, `lon` REAL NOT NULL, `timezone` TEXT NOT NULL, `source` TEXT NOT NULL, `state` TEXT, `isFavorite` INTEGER NOT NULL, `isPinned` INTEGER NOT NULL, `countryCode` TEXT, `isDefault` INTEGER NOT NULL, `isDeviceLocation` INTEGER NOT NULL, `alertSource` TEXT NOT NULL, `airQualitySource` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
@@ -83,6 +83,18 @@
|
||||
"columnName": "isDeviceLocation",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "alertSource",
|
||||
"columnName": "alertSource",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "airQualitySource",
|
||||
"columnName": "airQualitySource",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
@@ -845,7 +857,7 @@
|
||||
],
|
||||
"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, 'b2ca5c75db987a1d27628fc45eac72bf')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'fd66b7531bfe72f6bcac04b8fe26dc9e')"
|
||||
]
|
||||
}
|
||||
}
|
||||
+863
@@ -0,0 +1,863 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 47,
|
||||
"identityHash": "fd66b7531bfe72f6bcac04b8fe26dc9e",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "weather_locations",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `country` TEXT NOT NULL, `lat` REAL NOT NULL, `lon` REAL NOT NULL, `timezone` TEXT NOT NULL, `source` TEXT NOT NULL, `state` TEXT, `isFavorite` INTEGER NOT NULL, `isPinned` INTEGER NOT NULL, `countryCode` TEXT, `isDefault` INTEGER NOT NULL, `isDeviceLocation` INTEGER NOT NULL, `alertSource` TEXT NOT NULL, `airQualitySource` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "country",
|
||||
"columnName": "country",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lat",
|
||||
"columnName": "lat",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lon",
|
||||
"columnName": "lon",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "timezone",
|
||||
"columnName": "timezone",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "source",
|
||||
"columnName": "source",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "state",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "isFavorite",
|
||||
"columnName": "isFavorite",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isPinned",
|
||||
"columnName": "isPinned",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "countryCode",
|
||||
"columnName": "countryCode",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "isDefault",
|
||||
"columnName": "isDefault",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isDeviceLocation",
|
||||
"columnName": "isDeviceLocation",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "alertSource",
|
||||
"columnName": "alertSource",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "airQualitySource",
|
||||
"columnName": "airQualitySource",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tableName": "weather_current",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`locationId` TEXT NOT NULL, `temperature` REAL, `humidity` REAL NOT NULL, `windSpeed` REAL, `windDirection` TEXT, `pressureMsl` REAL, `visibility` INTEGER, `cloudCover` REAL, `uvIndex` REAL, `weatherCondition` TEXT NOT NULL, `feelsLike` REAL, `time` INTEGER NOT NULL, `dewPoint` REAL, `utcOffsetSeconds` INTEGER, `lastUpdatedInMilli` INTEGER NOT NULL, PRIMARY KEY(`locationId`), FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "temperature",
|
||||
"columnName": "temperature",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "humidity",
|
||||
"columnName": "humidity",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "windSpeed",
|
||||
"columnName": "windSpeed",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "windDirection",
|
||||
"columnName": "windDirection",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pressureMsl",
|
||||
"columnName": "pressureMsl",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "visibility",
|
||||
"columnName": "visibility",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "cloudCover",
|
||||
"columnName": "cloudCover",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "uvIndex",
|
||||
"columnName": "uvIndex",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "weatherCondition",
|
||||
"columnName": "weatherCondition",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "feelsLike",
|
||||
"columnName": "feelsLike",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dewPoint",
|
||||
"columnName": "dewPoint",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "utcOffsetSeconds",
|
||||
"columnName": "utcOffsetSeconds",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastUpdatedInMilli",
|
||||
"columnName": "lastUpdatedInMilli",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_weather_current_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_weather_current_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "weather_hourly",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`locationId` TEXT NOT NULL, `temperature` REAL, `windSpeed` REAL, `windDirection` TEXT, `rain` REAL NOT NULL, `snowfall` REAL, `uvIndex` REAL, `weatherCondition` TEXT NOT NULL, `pressureMsl` REAL, `visibility` INTEGER, `humidity` REAL, `dewPoint` REAL, `time` INTEGER NOT NULL, `precipitationProbability` INTEGER, PRIMARY KEY(`locationId`, `time`), FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "temperature",
|
||||
"columnName": "temperature",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "windSpeed",
|
||||
"columnName": "windSpeed",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "windDirection",
|
||||
"columnName": "windDirection",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "rain",
|
||||
"columnName": "rain",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "snowfall",
|
||||
"columnName": "snowfall",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "uvIndex",
|
||||
"columnName": "uvIndex",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "weatherCondition",
|
||||
"columnName": "weatherCondition",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pressureMsl",
|
||||
"columnName": "pressureMsl",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "visibility",
|
||||
"columnName": "visibility",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "humidity",
|
||||
"columnName": "humidity",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "dewPoint",
|
||||
"columnName": "dewPoint",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "precipitationProbability",
|
||||
"columnName": "precipitationProbability",
|
||||
"affinity": "INTEGER"
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"locationId",
|
||||
"time"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_weather_hourly_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_weather_hourly_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "weather_daily",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`locationId` TEXT NOT NULL, `temperatureMin` REAL, `temperatureMax` REAL, `windSpeed` REAL, `windDirection` TEXT, `rainSum` REAL NOT NULL, `snowfallSum` REAL, `uvIndexMax` REAL, `weatherCondition` TEXT NOT NULL, `time` INTEGER NOT NULL, `precipitationProbabilityMax` INTEGER, `pressureMsl` REAL, `visibility` INTEGER, `humidity` REAL, `dewPoint` REAL, `sunrise` INTEGER NOT NULL, `sunset` INTEGER NOT NULL, `moonrise` INTEGER NOT NULL, `moonset` INTEGER NOT NULL, `moonPhase` TEXT NOT NULL, `dawn` INTEGER NOT NULL, `dusk` INTEGER NOT NULL, PRIMARY KEY(`locationId`, `time`), FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "temperatureMin",
|
||||
"columnName": "temperatureMin",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "temperatureMax",
|
||||
"columnName": "temperatureMax",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "windSpeed",
|
||||
"columnName": "windSpeed",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "windDirection",
|
||||
"columnName": "windDirection",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "rainSum",
|
||||
"columnName": "rainSum",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "snowfallSum",
|
||||
"columnName": "snowfallSum",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "uvIndexMax",
|
||||
"columnName": "uvIndexMax",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "weatherCondition",
|
||||
"columnName": "weatherCondition",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "precipitationProbabilityMax",
|
||||
"columnName": "precipitationProbabilityMax",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pressureMsl",
|
||||
"columnName": "pressureMsl",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "visibility",
|
||||
"columnName": "visibility",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "humidity",
|
||||
"columnName": "humidity",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "dewPoint",
|
||||
"columnName": "dewPoint",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "sunrise",
|
||||
"columnName": "sunrise",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "sunset",
|
||||
"columnName": "sunset",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "moonrise",
|
||||
"columnName": "moonrise",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "moonset",
|
||||
"columnName": "moonset",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "moonPhase",
|
||||
"columnName": "moonPhase",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dawn",
|
||||
"columnName": "dawn",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dusk",
|
||||
"columnName": "dusk",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"locationId",
|
||||
"time"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_weather_daily_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_weather_daily_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "weather_units",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `tempUnit` TEXT NOT NULL, `windUnit` TEXT NOT NULL, `distanceUnit` TEXT NOT NULL, `pressureUnit` TEXT NOT NULL, `precipitationUnit` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "tempUnit",
|
||||
"columnName": "tempUnit",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "windUnit",
|
||||
"columnName": "windUnit",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "distanceUnit",
|
||||
"columnName": "distanceUnit",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pressureUnit",
|
||||
"columnName": "pressureUnit",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "precipitationUnit",
|
||||
"columnName": "precipitationUnit",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tableName": "weather_blocks",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `isDaily` INTEGER NOT NULL, `type` TEXT NOT NULL, `isHidden` INTEGER NOT NULL, `position` INTEGER NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isDaily",
|
||||
"columnName": "isDaily",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isHidden",
|
||||
"columnName": "isHidden",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "position",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tableName": "air_quality_current",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`locationId` TEXT NOT NULL, `usAqi` INTEGER, `pm10` REAL, `pm25` REAL, `carbonMonoxide` REAL, `nitrogenDioxide` REAL, `sulphurDioxide` REAL, `ozone` REAL, `lastUpdatedInMilli` INTEGER NOT NULL, PRIMARY KEY(`locationId`), FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "usAqi",
|
||||
"columnName": "usAqi",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pm10",
|
||||
"columnName": "pm10",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pm25",
|
||||
"columnName": "pm25",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "carbonMonoxide",
|
||||
"columnName": "carbonMonoxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "nitrogenDioxide",
|
||||
"columnName": "nitrogenDioxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "sulphurDioxide",
|
||||
"columnName": "sulphurDioxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "ozone",
|
||||
"columnName": "ozone",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastUpdatedInMilli",
|
||||
"columnName": "lastUpdatedInMilli",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_air_quality_current_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_air_quality_current_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "nws_location_gridpoints",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`locationId` TEXT NOT NULL, `officeId` TEXT NOT NULL, `gridX` INTEGER NOT NULL, `gridY` INTEGER NOT NULL, `stationIdentifier` TEXT NOT NULL, `lastUpdatedMilli` INTEGER NOT NULL, PRIMARY KEY(`locationId`), FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "officeId",
|
||||
"columnName": "officeId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gridX",
|
||||
"columnName": "gridX",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gridY",
|
||||
"columnName": "gridY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "stationIdentifier",
|
||||
"columnName": "stationIdentifier",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastUpdatedMilli",
|
||||
"columnName": "lastUpdatedMilli",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_nws_location_gridpoints_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_nws_location_gridpoints_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "github",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `currentTag` TEXT NOT NULL, `lastFetchedTag` TEXT NOT NULL, `lastFetchedTime` INTEGER NOT NULL, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "currentTag",
|
||||
"columnName": "currentTag",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastFetchedTag",
|
||||
"columnName": "lastFetchedTag",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastFetchedTime",
|
||||
"columnName": "lastFetchedTime",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tableName": "air_quality_hourly",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `locationId` TEXT NOT NULL, `pm10` REAL, `pm25` REAL, `carbonMonoxide` REAL, `nitrogenDioxide` REAL, `sulphurDioxide` REAL, `ozone` REAL, `time` INTEGER NOT NULL, FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pm10",
|
||||
"columnName": "pm10",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pm25",
|
||||
"columnName": "pm25",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "carbonMonoxide",
|
||||
"columnName": "carbonMonoxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "nitrogenDioxide",
|
||||
"columnName": "nitrogenDioxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "sulphurDioxide",
|
||||
"columnName": "sulphurDioxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "ozone",
|
||||
"columnName": "ozone",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_air_quality_hourly_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_air_quality_hourly_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"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, 'fd66b7531bfe72f6bcac04b8fe26dc9e')"
|
||||
]
|
||||
}
|
||||
}
|
||||
+868
@@ -0,0 +1,868 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 48,
|
||||
"identityHash": "5ca7c9b34ef5941f3d7515379d9646f9",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "weather_locations",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `country` TEXT NOT NULL, `lat` REAL NOT NULL, `lon` REAL NOT NULL, `timezone` TEXT NOT NULL, `source` TEXT NOT NULL, `state` TEXT, `isFavorite` INTEGER NOT NULL, `isPinned` INTEGER NOT NULL, `countryCode` TEXT, `isDefault` INTEGER NOT NULL, `isDeviceLocation` INTEGER NOT NULL, `alertSource` TEXT NOT NULL, `airQualitySource` TEXT NOT NULL, `customName` TEXT, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "name",
|
||||
"columnName": "name",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "country",
|
||||
"columnName": "country",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lat",
|
||||
"columnName": "lat",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lon",
|
||||
"columnName": "lon",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "timezone",
|
||||
"columnName": "timezone",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "source",
|
||||
"columnName": "source",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "state",
|
||||
"columnName": "state",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "isFavorite",
|
||||
"columnName": "isFavorite",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isPinned",
|
||||
"columnName": "isPinned",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "countryCode",
|
||||
"columnName": "countryCode",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "isDefault",
|
||||
"columnName": "isDefault",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isDeviceLocation",
|
||||
"columnName": "isDeviceLocation",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "alertSource",
|
||||
"columnName": "alertSource",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "airQualitySource",
|
||||
"columnName": "airQualitySource",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "customName",
|
||||
"columnName": "customName",
|
||||
"affinity": "TEXT"
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tableName": "weather_current",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`locationId` TEXT NOT NULL, `temperature` REAL, `humidity` REAL NOT NULL, `windSpeed` REAL, `windDirection` TEXT, `pressureMsl` REAL, `visibility` INTEGER, `cloudCover` REAL, `uvIndex` REAL, `weatherCondition` TEXT NOT NULL, `feelsLike` REAL, `time` INTEGER NOT NULL, `dewPoint` REAL, `utcOffsetSeconds` INTEGER, `lastUpdatedInMilli` INTEGER NOT NULL, PRIMARY KEY(`locationId`), FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "temperature",
|
||||
"columnName": "temperature",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "humidity",
|
||||
"columnName": "humidity",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "windSpeed",
|
||||
"columnName": "windSpeed",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "windDirection",
|
||||
"columnName": "windDirection",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pressureMsl",
|
||||
"columnName": "pressureMsl",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "visibility",
|
||||
"columnName": "visibility",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "cloudCover",
|
||||
"columnName": "cloudCover",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "uvIndex",
|
||||
"columnName": "uvIndex",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "weatherCondition",
|
||||
"columnName": "weatherCondition",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "feelsLike",
|
||||
"columnName": "feelsLike",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dewPoint",
|
||||
"columnName": "dewPoint",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "utcOffsetSeconds",
|
||||
"columnName": "utcOffsetSeconds",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastUpdatedInMilli",
|
||||
"columnName": "lastUpdatedInMilli",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_weather_current_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_weather_current_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "weather_hourly",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`locationId` TEXT NOT NULL, `temperature` REAL, `windSpeed` REAL, `windDirection` TEXT, `rain` REAL NOT NULL, `snowfall` REAL, `uvIndex` REAL, `weatherCondition` TEXT NOT NULL, `pressureMsl` REAL, `visibility` INTEGER, `humidity` REAL, `dewPoint` REAL, `time` INTEGER NOT NULL, `precipitationProbability` INTEGER, PRIMARY KEY(`locationId`, `time`), FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "temperature",
|
||||
"columnName": "temperature",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "windSpeed",
|
||||
"columnName": "windSpeed",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "windDirection",
|
||||
"columnName": "windDirection",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "rain",
|
||||
"columnName": "rain",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "snowfall",
|
||||
"columnName": "snowfall",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "uvIndex",
|
||||
"columnName": "uvIndex",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "weatherCondition",
|
||||
"columnName": "weatherCondition",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pressureMsl",
|
||||
"columnName": "pressureMsl",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "visibility",
|
||||
"columnName": "visibility",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "humidity",
|
||||
"columnName": "humidity",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "dewPoint",
|
||||
"columnName": "dewPoint",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "precipitationProbability",
|
||||
"columnName": "precipitationProbability",
|
||||
"affinity": "INTEGER"
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"locationId",
|
||||
"time"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_weather_hourly_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_weather_hourly_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "weather_daily",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`locationId` TEXT NOT NULL, `temperatureMin` REAL, `temperatureMax` REAL, `windSpeed` REAL, `windDirection` TEXT, `rainSum` REAL NOT NULL, `snowfallSum` REAL, `uvIndexMax` REAL, `weatherCondition` TEXT NOT NULL, `time` INTEGER NOT NULL, `precipitationProbabilityMax` INTEGER, `pressureMsl` REAL, `visibility` INTEGER, `humidity` REAL, `dewPoint` REAL, `sunrise` INTEGER NOT NULL, `sunset` INTEGER NOT NULL, `moonrise` INTEGER NOT NULL, `moonset` INTEGER NOT NULL, `moonPhase` TEXT NOT NULL, `dawn` INTEGER NOT NULL, `dusk` INTEGER NOT NULL, PRIMARY KEY(`locationId`, `time`), FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "temperatureMin",
|
||||
"columnName": "temperatureMin",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "temperatureMax",
|
||||
"columnName": "temperatureMax",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "windSpeed",
|
||||
"columnName": "windSpeed",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "windDirection",
|
||||
"columnName": "windDirection",
|
||||
"affinity": "TEXT"
|
||||
},
|
||||
{
|
||||
"fieldPath": "rainSum",
|
||||
"columnName": "rainSum",
|
||||
"affinity": "REAL",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "snowfallSum",
|
||||
"columnName": "snowfallSum",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "uvIndexMax",
|
||||
"columnName": "uvIndexMax",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "weatherCondition",
|
||||
"columnName": "weatherCondition",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "precipitationProbabilityMax",
|
||||
"columnName": "precipitationProbabilityMax",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pressureMsl",
|
||||
"columnName": "pressureMsl",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "visibility",
|
||||
"columnName": "visibility",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "humidity",
|
||||
"columnName": "humidity",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "dewPoint",
|
||||
"columnName": "dewPoint",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "sunrise",
|
||||
"columnName": "sunrise",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "sunset",
|
||||
"columnName": "sunset",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "moonrise",
|
||||
"columnName": "moonrise",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "moonset",
|
||||
"columnName": "moonset",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "moonPhase",
|
||||
"columnName": "moonPhase",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dawn",
|
||||
"columnName": "dawn",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "dusk",
|
||||
"columnName": "dusk",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"locationId",
|
||||
"time"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_weather_daily_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_weather_daily_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "weather_units",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `tempUnit` TEXT NOT NULL, `windUnit` TEXT NOT NULL, `distanceUnit` TEXT NOT NULL, `pressureUnit` TEXT NOT NULL, `precipitationUnit` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "tempUnit",
|
||||
"columnName": "tempUnit",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "windUnit",
|
||||
"columnName": "windUnit",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "distanceUnit",
|
||||
"columnName": "distanceUnit",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pressureUnit",
|
||||
"columnName": "pressureUnit",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "precipitationUnit",
|
||||
"columnName": "precipitationUnit",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tableName": "weather_blocks",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `isDaily` INTEGER NOT NULL, `type` TEXT NOT NULL, `isHidden` INTEGER NOT NULL, `position` INTEGER NOT NULL)",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isDaily",
|
||||
"columnName": "isDaily",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "type",
|
||||
"columnName": "type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isHidden",
|
||||
"columnName": "isHidden",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "position",
|
||||
"columnName": "position",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tableName": "air_quality_current",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`locationId` TEXT NOT NULL, `usAqi` INTEGER, `pm10` REAL, `pm25` REAL, `carbonMonoxide` REAL, `nitrogenDioxide` REAL, `sulphurDioxide` REAL, `ozone` REAL, `lastUpdatedInMilli` INTEGER NOT NULL, PRIMARY KEY(`locationId`), FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "usAqi",
|
||||
"columnName": "usAqi",
|
||||
"affinity": "INTEGER"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pm10",
|
||||
"columnName": "pm10",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pm25",
|
||||
"columnName": "pm25",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "carbonMonoxide",
|
||||
"columnName": "carbonMonoxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "nitrogenDioxide",
|
||||
"columnName": "nitrogenDioxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "sulphurDioxide",
|
||||
"columnName": "sulphurDioxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "ozone",
|
||||
"columnName": "ozone",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastUpdatedInMilli",
|
||||
"columnName": "lastUpdatedInMilli",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_air_quality_current_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_air_quality_current_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "nws_location_gridpoints",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`locationId` TEXT NOT NULL, `officeId` TEXT NOT NULL, `gridX` INTEGER NOT NULL, `gridY` INTEGER NOT NULL, `stationIdentifier` TEXT NOT NULL, `lastUpdatedMilli` INTEGER NOT NULL, PRIMARY KEY(`locationId`), FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "officeId",
|
||||
"columnName": "officeId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gridX",
|
||||
"columnName": "gridX",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "gridY",
|
||||
"columnName": "gridY",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "stationIdentifier",
|
||||
"columnName": "stationIdentifier",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastUpdatedMilli",
|
||||
"columnName": "lastUpdatedMilli",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_nws_location_gridpoints_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_nws_location_gridpoints_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "github",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `currentTag` TEXT NOT NULL, `lastFetchedTag` TEXT NOT NULL, `lastFetchedTime` INTEGER NOT NULL, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "currentTag",
|
||||
"columnName": "currentTag",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastFetchedTag",
|
||||
"columnName": "lastFetchedTag",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastFetchedTime",
|
||||
"columnName": "lastFetchedTime",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": false,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tableName": "air_quality_hourly",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `locationId` TEXT NOT NULL, `pm10` REAL, `pm25` REAL, `carbonMonoxide` REAL, `nitrogenDioxide` REAL, `sulphurDioxide` REAL, `ozone` REAL, `time` INTEGER NOT NULL, FOREIGN KEY(`locationId`) REFERENCES `weather_locations`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "locationId",
|
||||
"columnName": "locationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "pm10",
|
||||
"columnName": "pm10",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "pm25",
|
||||
"columnName": "pm25",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "carbonMonoxide",
|
||||
"columnName": "carbonMonoxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "nitrogenDioxide",
|
||||
"columnName": "nitrogenDioxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "sulphurDioxide",
|
||||
"columnName": "sulphurDioxide",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "ozone",
|
||||
"columnName": "ozone",
|
||||
"affinity": "REAL"
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"autoGenerate": true,
|
||||
"columnNames": [
|
||||
"id"
|
||||
]
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_air_quality_hourly_locationId",
|
||||
"unique": false,
|
||||
"columnNames": [
|
||||
"locationId"
|
||||
],
|
||||
"orders": [],
|
||||
"createSql": "CREATE INDEX IF NOT EXISTS `index_air_quality_hourly_locationId` ON `${TABLE_NAME}` (`locationId`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "weather_locations",
|
||||
"onDelete": "CASCADE",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"locationId"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"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, '5ca7c9b34ef5941f3d7515379d9646f9')"
|
||||
]
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -1,5 +1,7 @@
|
||||
package com.pranshulgg.weather_master_app.core.model.domain.location
|
||||
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AirQualitySource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AlertSource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.WeatherSource
|
||||
|
||||
data class Location(
|
||||
@@ -15,5 +17,8 @@ data class Location(
|
||||
val isFavorite: Boolean = false,
|
||||
val isPinned: Boolean = false,
|
||||
val isDefault: Boolean,
|
||||
val isDeviceLocation: Boolean = false
|
||||
val isDeviceLocation: Boolean = false,
|
||||
val alertSource: AlertSource = AlertSource.NONE,
|
||||
val airQualitySource: AirQualitySource = AirQualitySource.OPEN_METEO,
|
||||
val customName: String? = null
|
||||
)
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.pranshulgg.weather_master_app.core.model.sources
|
||||
|
||||
enum class AirQualitySource(
|
||||
val displayName: String,
|
||||
val displayLink: String,
|
||||
val fullName: String
|
||||
|
||||
) {
|
||||
NONE(displayName = "None", fullName = "", displayLink = ""),
|
||||
ACCU_WEATHER(
|
||||
displayName = "AccuWeather",
|
||||
fullName = "AccuWeather",
|
||||
displayLink = "https://www.accuweather.com/"
|
||||
),
|
||||
OPEN_METEO(
|
||||
displayName = "Open Meteo",
|
||||
fullName = "Open Meteo",
|
||||
displayLink = "https://open-meteo.com/"
|
||||
),
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.pranshulgg.weather_master_app.core.model.sources
|
||||
|
||||
|
||||
enum class AlertSource(
|
||||
val displayName: String,
|
||||
val displayLink: String,
|
||||
val fullName: String
|
||||
|
||||
) {
|
||||
NONE(displayName = "None", fullName = "", displayLink = ""),
|
||||
ACCU_WEATHER(
|
||||
displayName = "AccuWeather",
|
||||
fullName = "AccuWeather",
|
||||
displayLink = "https://www.accuweather.com/"
|
||||
),
|
||||
WEATHER_API(
|
||||
displayName = "WeatherApi",
|
||||
fullName = "WeatherApi.com",
|
||||
displayLink = "https://www.weatherapi.com/"
|
||||
),
|
||||
|
||||
}
|
||||
+3
@@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.FabPosition
|
||||
import androidx.compose.material3.LargeFlexibleTopAppBar
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
@@ -24,6 +25,7 @@ fun LargeTopBarScaffold(
|
||||
fab: @Composable () -> Unit = {},
|
||||
bottomBar: @Composable (() -> Unit) = {},
|
||||
defaultCollapsed: Boolean = false,
|
||||
floatingActionButtonPosition: FabPosition = FabPosition.End,
|
||||
content: @Composable (PaddingValues) -> Unit,
|
||||
) {
|
||||
|
||||
@@ -43,6 +45,7 @@ fun LargeTopBarScaffold(
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
containerColor = MaterialTheme.colorScheme.surfaceContainer,
|
||||
floatingActionButton = fab,
|
||||
floatingActionButtonPosition = floatingActionButtonPosition,
|
||||
topBar = {
|
||||
LargeFlexibleTopAppBar(
|
||||
title = { Text(text = title) },
|
||||
|
||||
+6
-2
@@ -92,7 +92,9 @@ sealed class SettingTile {
|
||||
val onTextSubmitted: (String) -> Unit,
|
||||
val placeholder: String,
|
||||
val placeholderTextField: String,
|
||||
val initialText: String = ""
|
||||
val initialText: String = "",
|
||||
val trailing: (@Composable (() -> Unit))? = null,
|
||||
val placeholderAsValue: Boolean = false
|
||||
) : SettingTile()
|
||||
|
||||
data class DialogSliderTile(
|
||||
@@ -247,7 +249,9 @@ fun SettingSection(
|
||||
placeholder = tile.placeholder,
|
||||
placeholderTextField = tile.placeholderTextField,
|
||||
initialText = tile.initialText,
|
||||
itemBgColor = itemBgColor
|
||||
itemBgColor = itemBgColor,
|
||||
trailing = tile.trailing,
|
||||
placeholderAsValue = tile.placeholderAsValue
|
||||
)
|
||||
|
||||
is SettingTile.DialogSliderTile -> DialogSliderTile(
|
||||
|
||||
+9
-3
@@ -20,7 +20,9 @@ fun DialogTextFieldTile(
|
||||
placeholder: String,
|
||||
placeholderTextField: String,
|
||||
shapes: RoundedCornerShape,
|
||||
itemBgColor: Color
|
||||
itemBgColor: Color,
|
||||
trailing: (@Composable (() -> Unit))? = null,
|
||||
placeholderAsValue: Boolean = false
|
||||
) {
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
var textFieldValue by remember { mutableStateOf(initialText) }
|
||||
@@ -37,17 +39,21 @@ fun DialogTextFieldTile(
|
||||
leadingContent = leading,
|
||||
headlineContent = { Text(headline) },
|
||||
supportingContent = {
|
||||
if (description != null) Text(description)
|
||||
if (description != null) Text(
|
||||
description,
|
||||
color = if (placeholderAsValue) MaterialTheme.colorScheme.tertiary else Color.Unspecified
|
||||
)
|
||||
else if (textFieldValue.isNotEmpty()) Text(
|
||||
textFieldValue,
|
||||
color = MaterialTheme.colorScheme.tertiary
|
||||
) else {
|
||||
Text(
|
||||
placeholder,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
color = if (placeholderAsValue) MaterialTheme.colorScheme.tertiary else MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
},
|
||||
trailingContent = trailing
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+18
-8
@@ -21,16 +21,17 @@ import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.navigation
|
||||
import androidx.navigation.navArgument
|
||||
import com.pranshulgg.weather_master_app.feature.blocks.screens.humidity.HumidityScreen
|
||||
import com.pranshulgg.weather_master_app.feature.blocks.screens.pressure.PressureScreen
|
||||
import com.pranshulgg.weather_master_app.feature.blocks.screens.SunMoonScreen
|
||||
import com.pranshulgg.weather_master_app.feature.blocks.screens.airquality.AirQualityScreen
|
||||
import com.pranshulgg.weather_master_app.feature.blocks.screens.humidity.HumidityScreen
|
||||
import com.pranshulgg.weather_master_app.feature.blocks.screens.precipitation.RainScreen
|
||||
import com.pranshulgg.weather_master_app.feature.blocks.screens.precipitation.SnowScreen
|
||||
import com.pranshulgg.weather_master_app.feature.blocks.screens.pressure.PressureScreen
|
||||
import com.pranshulgg.weather_master_app.feature.blocks.screens.uvindex.UvIndexScreen
|
||||
import com.pranshulgg.weather_master_app.feature.blocks.screens.visibility.VisibilityScreen
|
||||
import com.pranshulgg.weather_master_app.feature.blocks.screens.wind.WindScreen
|
||||
import com.pranshulgg.weather_master_app.feature.daily.DailyScreen
|
||||
import com.pranshulgg.weather_master_app.feature.editlocation.EditLocationScreen
|
||||
import com.pranshulgg.weather_master_app.feature.main.MainScreen
|
||||
import com.pranshulgg.weather_master_app.feature.search.SearchScreen
|
||||
import com.pranshulgg.weather_master_app.feature.settings.SettingsScreen
|
||||
@@ -66,12 +67,8 @@ fun AppNavHost(
|
||||
) {
|
||||
navigation(
|
||||
route = "root",
|
||||
startDestination = NavRoutes.MAIN
|
||||
// startDestination = NavRoutes.blockScreen(
|
||||
// NavRoutes.AIR_QUALITY,
|
||||
// 0,
|
||||
// "ab73f0ac-0dd9-410b-aa85-c944abfdcf60"
|
||||
// )
|
||||
// startDestination = NavRoutes.MAIN
|
||||
startDestination = NavRoutes.editLocation("af673c89-72b7-4da9-865d-c26fdabeca07")
|
||||
) {
|
||||
composable(
|
||||
NavRoutes.MAIN
|
||||
@@ -156,6 +153,19 @@ fun AppNavHost(
|
||||
) {
|
||||
WorkerInfoScreen(navController)
|
||||
}
|
||||
composable(
|
||||
route = "${NavRoutes.EDIT_LOCATION}/{locationId}",
|
||||
arguments = listOf(
|
||||
navArgument("locationId") {
|
||||
type = NavType.StringType
|
||||
}
|
||||
)
|
||||
) { backStackEntry ->
|
||||
|
||||
val locationId = backStackEntry.arguments?.getString("locationId")
|
||||
|
||||
EditLocationScreen(navController, locationId!!)
|
||||
}
|
||||
composable(
|
||||
route = "{block}/{index}/{locationId}",
|
||||
arguments = listOf(
|
||||
|
||||
@@ -45,6 +45,12 @@ object NavRoutes {
|
||||
|
||||
const val WORKER_INFO = "worker_info"
|
||||
|
||||
const val EDIT_LOCATION = "edit_location"
|
||||
|
||||
fun editLocation(locationId: String): String {
|
||||
return "$EDIT_LOCATION/$locationId"
|
||||
}
|
||||
|
||||
fun blockScreen(block: String, index: Int, locationId: String): String {
|
||||
return "$block/$index/$locationId"
|
||||
}
|
||||
|
||||
+12
-3
@@ -38,12 +38,13 @@ import com.pranshulgg.weather_master_app.data.local.entity.weather.nws.NwsGridPo
|
||||
GithubEntity::class,
|
||||
HourlyAirQualityEntity::class
|
||||
],
|
||||
version = 46,
|
||||
version = 48,
|
||||
autoMigrations = [
|
||||
AutoMigration(from = 39, to = 40),
|
||||
AutoMigration(from = 42, to = 43),
|
||||
AutoMigration(from = 43, to = 44),
|
||||
AutoMigration(from = 44, to = 45)
|
||||
AutoMigration(from = 44, to = 45),
|
||||
AutoMigration(from = 47, to = 48)
|
||||
]
|
||||
)
|
||||
abstract class WeatherMasterDatabase : RoomDatabase() {
|
||||
@@ -67,7 +68,8 @@ abstract class WeatherMasterDatabase : RoomDatabase() {
|
||||
context.applicationContext,
|
||||
WeatherMasterDatabase::class.java,
|
||||
"weather_master.db"
|
||||
).addMigrations(MIGRATION_40_41, MIGRATION_41_42, MIGRATION_45_46).build()
|
||||
).addMigrations(MIGRATION_40_41, MIGRATION_41_42, MIGRATION_45_46, MIGRATION_46_47)
|
||||
.build()
|
||||
.also { INSTANCE = it }
|
||||
}
|
||||
}
|
||||
@@ -144,4 +146,11 @@ val MIGRATION_45_46 = object : Migration(45, 46) {
|
||||
"CREATE INDEX IF NOT EXISTS index_air_quality_hourly_locationId ON air_quality_hourly(locationId)"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val MIGRATION_46_47 = object : Migration(46, 47) {
|
||||
override fun migrate(db: SupportSQLiteDatabase) {
|
||||
db.execSQL("ALTER TABLE weather_locations ADD COLUMN alertSource TEXT NOT NULL DEFAULT 'NONE'")
|
||||
db.execSQL("ALTER TABLE weather_locations ADD COLUMN airQualitySource TEXT NOT NULL DEFAULT 'OPEN_METEO'")
|
||||
}
|
||||
}
|
||||
+7
@@ -5,6 +5,7 @@ import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AirQualitySource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.WeatherSource
|
||||
import com.pranshulgg.weather_master_app.data.local.entity.location.WeatherLocationEntity
|
||||
import com.pranshulgg.weather_master_app.data.local.entity.weather.WeatherWithRelations
|
||||
@@ -72,4 +73,10 @@ interface LocationsDao {
|
||||
|
||||
@Query("SELECT * FROM weather_locations WHERE isDeviceLocation = 1 LIMIT 1")
|
||||
suspend fun getDeviceLocation(): WeatherLocationEntity
|
||||
|
||||
@Query("SELECT * FROM weather_locations WHERE id = :id LIMIT 1")
|
||||
suspend fun getLocationForId(id: String): WeatherLocationEntity
|
||||
|
||||
@Query("UPDATE weather_locations SET airQualitySource = :source WHERE id = :id")
|
||||
suspend fun updateAirQualitySourceForLocation(id: String, source: AirQualitySource)
|
||||
}
|
||||
+6
-2
@@ -2,6 +2,8 @@ package com.pranshulgg.weather_master_app.data.local.entity.location
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AirQualitySource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AlertSource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.WeatherSource
|
||||
import kotlin.uuid.ExperimentalUuidApi
|
||||
|
||||
@@ -22,6 +24,8 @@ data class WeatherLocationEntity(
|
||||
val isPinned: Boolean = false,
|
||||
val countryCode: String? = null,
|
||||
val isDefault: Boolean = false,
|
||||
val isDeviceLocation: Boolean = false
|
||||
|
||||
val isDeviceLocation: Boolean = false,
|
||||
val alertSource: AlertSource,
|
||||
val airQualitySource: AirQualitySource,
|
||||
val customName: String? = null
|
||||
)
|
||||
+8
-2
@@ -66,7 +66,10 @@ fun Location.toEntity(): WeatherLocationEntity =
|
||||
isPinned = false,
|
||||
isFavorite = false,
|
||||
isDefault = isDefault,
|
||||
isDeviceLocation = isDeviceLocation
|
||||
isDeviceLocation = isDeviceLocation,
|
||||
alertSource = alertSource,
|
||||
airQualitySource = airQualitySource,
|
||||
customName = customName
|
||||
)
|
||||
|
||||
fun List<WeatherLocationEntity>.toDomain(): List<Location> =
|
||||
@@ -88,5 +91,8 @@ fun WeatherLocationEntity.toDomain(): Location =
|
||||
isFavorite = isFavorite,
|
||||
isPinned = isPinned,
|
||||
isDefault = isDefault,
|
||||
isDeviceLocation = isDeviceLocation
|
||||
isDeviceLocation = isDeviceLocation,
|
||||
alertSource = alertSource,
|
||||
airQualitySource = airQualitySource,
|
||||
customName = customName
|
||||
)
|
||||
+9
@@ -7,6 +7,7 @@ import com.pranshulgg.weather_master_app.core.model.domain.AppException
|
||||
import com.pranshulgg.weather_master_app.core.model.domain.airquality.AirQuality
|
||||
import com.pranshulgg.weather_master_app.core.model.domain.location.Location
|
||||
import com.pranshulgg.weather_master_app.core.model.domain.weather.Weather
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AirQualitySource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.WeatherSource
|
||||
import com.pranshulgg.weather_master_app.core.network.sources.address.nominatim.json.NominatimRepository
|
||||
import com.pranshulgg.weather_master_app.data.local.dao.airquality.AirQualityDao
|
||||
@@ -74,6 +75,14 @@ class LocationsRepository @Inject constructor(
|
||||
dao.updateSourceForLocation(id, source)
|
||||
}
|
||||
|
||||
suspend fun updateAirQualitySourceForLocation(id: String, source: AirQualitySource) {
|
||||
dao.updateAirQualitySourceForLocation(id, source)
|
||||
}
|
||||
|
||||
suspend fun getLocationForId(id: String): Location {
|
||||
return dao.getLocationForId(id).toDomain()
|
||||
}
|
||||
|
||||
|
||||
@Transaction
|
||||
suspend fun saveLocation(location: Location) {
|
||||
|
||||
+256
@@ -0,0 +1,256 @@
|
||||
package com.pranshulgg.weather_master_app.feature.editlocation
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.systemBars
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.FabPosition
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.SheetValue
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.rememberBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.navigation.NavController
|
||||
import com.pranshulgg.weather_master_app.R
|
||||
import com.pranshulgg.weather_master_app.core.model.domain.location.Location
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AirQualitySource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AlertSource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.WeatherSource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.getWeatherSourcesForCountry
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.getWeatherSourcesGlobal
|
||||
import com.pranshulgg.weather_master_app.core.ui.components.Gap
|
||||
import com.pranshulgg.weather_master_app.core.ui.components.LargeTopBarScaffold
|
||||
import com.pranshulgg.weather_master_app.core.ui.components.NavigateUpBtn
|
||||
import com.pranshulgg.weather_master_app.core.ui.components.SettingSection
|
||||
import com.pranshulgg.weather_master_app.core.ui.components.SettingTile
|
||||
import com.pranshulgg.weather_master_app.core.ui.components.Symbol
|
||||
import com.pranshulgg.weather_master_app.feature.editlocation.ui.EditLocationBottomSheet
|
||||
import com.pranshulgg.weather_master_app.feature.shared.ui.SharedBottomSheet
|
||||
|
||||
|
||||
data class EditLocationScreenUiState(
|
||||
val location: Location? = null,
|
||||
val isWeatherSourcesForLocationSheetOpen: Boolean = false,
|
||||
val selectedWeatherSource: WeatherSource? = null,
|
||||
val selectedAlertSource: AlertSource? = null,
|
||||
val selectedAirQualitySource: AirQualitySource? = null,
|
||||
val isAlertSourcesSheetOpen: Boolean = false,
|
||||
val isAirQualitySourcesSheetOpen: Boolean = false,
|
||||
val isEditLocationNameSheetOpen: Boolean = false
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun EditLocationScreen(
|
||||
navController: NavController, id: String
|
||||
) {
|
||||
|
||||
val viewModel: EditLocationViewModel = hiltViewModel()
|
||||
val uiState = viewModel.uiState.value
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.getLocationForId(id)
|
||||
}
|
||||
|
||||
if (uiState.location == null) return
|
||||
|
||||
val btnSize = ButtonDefaults.MediumContainerHeight
|
||||
|
||||
val sheetState = rememberBottomSheetState(
|
||||
initialValue = SheetValue.Hidden,
|
||||
enabledValues = setOf(SheetValue.Expanded, SheetValue.Hidden)
|
||||
)
|
||||
|
||||
val colorDesc = MaterialTheme.colorScheme.tertiary
|
||||
|
||||
|
||||
val locationText = buildString {
|
||||
append(uiState.location.name)
|
||||
if (uiState.location.country.isNotBlank()) {
|
||||
append(", ")
|
||||
}
|
||||
if (uiState.location.state.isNotBlank()) {
|
||||
append(uiState.location.state)
|
||||
append(", ")
|
||||
}
|
||||
append(uiState.location.country)
|
||||
}
|
||||
|
||||
val locationName = if (!uiState.location.customName.isNullOrBlank()) uiState.location.customName
|
||||
else locationText
|
||||
|
||||
var currentLocationName by remember { mutableStateOf(locationName) }
|
||||
|
||||
|
||||
LargeTopBarScaffold(
|
||||
title = stringResource(R.string.location_edit),
|
||||
navigationIcon = { NavigateUpBtn(navController) },
|
||||
floatingActionButtonPosition = FabPosition.Center,
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(top = paddingValues.calculateTopPadding())
|
||||
) {
|
||||
SettingSection(
|
||||
tiles = listOf(
|
||||
SettingTile.ActionTile(
|
||||
title = "Location name",
|
||||
description = currentLocationName,
|
||||
onClick = {
|
||||
viewModel.showEditLocationNameSheet()
|
||||
},
|
||||
trailing = {
|
||||
IconButton(onClick = { currentLocationName = locationName }) {
|
||||
Symbol(R.drawable.refresh_24px)
|
||||
}
|
||||
},
|
||||
colorDesc = colorDesc
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Gap(10.dp)
|
||||
SettingSection(
|
||||
tiles = listOf(
|
||||
SettingTile.ActionTile(
|
||||
title = "Weather source",
|
||||
description = uiState.selectedWeatherSource?.displayName
|
||||
?: uiState.location.source.displayName,
|
||||
colorDesc = colorDesc,
|
||||
onClick = {
|
||||
viewModel.showWeatherSourcesForLocationSheet()
|
||||
}
|
||||
),
|
||||
SettingTile.ActionTile(
|
||||
title = "Alert source",
|
||||
description = uiState.selectedAlertSource?.displayName
|
||||
?: uiState.location.alertSource.displayName,
|
||||
colorDesc = colorDesc,
|
||||
onClick = {
|
||||
viewModel.showAlertSourcesSheet()
|
||||
}
|
||||
),
|
||||
SettingTile.ActionTile(
|
||||
title = "Air quality source",
|
||||
description = uiState.selectedAirQualitySource?.displayName
|
||||
?: uiState.location.airQualitySource.displayName,
|
||||
colorDesc = colorDesc,
|
||||
onClick = {
|
||||
viewModel.showAirQualitySourcesSheet()
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
Text(
|
||||
"Latitude: ${uiState.location.latitude}, Longitude: ${uiState.location.longitude}",
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
modifier = Modifier.padding(top = 10.dp, start = 16.dp, end = 16.dp)
|
||||
)
|
||||
Gap(26.dp)
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.heightIn(btnSize)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
onClick = { /* Handle click */ },
|
||||
shapes = ButtonDefaults.shapes(),
|
||||
contentPadding = ButtonDefaults.contentPaddingFor(btnSize),
|
||||
) {
|
||||
Symbol(
|
||||
R.drawable.check_24px,
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||
size = ButtonDefaults.iconSizeFor(btnSize)
|
||||
)
|
||||
Gap(horizontal = ButtonDefaults.iconSpacingFor(btnSize))
|
||||
Text(
|
||||
stringResource(R.string.action_save_changes),
|
||||
style = ButtonDefaults.textStyleFor(btnSize),
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
}
|
||||
|
||||
// WEATHER SOURCES SHEET
|
||||
SharedBottomSheet.WeatherSourcesForLocationSheet(
|
||||
countryCode = uiState.location.countryCode,
|
||||
show = uiState.isWeatherSourcesForLocationSheetOpen,
|
||||
isEditing = true,
|
||||
selectedSource = uiState.selectedWeatherSource ?: uiState.location.source,
|
||||
onSave = {
|
||||
viewModel.updateSelectedWeatherSource(it)
|
||||
},
|
||||
onDismiss = viewModel::hideWeatherSourcesForLocationSheet,
|
||||
sheetState = sheetState
|
||||
)
|
||||
|
||||
|
||||
// ALERT SOURCES SHEET
|
||||
EditLocationBottomSheet.AlertSourcesSheet(
|
||||
show = uiState.isAlertSourcesSheetOpen,
|
||||
sheetState = sheetState,
|
||||
selectedSource = uiState.selectedAlertSource ?: uiState.location.alertSource,
|
||||
onSave = {
|
||||
viewModel.updateSelectedAlertSource(it)
|
||||
},
|
||||
onDismiss = viewModel::hideAlertSourcesSheet
|
||||
)
|
||||
|
||||
// AIR QUALITY SOURCES SHEET
|
||||
EditLocationBottomSheet.AirQualitySourcesSheet(
|
||||
show = uiState.isAirQualitySourcesSheetOpen,
|
||||
sheetState = sheetState,
|
||||
selectedSource = uiState.selectedAirQualitySource
|
||||
?: uiState.location.airQualitySource,
|
||||
onSave = {
|
||||
viewModel.updateSelectedAirQualitySource(it)
|
||||
},
|
||||
onDismiss = viewModel::hideAirQualitySourcesSheet
|
||||
)
|
||||
|
||||
// EDIT LOCATION NAME SHEET
|
||||
EditLocationBottomSheet.EditLocationNameSheet(
|
||||
show = uiState.isEditLocationNameSheetOpen,
|
||||
sheetState = sheetState,
|
||||
onDismiss = {
|
||||
viewModel.hideEditLocationNameSheet()
|
||||
},
|
||||
onSave = {
|
||||
if (it.isNotBlank()) {
|
||||
currentLocationName = it
|
||||
}
|
||||
},
|
||||
value = currentLocationName,
|
||||
)
|
||||
|
||||
Gap(WindowInsets.systemBars.asPaddingValues().calculateBottomPadding())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package com.pranshulgg.weather_master_app.feature.editlocation
|
||||
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.pranshulgg.weather_master_app.R
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AirQualitySource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AlertSource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.WeatherSource
|
||||
import com.pranshulgg.weather_master_app.core.ui.snackbar.SnackbarManager
|
||||
import com.pranshulgg.weather_master_app.data.repository.LocationsRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
@HiltViewModel
|
||||
class EditLocationViewModel @Inject constructor(
|
||||
private val locationsRepo: LocationsRepository,
|
||||
) : ViewModel() {
|
||||
|
||||
private var _uiState = mutableStateOf(EditLocationScreenUiState())
|
||||
val uiState: State<EditLocationScreenUiState> = _uiState
|
||||
|
||||
fun getLocationForId(id: String) {
|
||||
viewModelScope.launch {
|
||||
val location = locationsRepo.getLocationForId(id)
|
||||
_uiState.value = _uiState.value.copy(location = location)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun showWeatherSourcesForLocationSheet() {
|
||||
_uiState.value = _uiState.value.copy(isWeatherSourcesForLocationSheetOpen = true)
|
||||
}
|
||||
|
||||
fun hideWeatherSourcesForLocationSheet() {
|
||||
_uiState.value = _uiState.value.copy(isWeatherSourcesForLocationSheetOpen = false)
|
||||
}
|
||||
|
||||
fun updateSelectedWeatherSource(source: WeatherSource) {
|
||||
_uiState.value = _uiState.value.copy(selectedWeatherSource = source)
|
||||
}
|
||||
|
||||
fun updateSelectedAlertSource(source: AlertSource) {
|
||||
_uiState.value = _uiState.value.copy(selectedAlertSource = source)
|
||||
}
|
||||
|
||||
fun updateSelectedAirQualitySource(source: AirQualitySource) {
|
||||
_uiState.value = _uiState.value.copy(selectedAirQualitySource = source)
|
||||
}
|
||||
|
||||
fun showAlertSourcesSheet() {
|
||||
_uiState.value = _uiState.value.copy(isAlertSourcesSheetOpen = true)
|
||||
}
|
||||
|
||||
fun hideAlertSourcesSheet() {
|
||||
_uiState.value = _uiState.value.copy(isAlertSourcesSheetOpen = false)
|
||||
}
|
||||
|
||||
fun showAirQualitySourcesSheet() {
|
||||
_uiState.value = _uiState.value.copy(isAirQualitySourcesSheetOpen = true)
|
||||
}
|
||||
|
||||
fun hideAirQualitySourcesSheet() {
|
||||
_uiState.value = _uiState.value.copy(isAirQualitySourcesSheetOpen = false)
|
||||
}
|
||||
|
||||
fun showEditLocationNameSheet() {
|
||||
_uiState.value = _uiState.value.copy(isEditLocationNameSheetOpen = true)
|
||||
}
|
||||
|
||||
fun hideEditLocationNameSheet() {
|
||||
_uiState.value = _uiState.value.copy(isEditLocationNameSheetOpen = false)
|
||||
}
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
package com.pranshulgg.weather_master_app.feature.editlocation.ui
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pranshulgg.weather_master_app.R
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AirQualitySource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AlertSource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.WeatherSource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.getWeatherSourcesForCountry
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.getWeatherSourcesGlobal
|
||||
import com.pranshulgg.weather_master_app.core.ui.components.ActionBottomSheet
|
||||
import com.pranshulgg.weather_master_app.core.ui.components.Gap
|
||||
import com.pranshulgg.weather_master_app.core.ui.components.SettingSection
|
||||
import com.pranshulgg.weather_master_app.core.ui.components.SettingTile
|
||||
import com.pranshulgg.weather_master_app.core.ui.components.Symbol
|
||||
|
||||
|
||||
object EditLocationBottomSheet {
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun EditLocationNameSheet(
|
||||
show: Boolean,
|
||||
sheetState: SheetState,
|
||||
onDismiss: () -> Unit,
|
||||
onSave: (String) -> Unit,
|
||||
value: String
|
||||
) {
|
||||
if (show) {
|
||||
|
||||
var currentText by remember { mutableStateOf(value) }
|
||||
|
||||
ActionBottomSheet(
|
||||
sheetState = sheetState,
|
||||
onCancel = { onDismiss() },
|
||||
onConfirm = { onSave(currentText) },
|
||||
confirmText = stringResource(R.string.action_save),
|
||||
cancelText = stringResource(R.string.action_cancel)
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = currentText,
|
||||
onValueChange = { currentText = it },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
placeholder = { Text("Name") },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun AlertSourcesSheet(
|
||||
show: Boolean,
|
||||
sheetState: SheetState,
|
||||
selectedSource: AlertSource = AlertSource.NONE,
|
||||
onSave: (AlertSource) -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
if (show) {
|
||||
|
||||
var currentSelectedSource by remember(
|
||||
show,
|
||||
selectedSource
|
||||
) {
|
||||
mutableStateOf(selectedSource)
|
||||
}
|
||||
|
||||
ActionBottomSheet(
|
||||
sheetState = sheetState,
|
||||
onCancel = { onDismiss() },
|
||||
onConfirm = { onSave(currentSelectedSource) },
|
||||
confirmText = stringResource(R.string.action_save),
|
||||
cancelText = stringResource(R.string.action_cancel)
|
||||
) {
|
||||
SettingSection(
|
||||
title = stringResource(R.string.global_sources),
|
||||
tiles = AlertSource.entries.map { source ->
|
||||
val isSelected = currentSelectedSource == source
|
||||
|
||||
SettingTile.ActionTile(
|
||||
leading = {
|
||||
if (isSelected) Symbol(
|
||||
R.drawable.check_24px,
|
||||
color = MaterialTheme.colorScheme.onSecondaryContainer
|
||||
)
|
||||
},
|
||||
title = source.displayName,
|
||||
selected = isSelected,
|
||||
onClick = {
|
||||
currentSelectedSource = source
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun AirQualitySourcesSheet(
|
||||
show: Boolean,
|
||||
sheetState: SheetState,
|
||||
selectedSource: AirQualitySource = AirQualitySource.OPEN_METEO,
|
||||
onSave: (AirQualitySource) -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
if (show) {
|
||||
|
||||
var currentSelectedSource by remember(
|
||||
show,
|
||||
selectedSource
|
||||
) {
|
||||
mutableStateOf(selectedSource)
|
||||
}
|
||||
|
||||
ActionBottomSheet(
|
||||
sheetState = sheetState,
|
||||
onCancel = { onDismiss() },
|
||||
onConfirm = { onSave(currentSelectedSource) },
|
||||
confirmText = stringResource(R.string.action_save),
|
||||
cancelText = stringResource(R.string.action_cancel)
|
||||
) {
|
||||
SettingSection(
|
||||
title = stringResource(R.string.global_sources),
|
||||
tiles = AirQualitySource.entries.map { source ->
|
||||
val isSelected = currentSelectedSource == source
|
||||
|
||||
SettingTile.ActionTile(
|
||||
leading = {
|
||||
if (isSelected) Symbol(
|
||||
R.drawable.check_24px,
|
||||
color = MaterialTheme.colorScheme.onSecondaryContainer
|
||||
)
|
||||
},
|
||||
title = source.displayName,
|
||||
selected = isSelected,
|
||||
onClick = {
|
||||
currentSelectedSource = source
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -173,13 +173,13 @@ private fun UseDeviceLocationCard(onClick: () -> Unit, isLoading: Boolean = fals
|
||||
},
|
||||
headlineContent = {
|
||||
Text(
|
||||
"Use current location",
|
||||
stringResource(R.string.location_use_current),
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
},
|
||||
supportingContent = {
|
||||
Text(
|
||||
"Detect your device’s current location automatically and add it to your list",
|
||||
stringResource(R.string.location_use_current_secondary),
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
},
|
||||
|
||||
+37
-1
@@ -10,6 +10,7 @@ import com.pranshulgg.weather_master_app.core.model.domain.location.Location
|
||||
import com.pranshulgg.weather_master_app.core.model.domain.toAppException
|
||||
import com.pranshulgg.weather_master_app.core.model.domain.toMessageRes
|
||||
import com.pranshulgg.weather_master_app.core.model.domain.weather.WeatherBlock
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.AirQualitySource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.WeatherSource
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.isGlobal
|
||||
import com.pranshulgg.weather_master_app.core.model.sources.isSourceSupportedFor
|
||||
@@ -106,7 +107,8 @@ class WeatherViewModel @Inject constructor(
|
||||
location: Location,
|
||||
source: WeatherSource,
|
||||
isManualRefresh: Boolean = false,
|
||||
isForceRefresh: Boolean = false
|
||||
isForceRefresh: Boolean = false,
|
||||
isForceRefreshForAirQuality: Boolean = false
|
||||
) {
|
||||
setLoading(true)
|
||||
weatherJob?.cancel()
|
||||
@@ -190,6 +192,40 @@ class WeatherViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
|
||||
private fun handleSourceChangeForWeather(
|
||||
location: Location,
|
||||
source: WeatherSource,
|
||||
airQualitySource: AirQualitySource,
|
||||
) {
|
||||
val updatedLocation = location.copy(source = source, airQualitySource = airQualitySource)
|
||||
|
||||
viewModelScope.launch {
|
||||
|
||||
locationsRepo.updateSourceForLocation(location.id, source)
|
||||
locationsRepo.updateAirQualitySourceForLocation(location.id, airQualitySource)
|
||||
|
||||
val allowForceRefreshForWeather = location.source != source
|
||||
val allowForceRefreshForAirQuality = location.airQualitySource != airQualitySource
|
||||
|
||||
|
||||
if (allowForceRefreshForWeather) {
|
||||
weatherDataReconcilerRepository.cleanUpStaleData(location.source, location.id)
|
||||
}
|
||||
_uiState.value = _uiState.value.copy(
|
||||
activeLocation = updatedLocation
|
||||
)
|
||||
getWeather(
|
||||
updatedLocation,
|
||||
source,
|
||||
isForceRefresh = allowForceRefreshForWeather,
|
||||
isForceRefreshForAirQuality = allowForceRefreshForAirQuality
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun saveBlocks(
|
||||
items: List<WeatherBlock>,
|
||||
isDaily: Boolean = false
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<item quantity="other">%d tuntia sitten</item>
|
||||
</plurals>
|
||||
<plurals name="time_days_ago">
|
||||
<item quantity="one">% päivä sitten</item>
|
||||
<item quantity="one">%d päivä sitten</item>
|
||||
<item quantity="other">%d päivää sitten</item>
|
||||
</plurals>
|
||||
<string name="time_just_now">Juuri nyt</string>
|
||||
|
||||
@@ -360,6 +360,27 @@
|
||||
<string name="summary_overview_template_night_condition">Conditions will turn %1$s at night.</string>
|
||||
|
||||
<string name="gadgetbridge_not_available_error">Gadget bridge is not installed</string>
|
||||
|
||||
<string name="settings_worker_info">Worker information</string>
|
||||
<string name="settings_send_data_gadgetbridge">Send data to Gadgetbridge</string>
|
||||
<string name="aqi_PM25_full_label">Particulate matter less than 2.5 microns</string>
|
||||
<string name="aqi_PM10_full_label">Particulate matter less than 10 microns</string>
|
||||
<string name="aqi_CO_full_label">Carbon monoxide</string>
|
||||
<string name="aqi_NO2_full_label">Nitrogen Dioxide</string>
|
||||
<string name="aqi_SO2_full_label">Sulfur Dioxide</string>
|
||||
<string name="aqi_O3_full_label">Ground surface</string>
|
||||
<string name="settings_worker_info_successful_run">Last successful run</string>
|
||||
<string name="label_never">Never</string>
|
||||
<string name="worker_run_attempt">Run attempt</string>
|
||||
<string name="worker_tags">Tags</string>
|
||||
<string name="worker_next_schedule">Next schedule</string>
|
||||
|
||||
<string name="action_save_changes">Save changes</string>
|
||||
<string name="weather_alert_source">Alert source</string>
|
||||
<string name="location_edit">Edit location</string>
|
||||
<string name="weather_aqi_source">Air quality source</string>
|
||||
<string name="location_name">Location name</string>
|
||||
<string name="location_info">Location information</string>
|
||||
</resources>
|
||||
|
||||
<!--<string name=""></string>-->
|
||||
Reference in new issue
Block a user