Skip to content

Commit ee2c08e

Browse files
authored
Notifications: Add notification types for exercise, tutorial and channel management (#143)
* Add AddedToChannelNotification * Add more notification types * Add missing notification types * Make new communication types displayable * Make more notifications displayable
1 parent f5e6300 commit ee2c08e

17 files changed

+366
-9
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// AddedToChannelNotification.swift
3+
// ArtemisCore
4+
//
5+
// Created by Anian Schleyer on 27.04.25.
6+
//
7+
8+
public struct AddedToChannelNotification: CourseBaseNotification {
9+
public var courseId: Int?
10+
public var courseTitle: String?
11+
public var courseIconUrl: String?
12+
13+
public var channelModerator: String?
14+
public var channelName: String?
15+
public var channelId: Int?
16+
}
17+
18+
extension AddedToChannelNotification: DisplayableNotification {
19+
public var title: String {
20+
R.string.localizable.artemisAppSingleUserNotificationTitleAddUserChannel()
21+
}
22+
23+
public var body: String? {
24+
guard let channelName, let channelModerator else { return nil }
25+
return R.string.localizable.artemisAppSingleUserNotificationTextAddUserChannel(channelName, channelModerator)
26+
}
27+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//
2+
// ChannelDeletedNotification.swift
3+
// ArtemisCore
4+
//
5+
// Created by Anian Schleyer on 27.04.25.
6+
//
7+
8+
public struct ChannelDeletedNotification: CourseBaseNotification {
9+
public var courseId: Int?
10+
public var courseTitle: String?
11+
public var courseIconUrl: String?
12+
13+
public var deletingUser: String?
14+
public var channelName: String?
15+
}
16+
17+
extension ChannelDeletedNotification: DisplayableNotification {
18+
public var title: String {
19+
R.string.localizable.artemisAppSingleUserNotificationTitleDeleteChannel()
20+
}
21+
22+
public var body: String? {
23+
guard let channelName, let deletingUser else { return nil }
24+
return R.string.localizable.artemisAppSingleUserNotificationTextDeleteChannel(channelName, deletingUser)
25+
}
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// RemovedFromChannelNotification.swift
3+
// ArtemisCore
4+
//
5+
// Created by Anian Schleyer on 27.04.25.
6+
//
7+
8+
public struct RemovedFromChannelNotification: CourseBaseNotification {
9+
public var courseId: Int?
10+
public var courseTitle: String?
11+
public var courseIconUrl: String?
12+
13+
public var channelModerator: String?
14+
public var channelName: String?
15+
public var channelId: Int?
16+
}
17+
18+
extension RemovedFromChannelNotification: DisplayableNotification {
19+
public var title: String {
20+
R.string.localizable.artemisAppSingleUserNotificationTitleRemoveUserChannel()
21+
}
22+
23+
public var body: String? {
24+
guard let channelName, let channelModerator else { return nil }
25+
return R.string.localizable.artemisAppSingleUserNotificationTextRemoveUserChannel(channelName, channelModerator)
26+
}
27+
}

Sources/PushNotifications/Models/CoursePushNotification.swift

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,34 @@ public enum CoursePushNotification: Codable {
1515
case parameters
1616
}
1717

18+
case addedToChannel(AddedToChannelNotification)
19+
case channelDeleted(ChannelDeletedNotification)
1820
case newAnnouncement(NewAnnouncementNotification)
1921
case newAnswer(NewAnswerNotification)
2022
case newMention(NewMentionNotification)
2123
case newPost(NewPostNotification)
24+
case removedFromChannel(RemovedFromChannelNotification)
2225
case attachmentChanged(AttachmentChangedNotification)
26+
case deregisteredFromTutorial(DeregisteredFromTutorialGroupNotification)
27+
case duplicateTestCase(DuplicateTestCaseNotification)
2328
case exerciseAssessed(ExerciseAssessedNotification)
2429
case exerciseOpenForPractice(ExerciseOpenForPracticeNotification)
2530
case exerciseUpdated(ExerciseUpdatedNotification)
31+
case newCpcPlagiarismCase(NewCpcPlagiarismCaseNotification)
2632
case newExercise(NewExerciseNotification)
2733
case newManualFeedbackRequest(NewManualFeedbackRequestNotification)
34+
case newPlagiarismCase(NewPlagiarismCaseNotification)
35+
case plagiarismCaseVerdict(PlagiarismCaseVerdictNotification)
36+
case programmingBuildRunUpdate(ProgrammingBuildRunUpdateNotification)
37+
case programmingTestCasesChanged(ProgrammingTestCasesChangedNotification)
2838
case quizStarted(QuizExerciseStartedNotification)
39+
case registeredToTutorial(RegisteredToTutorialGroupNotification)
40+
case tutorialAssigned(TutorialGroupAssignedNotification)
41+
case tutorialDeleted(TutorialGroupDeletedNotification)
42+
case tutorialUnassigned(TutorialGroupUnassignedNotification)
2943
case unknown
3044

45+
// swiftlint:disable:next cyclomatic_complexity
3146
/// Initializer for using different CodingKeys.
3247
/// This is necessary because Notifications that aren't push notifications have a different name for `type`.
3348
public init<Key>(from decoder: Decoder, typeKey: Key, parametersKey: Key) throws where Key: CodingKey {
@@ -36,18 +51,32 @@ public enum CoursePushNotification: Codable {
3651
let decodeNotification = NotificationDecoder(key: parametersKey, container: container)
3752
self = switch type {
3853
// Communication
54+
case .addedToChannelNotification: .addedToChannel(try decodeNotification())
55+
case .channelDeletedNotification: .channelDeleted(try decodeNotification())
3956
case .newAnnouncementNotification: .newAnnouncement(try decodeNotification())
4057
case .newAnswerNotification: .newAnswer(try decodeNotification())
4158
case .newMentionNotification: .newMention(try decodeNotification())
4259
case .newPostNotification: .newPost(try decodeNotification())
60+
case .removedFromChannelNotification: .removedFromChannel(try decodeNotification())
4361
// General
4462
case .attachmentChangedNotification: .attachmentChanged(try decodeNotification())
63+
case .deregisteredFromTutorialGroupNotification: .deregisteredFromTutorial(try decodeNotification())
64+
case .duplicateTestCaseNotification: .duplicateTestCase(try decodeNotification())
4565
case .exerciseAssessedNotification: .exerciseAssessed(try decodeNotification())
4666
case .exerciseOpenForPracticeNotification: .exerciseOpenForPractice(try decodeNotification())
4767
case .exerciseUpdatedNotification: .exerciseUpdated(try decodeNotification())
68+
case .newCpcPlagiarismCaseNotification: .newCpcPlagiarismCase(try decodeNotification())
4869
case .newExerciseNotification: .newExercise(try decodeNotification())
4970
case .newManualFeedbackRequestNotification: .newManualFeedbackRequest(try decodeNotification())
71+
case .newPlagiarismCaseNotification: .newPlagiarismCase(try decodeNotification())
72+
case .plagiarismCaseVerdictNotification: .plagiarismCaseVerdict(try decodeNotification())
73+
case .programmingBuildRunUpdateNotification: .programmingBuildRunUpdate(try decodeNotification())
74+
case .programmingTestCasesChangedNotification: .programmingTestCasesChanged(try decodeNotification())
5075
case .quizExerciseStartedNotification: .quizStarted(try decodeNotification())
76+
case .registeredToTutorialGroupNotification: .registeredToTutorial(try decodeNotification())
77+
case .tutorialGroupAssignedNotification: .tutorialAssigned(try decodeNotification())
78+
case .tutorialGroupDeletedNotification: .tutorialDeleted(try decodeNotification())
79+
case .tutorialGroupUnassignedNotification: .tutorialUnassigned(try decodeNotification())
5180
case .unknown: .unknown
5281
}
5382
}
@@ -61,18 +90,26 @@ public enum CoursePushNotification: Codable {
6190

6291
public var displayable: DisplayableNotification? {
6392
switch self {
93+
case .addedToChannel(let notification): notification
94+
case .channelDeleted(let notification): notification
6495
case .newAnnouncement(let notification): notification
6596
case .newAnswer(let notification): notification
6697
case .newMention(let notification): notification
6798
case .newPost(let notification): notification
99+
case .removedFromChannel(let notification): notification
68100

69101
case .attachmentChanged(let notification): notification
102+
case .deregisteredFromTutorial(let notification): notification
70103
case .exerciseAssessed(let notification): notification
71104
case .exerciseOpenForPractice(let notification): notification
72105
case .exerciseUpdated(let notification): notification
73106
case .newExercise(let notification): notification
74107
case .newManualFeedbackRequest(let notification): notification
75108
case .quizStarted(let notification): notification
109+
case .registeredToTutorial(let notification): notification
110+
case .tutorialAssigned(let notification): notification
111+
case .tutorialDeleted(let notification): notification
112+
case .tutorialUnassigned(let notification): notification
76113
default:
77114
nil
78115
}
@@ -92,18 +129,32 @@ private struct NotificationDecoder<Key: CodingKey> {
92129

93130
public enum CourseNotificationType: String, Codable, ConstantsEnum {
94131
// Communication
132+
case addedToChannelNotification
133+
case channelDeletedNotification
95134
case newAnnouncementNotification
96135
case newAnswerNotification
97136
case newMentionNotification
98137
case newPostNotification
138+
case removedFromChannelNotification
99139
// General
100140
case attachmentChangedNotification
141+
case deregisteredFromTutorialGroupNotification
142+
case duplicateTestCaseNotification
101143
case exerciseAssessedNotification
102144
case exerciseOpenForPracticeNotification
103145
case exerciseUpdatedNotification
146+
case newCpcPlagiarismCaseNotification
104147
case newExerciseNotification
105148
case newManualFeedbackRequestNotification
149+
case newPlagiarismCaseNotification
150+
case plagiarismCaseVerdictNotification
151+
case programmingBuildRunUpdateNotification
152+
case programmingTestCasesChangedNotification
106153
case quizExerciseStartedNotification
154+
case registeredToTutorialGroupNotification
155+
case tutorialGroupAssignedNotification
156+
case tutorialGroupDeletedNotification
157+
case tutorialGroupUnassignedNotification
107158
case unknown
108159
}
109160

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// DeregisteredFromTutorialGroupNotification.swift
3+
// ArtemisCore
4+
//
5+
// Created by Anian Schleyer on 27.04.25.
6+
//
7+
8+
// swiftlint:disable:next type_name
9+
public struct DeregisteredFromTutorialGroupNotification: CourseBaseNotification {
10+
public var courseId: Int?
11+
public var courseTitle: String?
12+
public var courseIconUrl: String?
13+
14+
public var groupTitle: String?
15+
public var groupId: Int?
16+
public var moderatorName: String?
17+
}
18+
19+
extension DeregisteredFromTutorialGroupNotification: DisplayableNotification {
20+
public var title: String {
21+
R.string.localizable.artemisAppSingleUserNotificationTitleTutorialGroupDeregistrationStudent()
22+
}
23+
24+
public var body: String? {
25+
R.string.localizable.artemisAppSingleUserNotificationTextTutorialGroupDeregistrationStudent(groupTitle ?? "", moderatorName ?? "user")
26+
}
27+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// DuplicateTestCaseNotification.swift
3+
// ArtemisCore
4+
//
5+
// Created by Anian Schleyer on 27.04.25.
6+
//
7+
8+
public struct DuplicateTestCaseNotification: CourseBaseNotification {
9+
public var courseId: Int?
10+
public var courseTitle: String?
11+
public var courseIconUrl: String?
12+
13+
public var exerciseId: Int?
14+
public var exerciseTitle: String?
15+
public var releaseDate: String?
16+
public var dueDate: String?
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// NewCpcPlagiarismCaseNotification.swift
3+
// ArtemisCore
4+
//
5+
// Created by Anian Schleyer on 27.04.25.
6+
//
7+
8+
public struct NewCpcPlagiarismCaseNotification: CourseBaseNotification {
9+
public var courseId: Int?
10+
public var courseTitle: String?
11+
public var courseIconUrl: String?
12+
13+
public var exerciseId: Int?
14+
public var exerciseTitle: String?
15+
public var exerciseType: String?
16+
public var postMarkdownContent: String?
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// NewPlagiarismCaseNotification.swift
3+
// ArtemisCore
4+
//
5+
// Created by Anian Schleyer on 27.04.25.
6+
//
7+
8+
public struct NewPlagiarismCaseNotification: CourseBaseNotification {
9+
public var courseId: Int?
10+
public var courseTitle: String?
11+
public var courseIconUrl: String?
12+
13+
public var exerciseId: Int?
14+
public var exerciseTitle: String?
15+
public var exerciseType: String?
16+
public var postMarkdownContent: String?
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// PlagiarismCaseVerdictNotification.swift
3+
// ArtemisCore
4+
//
5+
// Created by Anian Schleyer on 27.04.25.
6+
//
7+
8+
public struct PlagiarismCaseVerdictNotification: CourseBaseNotification {
9+
public var courseId: Int?
10+
public var courseTitle: String?
11+
public var courseIconUrl: String?
12+
13+
public var exerciseId: Int?
14+
public var exerciseTitle: String?
15+
public var exerciseType: String?
16+
public var verdict: String?
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// ProgrammingBuildRunUpdateNotification.swift
3+
// ArtemisCore
4+
//
5+
// Created by Anian Schleyer on 27.04.25.
6+
//
7+
8+
public struct ProgrammingBuildRunUpdateNotification: CourseBaseNotification {
9+
public var courseId: Int?
10+
public var courseTitle: String?
11+
public var courseIconUrl: String?
12+
13+
public var exerciseId: Int?
14+
public var exerciseTitle: String?
15+
}

0 commit comments

Comments
 (0)