Skip to content
Merged

Osmcal #6743

Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package de.westnordost.streetcomplete.data.osmcal

import de.westnordost.streetcomplete.data.ApplicationDbTestCase
import de.westnordost.streetcomplete.data.osm.mapdata.LatLon
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.time.Duration
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.hours

class CalendarEventsDaoTest : ApplicationDbTestCase() {
private lateinit var dao: CalendarEventsDao

@BeforeTest fun createDao() {
dao = CalendarEventsDao(database)
}

@Test
fun putAndGet() {
val tomorrow = Clock.System.now() + 1.days
val multiDayEventTomorrow = CalendarEvent(
id = 123L,
name = "multi day event",
startDate = tomorrow,
endDate = tomorrow + 1.days,
wholeDay = true,
position = LatLon(5.0, 1.5),
venue = "House",
address = "an address",
notified = false,
)
val eventSoon = CalendarEvent(
id = 124L,
name = "soon event",
startDate = tomorrow - 23.hours,
endDate = null,
wholeDay = false,
position = LatLon(-5.0, 2.5),
venue = "House2",
address = "an address2",
notified = false,
)
val yesterdayEvent = CalendarEvent(
id = 125L,
name = "yesterday event",
startDate = tomorrow - 2.days,
endDate = null,
wholeDay = false,
position = LatLon(-5.0, 2.5),
venue = "House3",
address = "an address3",
notified = false,
)

dao.putAll(listOf(multiDayEventTomorrow, eventSoon, yesterdayEvent))

// getting / marking as read one by one
assertEquals(2, dao.getUnreadCount())
assertEquals(eventSoon, dao.getFirstUnread())

dao.markRead(eventSoon.id)
assertEquals(1, dao.getUnreadCount())
assertEquals(multiDayEventTomorrow, dao.getFirstUnread())

dao.markRead(multiDayEventTomorrow.id)
assertEquals(0, dao.getUnreadCount())
assertEquals(null, dao.getFirstUnread())

// deleting yesterday's event
assertEquals(1, dao.deleteOld())

// new putAll doesn't overwrite existing records
dao.putAll(listOf(multiDayEventTomorrow, eventSoon, yesterdayEvent))
assertEquals(0, dao.getUnreadCount())
assertEquals(null, dao.getFirstUnread())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import de.westnordost.streetcomplete.data.ApplicationDbTestCase
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue

class UserLinksDaoTest : ApplicationDbTestCase() {
private lateinit var dao: UserLinksDao
Expand All @@ -17,6 +19,10 @@ class UserLinksDaoTest : ApplicationDbTestCase() {
dao.add(ONE)
dao.add(TWO)
assertEquals(listOf(ONE, TWO), dao.getAll())

assertTrue(dao.has(ONE))
assertTrue(dao.has(TWO))
assertFalse(dao.has(THREE))
}

@Test fun addAll() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import de.westnordost.streetcomplete.data.osm.geometry.elementGeometryModule
import de.westnordost.streetcomplete.data.osm.mapdata.mapDataModule
import de.westnordost.streetcomplete.data.osm.osmquests.osmQuestModule
import de.westnordost.streetcomplete.data.osmApiModule
import de.westnordost.streetcomplete.data.osmcal.calendarEventsModule
import de.westnordost.streetcomplete.data.osmnotes.edits.noteEditsModule
import de.westnordost.streetcomplete.data.osmnotes.notequests.osmNoteQuestModule
import de.westnordost.streetcomplete.data.osmnotes.notesModule
Expand Down Expand Up @@ -142,6 +143,7 @@ class StreetCompleteApplication : Application() {
urlConfigModule,
urlConfigModule,
weeklyOsmModule,
calendarEventsModule,
feedsModule,
androidModule
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,16 @@ fun MessageDialog(
}
)
}
is Message.NewCalendarEvent -> {
val uriHandler = LocalUriHandler.current
CalendarEventDialog(
event = message.event,
onDismissRequest = onDismissRequest,
onClickOpenEvent = { uriHandler.openUri(message.event.url) },
onToggleDontNotifyAgain = { dontNotifyAgain ->
onToggleDontNotifyAgain(Message.NewCalendarEvent::class, dontNotifyAgain)
}
)
}
}
}
3 changes: 2 additions & 1 deletion app/src/androidMain/res/values-en/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ Additionally, some overlays allow you to add new data at the position of a displ
If you are overwhelmed by the number of quests, you can always fine-tune which quests are displayed to you and in what order in the settings.</string>

