Skip to content

Commit

Permalink
Add new pull request notifications options
Browse files Browse the repository at this point in the history
  • Loading branch information
walter-juan committed Nov 23, 2024
1 parent 4599173 commit 4366ab5
Show file tree
Hide file tree
Showing 10 changed files with 624 additions and 135 deletions.
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
### Security

## [1.5.4]
### Added
- Be able to filter the pull requests notifications by state
### Changed
- Pull request created notifications renamed to pull request state changed notifications
- Pull request updated notifications renamed to pull request activity notifications
### Fixed
- Pull request activity always sent notifications when they were never marked as seen

## [1.5.3]
### Changed
- Use icons from an external dependency
Expand Down Expand Up @@ -204,7 +213,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [1.0.0]
_First version_

[unreleased]: https://github.com/walter-juan/ghd/compare/v1.5.3...dev
[unreleased]: https://github.com/walter-juan/ghd/compare/v1.5.4...dev
[1.5.4]: https://github.com/walter-juan/ghd/releases/tag/v1.5.4
[1.5.3]: https://github.com/walter-juan/ghd/releases/tag/v1.5.3
[1.5.2]: https://github.com/walter-juan/ghd/releases/tag/v1.5.2
[1.5.1]: https://github.com/walter-juan/ghd/releases/tag/v1.5.1
Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ plugins {
}

group = "com.woowla"
version = "1.5.3"
version = "1.5.4"
val debug = (extra["debugConfig"] as String).toBoolean()
val debugAppFolder = "ghd-debug"

