-
-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BREAKING: Rename NotificationController to AnnouncementController (#697)
* Rename NotificationController to AnnouncementController * Rename public exports * Fix build * Fix test * Replace every mention of notifications
- Loading branch information
1 parent
3391089
commit 731246a
Showing
5 changed files
with
204 additions
and
204 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import { | ||
AnnouncementConfig, | ||
AnnouncementState, | ||
AnnouncementController, | ||
StateAnnouncementMap, | ||
} from './AnnouncementController'; | ||
|
||
const config1: AnnouncementConfig = { | ||
allAnnouncements: { | ||
1: { | ||
id: 1, | ||
date: '12/8/2020', | ||
}, | ||
2: { | ||
id: 2, | ||
date: '12/8/2020', | ||
}, | ||
}, | ||
}; | ||
|
||
const config2: AnnouncementConfig = { | ||
allAnnouncements: { | ||
1: { | ||
id: 1, | ||
date: '12/8/2020', | ||
}, | ||
2: { | ||
id: 2, | ||
date: '12/8/2020', | ||
}, | ||
3: { | ||
id: 3, | ||
date: '12/8/2020', | ||
}, | ||
}, | ||
}; | ||
|
||
const state1: AnnouncementState = { | ||
announcements: { | ||
1: { | ||
id: 1, | ||
date: '12/8/2020', | ||
isShown: true, | ||
}, | ||
2: { | ||
id: 2, | ||
date: '12/8/2020', | ||
isShown: true, | ||
}, | ||
}, | ||
}; | ||
|
||
describe('announcement controller', () => { | ||
it('should add announcement to state', () => { | ||
const controller = new AnnouncementController(config1); | ||
expect(Object.keys(controller.state.announcements)).toHaveLength(2); | ||
const expectedStateNotifications: StateAnnouncementMap = { | ||
1: { | ||
...config1.allAnnouncements[1], | ||
isShown: false, | ||
}, | ||
2: { | ||
...config1.allAnnouncements[2], | ||
isShown: false, | ||
}, | ||
}; | ||
expect(controller.state.announcements).toStrictEqual( | ||
expectedStateNotifications, | ||
); | ||
}); | ||
|
||
it('should add new announcement to state', () => { | ||
const controller = new AnnouncementController(config2, state1); | ||
expect(Object.keys(controller.state.announcements)).toHaveLength(3); | ||
expect(controller.state.announcements[1].isShown).toBe(true); | ||
expect(controller.state.announcements[2].isShown).toBe(true); | ||
expect(controller.state.announcements[3].isShown).toBe(false); | ||
}); | ||
|
||
describe('update viewed announcements', () => { | ||
it('should update isShown status', () => { | ||
const controller = new AnnouncementController(config2); | ||
controller.updateViewed({ 1: true }); | ||
expect(controller.state.announcements[1].isShown).toBe(true); | ||
expect(controller.state.announcements[2].isShown).toBe(false); | ||
expect(controller.state.announcements[3].isShown).toBe(false); | ||
}); | ||
|
||
it('should update isShown of more than one announcement', () => { | ||
const controller = new AnnouncementController(config2); | ||
controller.updateViewed({ 2: true, 3: true }); | ||
expect(controller.state.announcements[1].isShown).toBe(false); | ||
expect(controller.state.announcements[2].isShown).toBe(true); | ||
expect(controller.state.announcements[3].isShown).toBe(true); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { BaseController, BaseConfig, BaseState } from '../BaseController'; | ||
|
||
interface ViewedAnnouncement { | ||
[id: number]: boolean; | ||
} | ||
|
||
interface Announcement { | ||
id: number; | ||
date: string; | ||
} | ||
|
||
interface StateAnnouncement extends Announcement { | ||
isShown: boolean; | ||
} | ||
|
||
/** | ||
* A map of announcement ids to Announcement objects | ||
*/ | ||
interface AnnouncementMap { | ||
[id: number]: Announcement; | ||
} | ||
|
||
/** | ||
* A map of announcement ids to StateAnnouncement objects | ||
*/ | ||
export interface StateAnnouncementMap { | ||
[id: number]: StateAnnouncement; | ||
} | ||
|
||
/** | ||
* AnnouncementConfig will hold the active announcements | ||
*/ | ||
export interface AnnouncementConfig extends BaseConfig { | ||
allAnnouncements: AnnouncementMap; | ||
} | ||
|
||
/** | ||
* Announcement state will hold all the seen and unseen announcements | ||
* that are still active | ||
*/ | ||
export interface AnnouncementState extends BaseState { | ||
announcements: StateAnnouncementMap; | ||
} | ||
|
||
const defaultState = { | ||
announcements: {}, | ||
}; | ||
|
||
/** | ||
* Controller for managing in-app announcements. | ||
*/ | ||
export class AnnouncementController extends BaseController< | ||
AnnouncementConfig, | ||
AnnouncementState | ||
> { | ||
/** | ||
* Creates a AnnouncementController instance. | ||
* | ||
* @param config - Initial options used to configure this controller. | ||
* @param state - Initial state to set on this controller. | ||
*/ | ||
constructor(config: AnnouncementConfig, state?: AnnouncementState) { | ||
super(config, state || defaultState); | ||
this.initialize(); | ||
this._addAnnouncements(); | ||
} | ||
|
||
/** | ||
* Compares the announcements in state with the announcements from file | ||
* to check if there are any new announcements | ||
* if yes, the new announcement will be added to the state with a flag indicating | ||
* that the announcement is not seen by the user. | ||
*/ | ||
private _addAnnouncements(): void { | ||
const newAnnouncements: StateAnnouncementMap = {}; | ||
const { allAnnouncements } = this.config; | ||
Object.values(allAnnouncements).forEach( | ||
(announcement: StateAnnouncement) => { | ||
newAnnouncements[announcement.id] = this.state.announcements[ | ||
announcement.id | ||
] | ||
? this.state.announcements[announcement.id] | ||
: { | ||
...announcement, | ||
isShown: false, | ||
}; | ||
}, | ||
); | ||
this.update({ announcements: newAnnouncements }); | ||
} | ||
|
||
/** | ||
* Updates the status of the status of the specified announcements | ||
* once it is read by the user. | ||
* | ||
* @param viewedIds - The announcement IDs to mark as viewed. | ||
*/ | ||
updateViewed(viewedIds: ViewedAnnouncement): void { | ||
const stateAnnouncements = this.state.announcements; | ||
|
||
for (const id of Object.keys(viewedIds).map(Number)) { | ||
stateAnnouncements[id].isShown = viewedIds[id]; | ||
} | ||
this.update({ announcements: stateAnnouncements }, true); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.