<string name="weekly_osm_new_edition_title">New Edition!</string>
<string name="calendar_new_event_title">New OSM event in your area!</string>

<!-- Team mode -->

Expand Down Expand Up @@ -628,7 +629,7 @@ Before uploading your changes, the app checks with a &lt;a href="https://www.wes
<string name="pref_title_message_achievements">Unlocked achievements</string>
<string name="pref_title_message_weekly_osm">New editions of weeklyOSM</string>
<string name="pref_title_message_changelog">New app releases</string>

<string name="pref_title_message_calendar">New OSM events in your area</string>

<!-- Quest & overlay selection screen -->

Expand Down
3 changes: 2 additions & 1 deletion app/src/androidMain/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ Additionally, some overlays allow you to add new data at the position of a displ
If you are overwhelmed by the number of quests, you can always fine-tune which quests are displayed to you and in what order in the settings.</string>

<string name="weekly_osm_new_edition_title">New Edition!</string>
<string name="calendar_new_event_title">New OSM event in your area!</string>

<!-- Team mode -->

Expand Down Expand Up @@ -628,7 +629,7 @@ Before uploading your changes, the app checks with a &lt;a href="https://www.wes
<string name="pref_title_message_achievements">Unlocked achievements</string>
<string name="pref_title_message_weekly_osm">New editions of weeklyOSM</string>
<string name="pref_title_message_changelog">New app releases</string>

<string name="pref_title_message_calendar">New OSM events in your area</string>

<!-- Quest & overlay selection screen -->

Expand Down
10 changes: 10 additions & 0 deletions app/src/commonMain/composeResources/drawable/location_pin_red.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="m12,0c-4.418,0 -8,3.582 -8,8 -0,1.316 0.38,2.64 1,3.801l7,12.199 7,-12.199c0.63,-1.167 1,-2.475 1,-3.801 0,-4.418 -3.582,-8 -8,-8zM12,5a3,3 0,0 1,3 3,3 3,0 0,1 -3,3 3,3 0,0 1,-3 -3,3 3,0 0,1 3,-3z"
android:fillColor="#ee2c2c"
android:fillType="evenOdd"/>
</vector>
41 changes: 41 additions & 0 deletions app/src/commonMain/composeResources/drawable/wire_binding.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="36dp"
android:height="56dp"
android:viewportWidth="36"
android:viewportHeight="56">
<path
android:fillColor="#FF000000"
android:pathData="M18,46m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
android:fillAlpha="0.2"
android:fillType="evenOdd"/>
<path
android:pathData="M18,0L18,0A6,6 0,0 1,24 6L24,46A6,6 0,0 1,18 52L18,52A6,6 0,0 1,12 46L12,6A6,6 0,0 1,18 0z"
android:fillType="evenOdd">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="20"
android:centerY="19.999"
android:gradientRadius="32"
android:type="radial">
<item android:offset="0" android:color="#FFC7C7C7"/>
<item android:offset="1" android:color="#FF535353"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M18,0L18,0A6,6 0,0 1,24 6L24,46A6,6 0,0 1,18 52L18,52A6,6 0,0 1,12 46L12,6A6,6 0,0 1,18 0z"
android:fillType="evenOdd">
<aapt:attr name="android:fillColor">
<gradient
android:startX="17.889"
android:startY="29.333"
android:endX="26.111"
android:endY="29.389"
android:type="linear">
<item android:offset="0" android:color="#00454545"/>
<item android:offset="1" android:color="#FF262626"/>
</gradient>
</aapt:attr>
</path>
</vector>
3 changes: 2 additions & 1 deletion app/src/commonMain/composeResources/values-en/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ Additionally, some overlays allow you to add new data at the position of a displ
If you are overwhelmed by the number of quests, you can always fine-tune which quests are displayed to you and in what order in the settings.</string>

