ursus
02/18/2022, 1:27 PMLukasz Kalnik
02/18/2022, 2:02 PMLukasz Kalnik
02/18/2022, 2:03 PMLukasz Kalnik
02/18/2022, 2:04 PMLukasz Kalnik
02/18/2022, 2:05 PMursus
02/18/2022, 2:08 PMursus
02/18/2022, 2:09 PMursus
02/18/2022, 2:12 PMLukasz Kalnik
02/18/2022, 2:17 PMSong, Author and Podcast be mixed together? I.e. are they displayed in the UI within one list in a mixed fashion?Lukasz Kalnik
02/18/2022, 2:18 PMPodcast for both apps. So what that the other app doesn't use it?Lukasz Kalnik
02/18/2022, 2:20 PMSong, Author and Podcast all from one data source (API call, database query)?ursus
02/18/2022, 2:21 PMwhen etcLukasz Kalnik
02/18/2022, 2:21 PMLukasz Kalnik
02/18/2022, 2:21 PMLukasz Kalnik
02/18/2022, 2:22 PMLukasz Kalnik
02/18/2022, 2:22 PMLukasz Kalnik
02/18/2022, 2:24 PMLukasz Kalnik
02/18/2022, 2:25 PMViewModel1 and ViewModel2 where you inject CommonViewModel (which is the part where UI logic is really identical, and not only similar)ursus
02/18/2022, 2:26 PMLukasz Kalnik
02/18/2022, 2:26 PMursus
02/18/2022, 2:27 PMursus
02/18/2022, 2:27 PMLukasz Kalnik
02/18/2022, 2:27 PMLukasz Kalnik
02/18/2022, 2:27 PMursus
02/18/2022, 2:28 PMLukasz Kalnik
02/18/2022, 2:28 PMLukasz Kalnik
02/18/2022, 2:28 PMLukasz Kalnik
02/18/2022, 2:29 PMursus
02/18/2022, 2:29 PMLukasz Kalnik
02/18/2022, 2:29 PMSong and Author typesLukasz Kalnik
02/18/2022, 2:30 PMSong and AuthorLukasz Kalnik
02/18/2022, 2:30 PMSong and Author, and then a second call to get Podcast.
Data is combined inside your domain layer.Lukasz Kalnik
02/18/2022, 2:31 PMSong, Author and Podcast. Then you cannot share anything.ursus
02/18/2022, 2:31 PMLukasz Kalnik
02/18/2022, 2:31 PMIf in reality the types don't go together, why should they belong to the same hierarchy?Reality = description of your business case
Lukasz Kalnik
02/18/2022, 2:32 PMursus
02/18/2022, 2:32 PMLukasz Kalnik
02/18/2022, 2:32 PMursus
02/18/2022, 2:33 PMLukasz Kalnik
02/18/2022, 2:33 PMLukasz Kalnik
02/18/2022, 2:34 PMLukasz Kalnik
02/18/2022, 2:36 PMursus
02/18/2022, 2:41 PMsealed class Item
data class DateItem(val timestamp: Long) : Item()
data class ActivatePushItem(val processing: Boolean) : Item()
object NonDefaultSubscriberItem : Item()
data class MessageItem(val message: BusinessMessage) : Item()
list looks like
ActivatePushItem
DateItem
MessageItem
MessageItem
MessageItem
DateItem
MessageItem
MessageItem
api usage
ViewModel.items: Flow<List<Item>>
fun ViewModel.messageClick(message: BusinessMessage) {
navigator.goToDetail(message.id)
}
--------
appB wants to add
data class PromotionItem(...)
list looks like
ActivatePushItem
PromotionItem
PromotionItem
DateItem
MessageItem
MessageItem
MessageItem
DateItem
MessageItem
MessageItemursus
02/18/2022, 2:42 PMursus
02/18/2022, 2:44 PMLukasz Kalnik
02/18/2022, 2:44 PMLukasz Kalnik
02/18/2022, 2:45 PMLukasz Kalnik
02/18/2022, 2:45 PMItem is presentation (view) layer hierarchyLukasz Kalnik
02/18/2022, 2:46 PMItem1 and Item2 hierarchy for both appsLukasz Kalnik
02/18/2022, 2:47 PMursus
02/18/2022, 2:51 PMursus
02/18/2022, 2:52 PMursus
02/18/2022, 2:52 PMLukasz Kalnik
02/18/2022, 2:52 PMLukasz Kalnik
02/18/2022, 2:52 PMLukasz Kalnik
02/18/2022, 2:53 PMursus
02/18/2022, 2:53 PMLukasz Kalnik
02/18/2022, 2:53 PMLukasz Kalnik
02/18/2022, 2:53 PMLukasz Kalnik
02/18/2022, 2:54 PMPromotionItem how do you deal with this in AppA?Lukasz Kalnik
02/18/2022, 2:55 PMursus
02/18/2022, 2:55 PMfun ItemMapper(
subscriber: LoadedSubscriber?,
messages: List<BusinessMessage>,
notificationMethod: BusinessNotificationMethod?,
pushActivating: Boolean
): List<Item> {
if (subscriber == null) return emptyList()
val showSettings = subscriber.default && notificationMethod == BusinessNotificationMethod.PUSH
val items = mutableListOf<Item>()
if (!subscriber.default) {
items += NonDefaultSubscriberItem
} else {
if (notificationMethod == BusinessNotificationMethod.SMS) {
items += ActivatePushItem(pushActivating)
}
var previousDate: LocalDate? = null
for (message in messages) {
val date = message.timestamp.toLocalDateTime().toLocalDate()
if (previousDate == null || !date.isEqual(previousDate)) {
items += DateItem(date.atStartOfDay(TIMEZONE_SLOVAKIA).toInstant().toEpochMilli())
}
items += MessageItem(message)
previousDate = date
}
}
return items
}ursus
02/18/2022, 2:56 PMursus
02/18/2022, 2:58 PMfun ItemMapper(
subscriber: LoadedSubscriber?,
messages: List<BusinessMessage>,
notificationMethod: BusinessNotificationMethod?,
pushActivating: Boolean,
promos: List<Promo> <------------------------------------------------
): Triple<List<Item>, Set<BusinessMessage.Category>, Boolean> {
if (subscriber == null) return tupleOf(emptyList(), emptySet(), false)
val showSettings = subscriber.default && notificationMethod == BusinessNotificationMethod.PUSH
val items = mutableListOf<Item>()
if (!subscriber.default) {
items += NonDefaultSubscriberItem
} else {
if (notificationMethod == BusinessNotificationMethod.SMS) {
items += ActivatePushItem(pushActivating)
}
for (promo in promos) { <------------------------------------------------
items += PromoItem(promo.id, promo.title etc) <------------------------------------------------
}
var previousDate: LocalDate? = null
for (message in messages) {
val date = message.timestamp.toLocalDateTime().toLocalDate()
if (previousDate == null || !date.isEqual(previousDate)) {
items += DateItem(date.atStartOfDay(TIMEZONE_SLOVAKIA).toInstant().toEpochMilli())
}
items += MessageItem(message)
previousDate = date
}
}
return items
}ursus
02/18/2022, 2:59 PMLukasz Kalnik
02/18/2022, 3:28 PMPromoItem
AppB -> with PromoItem
shared library for data access and conversion -> with PromoItemDto.Lukasz Kalnik
02/18/2022, 3:29 PMItemDtoLukasz Kalnik
02/18/2022, 3:30 PMItemDto to its UiItem hierarchyLukasz Kalnik
02/18/2022, 3:30 PMPromoItemDto and converts ItemDto to its own UiItem hierarchy (without PromoItem)Lukasz Kalnik
02/18/2022, 3:31 PMLukasz Kalnik
02/18/2022, 3:31 PMursus
02/18/2022, 3:32 PMLukasz Kalnik
02/18/2022, 3:35 PMLukasz Kalnik
02/18/2022, 3:35 PMLukasz Kalnik
02/18/2022, 3:35 PMLukasz Kalnik
02/18/2022, 3:36 PMLukasz Kalnik
02/18/2022, 3:36 PMursus
02/18/2022, 3:37 PMLukasz Kalnik
02/18/2022, 3:38 PMLukasz Kalnik
02/18/2022, 3:38 PMursus
02/18/2022, 3:38 PMLukasz Kalnik
02/18/2022, 3:38 PMLukasz Kalnik
02/18/2022, 3:39 PMLukasz Kalnik
02/18/2022, 3:39 PMLukasz Kalnik
02/18/2022, 3:39 PMLukasz Kalnik
02/18/2022, 3:39 PMLukasz Kalnik
02/18/2022, 3:40 PMList<BusinessMessage> to List<Item> appending to mutable ListLukasz Kalnik
02/18/2022, 3:40 PMmapursus
02/18/2022, 3:40 PMLukasz Kalnik
02/18/2022, 3:41 PMLukasz Kalnik
02/18/2022, 3:41 PMgetMessages() in AppA and getMessages() and getPromos() in AppBLukasz Kalnik
02/18/2022, 3:41 PMursus
02/18/2022, 3:42 PMursus
02/18/2022, 3:42 PMLukasz Kalnik
02/18/2022, 3:45 PMMessageOrPromoursus
02/18/2022, 3:45 PMLukasz Kalnik
02/18/2022, 3:45 PMLukasz Kalnik
02/18/2022, 3:45 PMLukasz Kalnik
02/18/2022, 3:46 PMItemDto is not needed hereursus
02/18/2022, 3:46 PMLukasz Kalnik
02/18/2022, 3:48 PMLukasz Kalnik
02/18/2022, 3:51 PMursus
02/18/2022, 3:52 PMLukasz Kalnik
02/18/2022, 3:53 PMDateItem, MessageItem and PromoItem) into separate convertersLukasz Kalnik
02/18/2022, 3:53 PMursus
02/18/2022, 3:53 PMLukasz Kalnik
02/18/2022, 3:54 PMUiItemA and UiItemB hierarchiesLukasz Kalnik
02/18/2022, 3:54 PMLukasz Kalnik
02/18/2022, 3:54 PMLukasz Kalnik
02/18/2022, 3:55 PMursus
02/18/2022, 3:55 PMLukasz Kalnik
02/18/2022, 3:55 PMLukasz Kalnik
02/18/2022, 3:56 PMLukasz Kalnik
02/18/2022, 3:56 PMMessageItem doesn't have to be part of any sealed hierarchyursus
02/18/2022, 3:56 PMLukasz Kalnik
02/18/2022, 3:57 PMColumnLukasz Kalnik
02/18/2022, 3:57 PMLukasz Kalnik
02/18/2022, 3:57 PMursus
02/18/2022, 3:57 PMLukasz Kalnik
02/18/2022, 3:57 PMLukasz Kalnik
02/18/2022, 3:57 PMLukasz Kalnik
02/18/2022, 3:57 PMursus
02/18/2022, 3:58 PMLukasz Kalnik
02/18/2022, 3:58 PMursus
02/18/2022, 3:58 PMLukasz Kalnik
02/18/2022, 3:58 PMLukasz Kalnik
02/18/2022, 3:58 PMursus
02/18/2022, 3:59 PMLukasz Kalnik
02/18/2022, 3:59 PMLukasz Kalnik
02/18/2022, 3:59 PMLukasz Kalnik
02/18/2022, 4:00 PMLukasz Kalnik
02/18/2022, 4:00 PMursus
02/18/2022, 4:00 PMLukasz Kalnik
02/18/2022, 4:00 PMLukasz Kalnik
02/18/2022, 4:01 PMLukasz Kalnik
02/18/2022, 4:01 PMursus
02/18/2022, 4:02 PMLukasz Kalnik
02/18/2022, 4:02 PMLukasz Kalnik
02/18/2022, 4:02 PMursus
02/18/2022, 4:02 PMLukasz Kalnik
02/18/2022, 4:02 PMLukasz Kalnik
02/18/2022, 4:02 PMursus
02/18/2022, 4:02 PMLukasz Kalnik
02/18/2022, 4:03 PMLukasz Kalnik
02/18/2022, 4:03 PMLukasz Kalnik
02/18/2022, 4:03 PMLukasz Kalnik
02/18/2022, 4:04 PMLukasz Kalnik
02/18/2022, 4:04 PMLukasz Kalnik
02/18/2022, 4:05 PMursus
02/18/2022, 4:05 PMLukasz Kalnik
02/18/2022, 4:05 PMursus
02/18/2022, 4:05 PMLukasz Kalnik
02/18/2022, 4:06 PMLukasz Kalnik
02/18/2022, 4:06 PMursus
02/18/2022, 4:06 PMLukasz Kalnik
02/18/2022, 4:07 PMLukasz Kalnik
02/18/2022, 4:07 PMLukasz Kalnik
02/18/2022, 4:08 PMursus
02/18/2022, 4:08 PMLukasz Kalnik
02/18/2022, 4:08 PMLukasz Kalnik
02/18/2022, 4:08 PMursus
02/18/2022, 4:08 PMLukasz Kalnik
02/18/2022, 4:08 PMursus
02/18/2022, 4:09 PMLukasz Kalnik
02/18/2022, 4:09 PMLukasz Kalnik
02/18/2022, 4:09 PMursus
02/18/2022, 4:09 PMLukasz Kalnik
02/18/2022, 4:09 PMLukasz Kalnik
02/18/2022, 4:09 PMursus
02/18/2022, 4:10 PMLukasz Kalnik
02/18/2022, 4:10 PMursus
02/18/2022, 4:10 PMLukasz Kalnik
02/18/2022, 4:10 PMursus
02/18/2022, 4:10 PMLukasz Kalnik
02/18/2022, 4:10 PMLukasz Kalnik
02/18/2022, 4:10 PMursus
02/18/2022, 4:10 PMAnalyticsTracker.track(mesasge: Message)Lukasz Kalnik
02/18/2022, 4:11 PMLukasz Kalnik
02/18/2022, 4:11 PMursus
02/18/2022, 4:11 PMLukasz Kalnik
02/18/2022, 4:12 PMMessageConverted type, which is just independent typeLukasz Kalnik
02/18/2022, 4:12 PMLukasz Kalnik
02/18/2022, 4:12 PMLukasz Kalnik
02/18/2022, 4:12 PMLukasz Kalnik
02/18/2022, 4:12 PMLukasz Kalnik
02/18/2022, 4:12 PMLukasz Kalnik
02/18/2022, 4:13 PMLukasz Kalnik
02/18/2022, 4:13 PMLukasz Kalnik
02/18/2022, 4:13 PMLukasz Kalnik
02/18/2022, 4:13 PMursus
02/18/2022, 4:14 PMLukasz Kalnik
02/18/2022, 4:14 PMLukasz Kalnik
02/18/2022, 4:14 PMLukasz Kalnik
02/18/2022, 4:15 PMLukasz Kalnik
02/18/2022, 4:15 PMLukasz Kalnik
02/18/2022, 4:16 PMLukasz Kalnik
02/18/2022, 4:17 PMursus
02/18/2022, 4:18 PMLukasz Kalnik
02/18/2022, 4:19 PMLukasz Kalnik
02/18/2022, 4:20 PMAnalyticsTrackerAppA and AnalyticsTrackerAppB and skip the backwards mappingLukasz Kalnik
02/18/2022, 4:20 PMLukasz Kalnik
02/18/2022, 4:20 PMLukasz Kalnik
02/18/2022, 4:21 PMLukasz Kalnik
02/18/2022, 4:22 PMLukasz Kalnik
02/18/2022, 4:22 PMLukasz Kalnik
02/18/2022, 4:23 PMLukasz Kalnik
02/18/2022, 4:23 PMLukasz Kalnik
02/18/2022, 4:23 PMLukasz Kalnik
02/18/2022, 4:24 PMursus
02/18/2022, 4:24 PMLukasz Kalnik
02/18/2022, 4:26 PMLukasz Kalnik
02/18/2022, 4:26 PMLukasz Kalnik
02/18/2022, 4:26 PMLukasz Kalnik
02/18/2022, 4:27 PMursus
02/18/2022, 4:27 PMLukasz Kalnik
02/18/2022, 4:27 PMLukasz Kalnik
02/18/2022, 4:28 PMLukasz Kalnik
02/18/2022, 4:28 PMLukasz Kalnik
02/18/2022, 4:29 PMLukasz Kalnik
02/18/2022, 4:29 PMLukasz Kalnik
02/18/2022, 4:29 PMLukasz Kalnik
02/18/2022, 4:30 PMLukasz Kalnik
02/18/2022, 4:31 PMursus
02/18/2022, 4:31 PMursus
02/18/2022, 4:31 PMursus
02/18/2022, 4:32 PMLukasz Kalnik
02/18/2022, 4:32 PMLukasz Kalnik
02/18/2022, 4:32 PMursus
02/18/2022, 4:33 PMLukasz Kalnik
02/18/2022, 4:34 PMursus
02/18/2022, 4:35 PMColton Idle
02/18/2022, 5:10 PMWhat to do?I probably wouldn't let the two apps share a VM.
Colton Idle
02/18/2022, 5:12 PMursus
02/18/2022, 7:00 PM