Expand Down
21 changes: 17 additions & 4 deletions app/src/main/kotlin/com/woowla/ghd/data/local/LocalDataSource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,14 @@ class LocalDataSource(
appProperties.load()
AppSettings(
darkTheme = appProperties.darkTheme,
newPullRequestsNotificationsEnabled = appProperties.newPullRequestsNotificationsEnabled,
updatedPullRequestsNotificationsEnabled = appProperties.updatedPullRequestsNotificationsEnabled,
pullRequestStateNotificationsEnabled = appProperties.pullRequestStateNotificationsEnabled,
pullRequestNotificationsFilterOptions = PullRequestNotificationsFilterOptions(
open = appProperties.pullRequestNotificationsFilterOptionsOpen,
closed = appProperties.pullRequestNotificationsFilterOptionsClosed,
merged = appProperties.pullRequestNotificationsFilterOptionsMerged,
draft = appProperties.pullRequestNotificationsFilterOptionsDraft,
),
pullRequestActivityNotificationsEnabled = appProperties.pullRequestActivityNotificationsEnabled,
newReleaseNotificationsEnabled = appProperties.newReleaseNotificationsEnabled,
updatedReleaseNotificationsEnabled = appProperties.updatedReleaseNotificationsEnabled
)
Expand All @@ -25,8 +31,15 @@ class LocalDataSource(
return runCatching {
appProperties.load()
appProperties.darkTheme = appSettings.darkTheme
appProperties.newPullRequestsNotificationsEnabled = appSettings.newPullRequestsNotificationsEnabled
appProperties.updatedPullRequestsNotificationsEnabled = appSettings.updatedPullRequestsNotificationsEnabled

appProperties.pullRequestNotificationsFilterOptionsOpen = appSettings.pullRequestNotificationsFilterOptions.open
appProperties.pullRequestNotificationsFilterOptionsClosed = appSettings.pullRequestNotificationsFilterOptions.closed
appProperties.pullRequestNotificationsFilterOptionsMerged = appSettings.pullRequestNotificationsFilterOptions.merged
appProperties.pullRequestNotificationsFilterOptionsDraft = appSettings.pullRequestNotificationsFilterOptions.draft

appProperties.pullRequestStateNotificationsEnabled = appSettings.pullRequestStateNotificationsEnabled
appProperties.pullRequestActivityNotificationsEnabled = appSettings.pullRequestActivityNotificationsEnabled

appProperties.newReleaseNotificationsEnabled = appSettings.newReleaseNotificationsEnabled
appProperties.updatedReleaseNotificationsEnabled = appSettings.updatedReleaseNotificationsEnabled
appProperties.store()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,16 @@ object AppProperties {
val settings: Settings = PropertiesSettings(properties)

var darkTheme: Boolean? by settings.nullableBoolean("darkTheme")
var newPullRequestsNotificationsEnabled: Boolean by settings.boolean("newPullRequestsNotificationsEnabled", true)
var updatedPullRequestsNotificationsEnabled: Boolean by settings.boolean("updatedPullRequestsNotificationsEnabled", true)
var pullRequestNotificationsFilterOptionsOpen: Boolean by settings.boolean("pullRequestNotificationsFilterOptionsOpen", true)
var pullRequestNotificationsFilterOptionsClosed: Boolean by settings.boolean("pullRequestNotificationsFilterOptionsClosed", true)
var pullRequestNotificationsFilterOptionsMerged: Boolean by settings.boolean("pullRequestNotificationsFilterOptionsMerged", true)
var pullRequestNotificationsFilterOptionsDraft: Boolean by settings.boolean("pullRequestNotificationsFilterOptionsDraft", true)

// TODO the property should be migrated from newPullRequestsNotificationsEnabled to pullRequestStateNotificationsEnabled
var pullRequestStateNotificationsEnabled: Boolean by settings.boolean("newPullRequestsNotificationsEnabled", true)
// TODO the property should be migrated from updatedPullRequestsNotificationsEnabled to pullRequestActivityNotificationsEnabled
var pullRequestActivityNotificationsEnabled: Boolean by settings.boolean("updatedPullRequestsNotificationsEnabled", true)

var newReleaseNotificationsEnabled: Boolean by settings.boolean("newReleaseNotificationsEnabled", true)
var updatedReleaseNotificationsEnabled: Boolean by settings.boolean("updatedReleaseNotificationsEnabled", true)

Expand Down
13 changes: 11 additions & 2 deletions app/src/main/kotlin/com/woowla/ghd/domain/entities/AppSettings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@ package com.woowla.ghd.domain.entities

data class AppSettings(
val darkTheme: Boolean?,
val newPullRequestsNotificationsEnabled: Boolean,
val updatedPullRequestsNotificationsEnabled: Boolean,
val pullRequestNotificationsFilterOptions: PullRequestNotificationsFilterOptions,
val pullRequestStateNotificationsEnabled: Boolean,
val pullRequestActivityNotificationsEnabled: Boolean,
val newReleaseNotificationsEnabled: Boolean,
val updatedReleaseNotificationsEnabled: Boolean
) {
}

data class PullRequestNotificationsFilterOptions(
val open: Boolean,
val closed: Boolean,
val merged: Boolean,
val draft: Boolean
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import com.woowla.ghd.domain.entities.RepoToCheck
import com.woowla.ghd.domain.entities.SyncResultEntry
import com.woowla.ghd.domain.entities.SyncSettings
import com.woowla.ghd.data.remote.mappers.toPullRequest
import com.woowla.ghd.domain.entities.PullRequest
import com.woowla.ghd.domain.entities.PullRequestStateWithDraft
import com.woowla.ghd.domain.entities.PullRequestWithRepoAndReviews
import com.woowla.ghd.domain.entities.filterNotSyncValid
import com.woowla.ghd.domain.entities.filterSyncValid
Expand Down Expand Up @@ -121,30 +123,26 @@ class PullRequestService(
}

suspend fun sendNotifications(appSettings: AppSettings, oldPullRequestsWithReviews: List<PullRequestWithRepoAndReviews>, newPullRequestsWithReviews: List<PullRequestWithRepoAndReviews>): Result<Unit> {
val oldPullRequestIds = oldPullRequestsWithReviews.map { it.pullRequest.id }

// notification for a new pull requests
if (appSettings.newPullRequestsNotificationsEnabled) {
newPullRequestsWithReviews
.filterNot {
oldPullRequestIds.contains(it.pullRequest.id)
}
.forEach {
notificationsSender.newPullRequest(it.pullRequest)
// notification for state change
val pullRequestsWithStateChange = newPullRequestsWithReviews
.filter { newPull ->
val oldRelease = oldPullRequestsWithReviews.firstOrNull { it.pullRequest.id == newPull.pullRequest.id }
if (oldRelease != null) {
shouldNotifyPullRequestStateChange(appSettings, oldRelease.pullRequest, newPull.pullRequest)
} else {
shouldNotifyPullRequestStateChange(appSettings, newPull.pullRequest)
}
}
}
pullRequestsWithStateChange.forEach { notificationsSender.newPullRequest(it.pullRequest) }

// notification for an update
if (appSettings.updatedPullRequestsNotificationsEnabled) {
newPullRequestsWithReviews
.filter {
!it.pullRequest.appSeen
}
// notification for activity change
if (appSettings.pullRequestActivityNotificationsEnabled) {
val nonNotified = newPullRequestsWithReviews - pullRequestsWithStateChange
nonNotified
.filter { newPull ->
val oldRelease = oldPullRequestsWithReviews.firstOrNull { it.pullRequest.id == newPull.pullRequest.id }

if (oldRelease != null) {
oldRelease.pullRequest.updatedAt != newPull.pullRequest.updatedAt
shouldNotifyPullRequestActivityChange(appSettings, oldRelease.pullRequest, newPull.pullRequest)
} else {
false
}
Expand All @@ -156,4 +154,37 @@ class PullRequestService(

return Result.success(Unit)
}

private fun shouldNotifyPullRequestStateChange(appSettings: AppSettings, pullRequest: PullRequest): Boolean {
val validState = appSettings.pullRequestNotificationsFilterOptions.let {
when (pullRequest.stateWithDraft) {
PullRequestStateWithDraft.OPEN -> it.open
PullRequestStateWithDraft.CLOSED -> it.closed
PullRequestStateWithDraft.MERGED -> it.merged
PullRequestStateWithDraft.DRAFT -> it.draft
PullRequestStateWithDraft.UNKNOWN -> false
}
}
return appSettings.pullRequestStateNotificationsEnabled && validState
}

private fun shouldNotifyPullRequestStateChange(appSettings: AppSettings, oldPullRequest: PullRequest, newPullRequest: PullRequest): Boolean {
val stateChanged = oldPullRequest.state != newPullRequest.state
val validState = appSettings.pullRequestNotificationsFilterOptions.let {
when (newPullRequest.stateWithDraft) {
PullRequestStateWithDraft.OPEN -> it.open
PullRequestStateWithDraft.CLOSED -> it.closed
PullRequestStateWithDraft.MERGED -> it.merged
PullRequestStateWithDraft.DRAFT -> it.draft
PullRequestStateWithDraft.UNKNOWN -> false
}
}
return appSettings.pullRequestStateNotificationsEnabled && stateChanged && validState
}

private fun shouldNotifyPullRequestActivityChange(appSettings: AppSettings, oldPullRequest: PullRequest, newPullRequest: PullRequest): Boolean {
val seen = newPullRequest.appSeenAt != null && !newPullRequest.appSeen
val updated = oldPullRequest.updatedAt != newPullRequest.updatedAt
return appSettings.pullRequestActivityNotificationsEnabled && seen && updated
}
}
17 changes: 16 additions & 1 deletion app/src/main/kotlin/com/woowla/ghd/presentation/app/i18n.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ object i18n {
val generic_days_ago: (Long) -> String = { "$it days ago" }
val generic_date_format: (String, String, String, String) -> String = {month, day, year, hour -> "$month $day, $year at $hour" }
val generic_unknown = "unknown"
val generic_enabled = "Enabled"
val generic_disabled = "Disabled"

val menu_bar_menu_actions = "Actions"
val menu_bar_menu_item_synchronize = "Synchronize"
Expand Down Expand Up @@ -77,7 +79,20 @@ object i18n {
val screen_app_settings_save = "Save"
val screen_app_settings_synchronization_section = "Synchronization"
val screen_app_settings_appliation_section = "Application"
val screen_app_settings_notifications_section = "Notifications"
val screen_app_settings_pull_requests_notifications_section = "Pull requests notifications"
val screen_app_settings_releases_notifications_section = "Releases notifications"
val screen_app_settings_notifications_pr_filter_out_title = "Filter notifications by state"
val screen_app_settings_notifications_pr_filter_out_description = "Enable notifications only for specific states."
val screen_app_settings_notifications_pr_state_title = "State changes notifications"
val screen_app_settings_notifications_pr_state_description = "Enable to receive notifications when the sate of a pull request changes (e.g., Draft → Open), new pull requests are considered as changes."
val screen_app_settings_notifications_pr_state_checkbox_label = "State changes"
val screen_app_settings_notifications_pr_activity_title = "Activity notifications"
val screen_app_settings_notifications_pr_activity_description = "Enable to receive notifications for updates to pull requests (e.g., comments or edits). "
val screen_app_settings_notifications_pr_activity_checkbox_label = "Activity"
val screen_app_settings_notifications_new_release_title = "Release created notifications"
val screen_app_settings_notifications_new_release_description = "Enable to receive notifications when a new release is created."
val screen_app_settings_notifications_update_release_title = "Release updated notifications"
val screen_app_settings_notifications_update_release_description = "Enable to receive notifications when an existing release is updated."
val screen_app_settings_github_token_field_label = "GitHub PAT token"
val screen_app_settings_github_field_show = "Show GitHub PAT token"
val screen_app_settings_github_field_hide = "Hide GitHub PAT token"
Expand Down
Loading

0 comments on commit 4366ab5

Please sign in to comment.