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 Author
Lukasz 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
MessageItem
ursus
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 PMItemDto
Lukasz 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 PMmap
ursus
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 PMMessageOrPromo
ursus
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 PMColumn
Lukasz 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