<string name="weekly_osm_new_edition_title">New Edition!</string>
<string name="calendar_new_event_title">New OSM event in your area!</string>

<!-- Team mode -->

Expand Down Expand Up @@ -628,7 +629,7 @@ Before uploading your changes, the app checks with a &lt;a href="https://www.wes
<string name="pref_title_message_achievements">Unlocked achievements</string>
<string name="pref_title_message_weekly_osm">New editions of weeklyOSM</string>
<string name="pref_title_message_changelog">New app releases</string>

<string name="pref_title_message_calendar">New OSM events in your area</string>

<!-- Quest & overlay selection screen -->

Expand Down
3 changes: 2 additions & 1 deletion app/src/commonMain/composeResources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ Additionally, some overlays allow you to add new data at the position of a displ
If you are overwhelmed by the number of quests, you can always fine-tune which quests are displayed to you and in what order in the settings.</string>

<string name="weekly_osm_new_edition_title">New Edition!</string>
<string name="calendar_new_event_title">New OSM event in your area!</string>

<!-- Team mode -->

Expand Down Expand Up @@ -628,7 +629,7 @@ Before uploading your changes, the app checks with a &lt;a href="https://www.wes
<string name="pref_title_message_achievements">Unlocked achievements</string>
<string name="pref_title_message_weekly_osm">New editions of weeklyOSM</string>
<string name="pref_title_message_changelog">New app releases</string>

<string name="pref_title_message_calendar">New OSM events in your area</string>

<!-- Quest & overlay selection screen -->

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.westnordost.streetcomplete

import de.westnordost.streetcomplete.data.osm.edits.split_way.SplitWayAction
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.minutes

object ApplicationConstants {
Expand Down Expand Up @@ -83,6 +84,10 @@ object ApplicationConstants {
// where to send the error reports to
const val ERROR_REPORTS_EMAIL = "streetcomplete_errors@westnordost.de"

const val CALENDAR_EVENT_MAX_DISTANCE = 35000 // m

val CALENDAR_EVENT_MAX_IN_ADVANCE_NOTIFICATION = 31.days

/** Which relation types to drop already during download, before persisting. This is a
* performance improvement. Working properly with relations means we have to have it as
* complete as possible. Some relations are extremely large, which would require to pull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import de.westnordost.streetcomplete.data.download.tiles.DownloadedTilesControll
import de.westnordost.streetcomplete.data.logs.LogsController
import de.westnordost.streetcomplete.data.maptiles.MapTilesDownloader
import de.westnordost.streetcomplete.data.osm.mapdata.MapDataController
import de.westnordost.streetcomplete.data.osmcal.CalendarEventsController
import de.westnordost.streetcomplete.data.osmnotes.NoteController
import de.westnordost.streetcomplete.data.quest.QuestTypeRegistry
import de.westnordost.streetcomplete.util.ktx.format
Expand All @@ -25,6 +26,7 @@ class Cleaner(
private val downloadedTilesController: DownloadedTilesController,
private val logsController: LogsController,
private val mapTilesDownloader: MapTilesDownloader,
private val calendarEventsController: CalendarEventsController,
) {
private val scope = CoroutineScope(SupervisorJob() + CoroutineName("Cleaner") + Dispatchers.IO)

Expand All @@ -41,6 +43,8 @@ class Cleaner(
val oldLogTimestamp = nowAsEpochMilliseconds() - ApplicationConstants.DELETE_OLD_LOG_AFTER
logsController.deleteOlderThan(oldLogTimestamp)

calendarEventsController.deleteOld()

Log.i(TAG, "Cleaning took ${((nowAsEpochMilliseconds() - time) / 1000.0).format(1)}s")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import de.westnordost.streetcomplete.data.osm.mapdata.RelationTables
import de.westnordost.streetcomplete.data.osm.mapdata.WayTables
import de.westnordost.streetcomplete.data.osm.osmquests.OsmQuestTable
import de.westnordost.streetcomplete.data.osm.osmquests.OsmQuestsHiddenTable
import de.westnordost.streetcomplete.data.osmcal.CalendarEventsTable
import de.westnordost.streetcomplete.data.osmnotes.NoteTable
import de.westnordost.streetcomplete.data.osmnotes.edits.NoteEditsTable
import de.westnordost.streetcomplete.data.osmnotes.notequests.NoteQuestsHiddenTable
Expand All @@ -29,7 +30,7 @@ import de.westnordost.streetcomplete.util.logs.Log

/** Creates the database and upgrades it */
object DatabaseInitializer {
const val DB_VERSION = 19
const val DB_VERSION = 20

fun onCreate(db: Database) {
// OSM notes
Expand Down Expand Up @@ -99,6 +100,9 @@ object DatabaseInitializer {
// logs
db.exec(LogsTable.CREATE)
db.exec(LogsTable.INDEX_CREATE)

// OSM calendar events
db.exec(CalendarEventsTable.CREATE)
}

fun onUpgrade(db: Database, oldVersion: Int, newVersion: Int) {
Expand Down Expand Up @@ -254,6 +258,9 @@ object DatabaseInitializer {
db.deleteQuest("AddParcelLockerPickup")
db.deleteQuest("AddShoulder")
}
if (oldVersion <= 19 && newVersion > 19) {
db.exec(CalendarEventsTable.CREATE)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ package de.westnordost.streetcomplete.data
import org.koin.dsl.module

val feedsModule = module {
factory { FeedsUpdater(get(), get(), get()) }
factory { FeedsUpdater(get(), get(), get(), get(), get()) }
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package de.westnordost.streetcomplete.data

import de.westnordost.streetcomplete.data.messages.Message
import de.westnordost.streetcomplete.data.osmcal.OsmCalUpdater
import de.westnordost.streetcomplete.data.preferences.Preferences
import de.westnordost.streetcomplete.data.user.UserUpdater
import de.westnordost.streetcomplete.data.user.achievements.AchievementsSource
import de.westnordost.streetcomplete.data.weeklyosm.WeeklyOsmUpdater
import de.westnordost.streetcomplete.util.ktx.now
import kotlinx.datetime.LocalDate
Expand All @@ -11,7 +13,9 @@ import kotlinx.datetime.LocalDate
class FeedsUpdater(
private val userUpdater: UserUpdater,
private val weeklyOsmUpdater: WeeklyOsmUpdater,
private val osmCalUpdater: OsmCalUpdater,
private val prefs: Preferences,
private val achievementsSource: AchievementsSource,
) {
/** update at most daily */
fun updateDaily() {
Expand All @@ -23,8 +27,17 @@ class FeedsUpdater(

userUpdater.update()
val disabledMessageTypes = prefs.disabledMessageTypes
if (Message.NewWeeklyOsm::class !in disabledMessageTypes) {
if (
Message.NewWeeklyOsm::class !in disabledMessageTypes &&
achievementsSource.hasLink("weeklyosm")
) {
weeklyOsmUpdater.update()
}
if (
Message.NewCalendarEvent::class !in disabledMessageTypes &&
achievementsSource.hasLink("calendar")
) {
osmCalUpdater.update()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ val OSM_API_URL =
if (USE_TEST_API) OSM_API_URL_TEST else OSM_API_URL_LIVE

val osmApiModule = module {
factory { Cleaner(get(), get(), get(), get(), get(), get()) }
factory { Cleaner(get(), get(), get(), get(), get(), get(), get()) }
factory { CacheTrimmer(get(), get()) }
factory { MapDataApiClient(get(), OSM_API_URL, get(), get(), get()) }
factory { NotesApiClient(get(), OSM_API_URL, get(), get()) }
Expand Down
Loading