SlideShare a Scribd company logo
1 of 16
Download to read offline
Creating a Facebook Clone - Part XIV
The notifications container lists alerts received by the app. It's relatively simple.
public class Notification implements PropertyBusinessObject {
public final Property<String, Notification> id = new Property<>("id");
public final Property<User, Notification> user =
new Property<>("user", User.class);
public final Property<String, Notification> text =
new Property<>("text");
public final Property<String, Notification> reaction =
new Property<>("reaction");
public final IntProperty<Notification> reactionColor =
new IntProperty<>("reactionColor");
public final LongProperty<Notification> date =
new LongProperty<>("date");
public final BooleanProperty<Notification> wasRead =
new BooleanProperty<>("wasRead");
private final PropertyIndex idx=new PropertyIndex(this,"Notification",
id, user, text, reaction, reactionColor, date, wasRead);
@Override
public PropertyIndex getPropertyIndex() {
return idx;
}
}
FriendsContainer
To support this page we'll need to add a few things into the data model. First we need to add a new Notification business object to the data package.
public class Notification implements PropertyBusinessObject {
public final Property<String, Notification> id = new Property<>("id");
public final Property<User, Notification> user =
new Property<>("user", User.class);
public final Property<String, Notification> text =
new Property<>("text");
public final Property<String, Notification> reaction =
new Property<>("reaction");
public final IntProperty<Notification> reactionColor =
new IntProperty<>("reactionColor");
public final LongProperty<Notification> date =
new LongProperty<>("date");
public final BooleanProperty<Notification> wasRead =
new BooleanProperty<>("wasRead");
private final PropertyIndex idx=new PropertyIndex(this,"Notification",
id, user, text, reaction, reactionColor, date, wasRead);
@Override
public PropertyIndex getPropertyIndex() {
return idx;
}
}
FriendsContainer
The text of the notification should arrive from the server
public class Notification implements PropertyBusinessObject {
public final Property<String, Notification> id = new Property<>("id");
public final Property<User, Notification> user =
new Property<>("user", User.class);
public final Property<String, Notification> text =
new Property<>("text");
public final Property<String, Notification> reaction =
new Property<>("reaction");
public final IntProperty<Notification> reactionColor =
new IntProperty<>("reactionColor");
public final LongProperty<Notification> date =
new LongProperty<>("date");
public final BooleanProperty<Notification> wasRead =
new BooleanProperty<>("wasRead");
private final PropertyIndex idx=new PropertyIndex(this,"Notification",
id, user, text, reaction, reactionColor, date, wasRead);
@Override
public PropertyIndex getPropertyIndex() {
return idx;
}
}
FriendsContainer
Reaction is the material icon associated with the notification e.g. a heart or thumbUp
public class Notification implements PropertyBusinessObject {
public final Property<String, Notification> id = new Property<>("id");
public final Property<User, Notification> user =
new Property<>("user", User.class);
public final Property<String, Notification> text =
new Property<>("text");
public final Property<String, Notification> reaction =
new Property<>("reaction");
public final IntProperty<Notification> reactionColor =
new IntProperty<>("reactionColor");
public final LongProperty<Notification> date =
new LongProperty<>("date");
public final BooleanProperty<Notification> wasRead =
new BooleanProperty<>("wasRead");
private final PropertyIndex idx=new PropertyIndex(this,"Notification",
id, user, text, reaction, reactionColor, date, wasRead);
@Override
public PropertyIndex getPropertyIndex() {
return idx;
}
}
FriendsContainer
The background color can also come from the server as the original UI has different color for every notification reaction. This is all pretty simple.
return null;
}
public static List<Notification> fetchNotifications(
long since, int amount) {
if(since < initTime - UIUtils.DAY) {
return null;
}
List<Notification> response = new ArrayList<>();
response.add(new Notification().id.set("Notify-1").
user.set(dummyUsers[0]).
text.set("liked Your Post").
date.set(initTime - 60000).
reaction.set("" + FontImage.MATERIAL_FAVORITE).
reactionColor.set(0xff0000));
response.add(new Notification().id.set("Notify-2").
user.set(dummyUsers[1]).
text.set("commented on your post").
date.set(initTime - 600000000).
reaction.set("" + FontImage.MATERIAL_CHAT).
reactionColor.set(0xff00));
return response;
}
}
ServerAPI
To mock this in the UI we'll need a new method in the ServerAPI class
return null;
}
public static List<Notification> fetchNotifications(
long since, int amount) {
if(since < initTime - UIUtils.DAY) {
return null;
}
List<Notification> response = new ArrayList<>();
response.add(new Notification().id.set("Notify-1").
user.set(dummyUsers[0]).
text.set("liked Your Post").
date.set(initTime - 60000).
reaction.set("" + FontImage.MATERIAL_FAVORITE).
reactionColor.set(0xff0000));
response.add(new Notification().id.set("Notify-2").
user.set(dummyUsers[1]).
text.set("commented on your post").
date.set(initTime - 600000000).
reaction.set("" + FontImage.MATERIAL_CHAT).
reactionColor.set(0xff00));
return response;
}
}
ServerAPI
There can be a lot of notifications so we are asking for the notifications since a given time
return null;
}
public static List<Notification> fetchNotifications(
long since, int amount) {
if(since < initTime - UIUtils.DAY) {
return null;
}
List<Notification> response = new ArrayList<>();
response.add(new Notification().id.set("Notify-1").
user.set(dummyUsers[0]).
text.set("liked Your Post").
date.set(initTime - 60000).
reaction.set("" + FontImage.MATERIAL_FAVORITE).
reactionColor.set(0xff0000));
response.add(new Notification().id.set("Notify-2").
user.set(dummyUsers[1]).
text.set("commented on your post").
date.set(initTime - 600000000).
reaction.set("" + FontImage.MATERIAL_CHAT).
reactionColor.set(0xff00));
return response;
}
}
ServerAPI
We construct hardcoded notifications for every entry with a specific hardcoded reaction
© Codename One 2017 all rights reserved
Just so we are on the same page this is the UI of the notification tab

And these are the reactions I was talking about!
public class NotificationsContainer extends InfiniteContainer {
private long lastTime;
@Override
public Component[] fetchComponents(int index, int amount) {
if(index == 0) {
lastTime = System.currentTimeMillis();
}
List<Notification> response = ServerAPI.fetchNotifications(lastTime,
amount);
if(response == null) {
return null;
}
Component[] notifications = new Component[response.size()];
int iter = 0;
for(Notification n : response) {
lastTime = n.date.getLong();
notifications[iter] = createNotificationEntry(n);
iter++;
}
return notifications;
NotificationsContainer
Once we have all these changes in place the notification UI is pretty simple.

We use an InfiniteContainer just like we did in the newsfeed and use the timestamp of the last entry to fetch more
public class NotificationsContainer extends InfiniteContainer {
private long lastTime;
@Override
public Component[] fetchComponents(int index, int amount) {
if(index == 0) {
lastTime = System.currentTimeMillis();
}
List<Notification> response = ServerAPI.fetchNotifications(lastTime,
amount);
if(response == null) {
return null;
}
Component[] notifications = new Component[response.size()];
int iter = 0;
for(Notification n : response) {
lastTime = n.date.getLong();
notifications[iter] = createNotificationEntry(n);
iter++;
}
return notifications;
NotificationsContainer
We update the timestamp for the next request and create a notification component, the code is simple since there are no titles or special components
notifications[iter] = createNotificationEntry(n);
iter++;
}
return notifications;
}
private Container createNotificationEntry(Notification n) {
Image avatar = n.user.get().getAvatar(13);
Label icon = new Label("", "SmallBlueCircle");
icon.getAllStyles().setBorder(RoundBorder.create().
color(n.reactionColor.get()));
FontImage.setMaterialIcon(icon, n.reaction.get().charAt(0), 2);
Container avatarContainer = LayeredLayout.encloseIn(
new Label(avatar, "HalfPaddedContainer"),
FlowLayout.encloseRightBottom(icon));
RichTextView rt = new RichTextView("<b>" + n.user.get().fullName() +
"</b> " + n.text.get());
Label time = new Label(UIUtils.formatTimeAgo(n.date.get()),
"SmallBlueLabel");
Container yContainer = BoxLayout.encloseY(rt, time);
yContainer.setUIID("HalfPaddedContainer");
return BorderLayout.
centerEastWest(yContainer, null, avatarContainer);
}
}
NotificationsContainer
The reaction entry uses the blue circle UIID to annotate the reaction
notifications[iter] = createNotificationEntry(n);
iter++;
}
return notifications;
}
private Container createNotificationEntry(Notification n) {
Image avatar = n.user.get().getAvatar(13);
Label icon = new Label("", "SmallBlueCircle");
icon.getAllStyles().setBorder(RoundBorder.create().
color(n.reactionColor.get()));
FontImage.setMaterialIcon(icon, n.reaction.get().charAt(0), 2);
Container avatarContainer = LayeredLayout.encloseIn(
new Label(avatar, "HalfPaddedContainer"),
FlowLayout.encloseRightBottom(icon));
RichTextView rt = new RichTextView("<b>" + n.user.get().fullName() +
"</b> " + n.text.get());
Label time = new Label(UIUtils.formatTimeAgo(n.date.get()),
"SmallBlueLabel");
Container yContainer = BoxLayout.encloseY(rt, time);
yContainer.setUIID("HalfPaddedContainer");
return BorderLayout.
centerEastWest(yContainer, null, avatarContainer);
}
}
NotificationsContainer
Setting the color won't work correctly and might impact other borders. The solution is creating a new border instance
notifications[iter] = createNotificationEntry(n);
iter++;
}
return notifications;
}
private Container createNotificationEntry(Notification n) {
Image avatar = n.user.get().getAvatar(13);
Label icon = new Label("", "SmallBlueCircle");
icon.getAllStyles().setBorder(RoundBorder.create().
color(n.reactionColor.get()));
FontImage.setMaterialIcon(icon, n.reaction.get().charAt(0), 2);
Container avatarContainer = LayeredLayout.encloseIn(
new Label(avatar, "HalfPaddedContainer"),
FlowLayout.encloseRightBottom(icon));
RichTextView rt = new RichTextView("<b>" + n.user.get().fullName() +
"</b> " + n.text.get());
Label time = new Label(UIUtils.formatTimeAgo(n.date.get()),
"SmallBlueLabel");
Container yContainer = BoxLayout.encloseY(rt, time);
yContainer.setUIID("HalfPaddedContainer");
return BorderLayout.
centerEastWest(yContainer, null, avatarContainer);
}
}
NotificationsContainer
The avatar is placed in a layered layout and the reaction is placed above on the z-axis. We then use a flow layout to align the reaction to the bottom right
notifications[iter] = createNotificationEntry(n);
iter++;
}
return notifications;
}
private Container createNotificationEntry(Notification n) {
Image avatar = n.user.get().getAvatar(13);
Label icon = new Label("", "SmallBlueCircle");
icon.getAllStyles().setBorder(RoundBorder.create().
color(n.reactionColor.get()));
FontImage.setMaterialIcon(icon, n.reaction.get().charAt(0), 2);
Container avatarContainer = LayeredLayout.encloseIn(
new Label(avatar, "HalfPaddedContainer"),
FlowLayout.encloseRightBottom(icon));
RichTextView rt = new RichTextView("<b>" + n.user.get().fullName() +
"</b> " + n.text.get());
Label time = new Label(UIUtils.formatTimeAgo(n.date.get()),
"SmallBlueLabel");
Container yContainer = BoxLayout.encloseY(rt, time);
yContainer.setUIID("HalfPaddedContainer");
return BorderLayout.
centerEastWest(yContainer, null, avatarContainer);
}
}
NotificationsContainer
Just like the other forms we enclose the HTML label and the blue label below into a Y axis Container
SmallBlueLabel {
color: blue;
font-size: 2mm;
padding: 1mm;
font-family: "native:MainLight";
}
theme.css
There is just one missing piece in the CSS from the the listing. The code here is pretty self explanatory, it's a small blue label. With that we only have one last tab to
address...

More Related Content

Similar to Creating a Facebook Clone - Part XIV - Transcript.pdf

Creating a Facebook Clone - Part XII - Transcript.pdf
Creating a Facebook Clone - Part XII - Transcript.pdfCreating a Facebook Clone - Part XII - Transcript.pdf
Creating a Facebook Clone - Part XII - Transcript.pdfShaiAlmog1
 
Creating a Facebook Clone - Part XI.pdf
Creating a Facebook Clone - Part XI.pdfCreating a Facebook Clone - Part XI.pdf
Creating a Facebook Clone - Part XI.pdfShaiAlmog1
 
Creating a Facebook Clone - Part XXIII - Transcript.pdf
Creating a Facebook Clone - Part XXIII - Transcript.pdfCreating a Facebook Clone - Part XXIII - Transcript.pdf
Creating a Facebook Clone - Part XXIII - Transcript.pdfShaiAlmog1
 
Creating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdfCreating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdfShaiAlmog1
 
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019David Wengier
 
Creating a Facebook Clone - Part XL - Transcript.pdf
Creating a Facebook Clone - Part XL - Transcript.pdfCreating a Facebook Clone - Part XL - Transcript.pdf
Creating a Facebook Clone - Part XL - Transcript.pdfShaiAlmog1
 
Android Wear – IO Extended
Android Wear – IO ExtendedAndroid Wear – IO Extended
Android Wear – IO ExtendedDouglas Drumond
 
Creating a Facebook Clone - Part XX - Transcript.pdf
Creating a Facebook Clone - Part XX - Transcript.pdfCreating a Facebook Clone - Part XX - Transcript.pdf
Creating a Facebook Clone - Part XX - Transcript.pdfShaiAlmog1
 
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...Lviv Startup Club
 
Android studio plugin 作ってみた 〜 create intent method generator 〜
Android studio plugin 作ってみた 〜 create intent method generator 〜Android studio plugin 作ってみた 〜 create intent method generator 〜
Android studio plugin 作ってみた 〜 create intent method generator 〜外山 椋
 
Java beginners meetup: Introduction to class and application design
Java beginners meetup: Introduction to class and application designJava beginners meetup: Introduction to class and application design
Java beginners meetup: Introduction to class and application designPatrick Kostjens
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part III - Transcript.pdf
Creating a Whatsapp Clone - Part III - Transcript.pdfCreating a Whatsapp Clone - Part III - Transcript.pdf
Creating a Whatsapp Clone - Part III - Transcript.pdfShaiAlmog1
 
ReactiveCocoa in Practice
ReactiveCocoa in PracticeReactiveCocoa in Practice
ReactiveCocoa in PracticeOutware Mobile
 
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfCreating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfShaiAlmog1
 

Similar to Creating a Facebook Clone - Part XIV - Transcript.pdf (20)

Creating a Facebook Clone - Part XII - Transcript.pdf
Creating a Facebook Clone - Part XII - Transcript.pdfCreating a Facebook Clone - Part XII - Transcript.pdf
Creating a Facebook Clone - Part XII - Transcript.pdf
 
Creating a Facebook Clone - Part XI.pdf
Creating a Facebook Clone - Part XI.pdfCreating a Facebook Clone - Part XI.pdf
Creating a Facebook Clone - Part XI.pdf
 
Notification android
Notification androidNotification android
Notification android
 
Creating a Facebook Clone - Part XXIII - Transcript.pdf
Creating a Facebook Clone - Part XXIII - Transcript.pdfCreating a Facebook Clone - Part XXIII - Transcript.pdf
Creating a Facebook Clone - Part XXIII - Transcript.pdf
 
Creating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdfCreating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdf
 
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019Lowering in C#: What really happens with your code?, from NDC Oslo 2019
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
 
Creating a Facebook Clone - Part XL - Transcript.pdf
Creating a Facebook Clone - Part XL - Transcript.pdfCreating a Facebook Clone - Part XL - Transcript.pdf
Creating a Facebook Clone - Part XL - Transcript.pdf
 
Android Wear – IO Extended
Android Wear – IO ExtendedAndroid Wear – IO Extended
Android Wear – IO Extended
 
Android introduction by vidya topa
Android introduction by vidya topaAndroid introduction by vidya topa
Android introduction by vidya topa
 
Creating a Facebook Clone - Part XX - Transcript.pdf
Creating a Facebook Clone - Part XX - Transcript.pdfCreating a Facebook Clone - Part XX - Transcript.pdf
Creating a Facebook Clone - Part XX - Transcript.pdf
 
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
 
Android studio plugin 作ってみた 〜 create intent method generator 〜
Android studio plugin 作ってみた 〜 create intent method generator 〜Android studio plugin 作ってみた 〜 create intent method generator 〜
Android studio plugin 作ってみた 〜 create intent method generator 〜
 
Java beginners meetup: Introduction to class and application design
Java beginners meetup: Introduction to class and application designJava beginners meetup: Introduction to class and application design
Java beginners meetup: Introduction to class and application design
 
Exercises
ExercisesExercises
Exercises
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdf
 
Creating a Whatsapp Clone - Part III - Transcript.pdf
Creating a Whatsapp Clone - Part III - Transcript.pdfCreating a Whatsapp Clone - Part III - Transcript.pdf
Creating a Whatsapp Clone - Part III - Transcript.pdf
 
ReactiveCocoa in Practice
ReactiveCocoa in PracticeReactiveCocoa in Practice
ReactiveCocoa in Practice
 
Notifications
NotificationsNotifications
Notifications
 
16 18
16 1816 18
16 18
 
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfCreating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
 

More from ShaiAlmog1

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...ShaiAlmog1
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfShaiAlmog1
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfShaiAlmog1
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfShaiAlmog1
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfShaiAlmog1
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfCreating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part VI.pdf
Creating a Whatsapp Clone - Part VI.pdfCreating a Whatsapp Clone - Part VI.pdf
Creating a Whatsapp Clone - Part VI.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part XI - Transcript.pdf
Creating a Whatsapp Clone - Part XI - Transcript.pdfCreating a Whatsapp Clone - Part XI - Transcript.pdf
Creating a Whatsapp Clone - Part XI - Transcript.pdfShaiAlmog1
 

More from ShaiAlmog1 (20)

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdf
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdf
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdf
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdf
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdf
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdf
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdf
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdf
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdf
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdf
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdf
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdf
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdf
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdf
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdf
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdf
 
Creating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfCreating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdf
 
Creating a Whatsapp Clone - Part VI.pdf
Creating a Whatsapp Clone - Part VI.pdfCreating a Whatsapp Clone - Part VI.pdf
Creating a Whatsapp Clone - Part VI.pdf
 
Creating a Whatsapp Clone - Part XI - Transcript.pdf
Creating a Whatsapp Clone - Part XI - Transcript.pdfCreating a Whatsapp Clone - Part XI - Transcript.pdf
Creating a Whatsapp Clone - Part XI - Transcript.pdf
 

Recently uploaded

JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard37
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKJago de Vreede
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMKumar Satyam
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 

Recently uploaded (20)

JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 

Creating a Facebook Clone - Part XIV - Transcript.pdf

  • 1. Creating a Facebook Clone - Part XIV The notifications container lists alerts received by the app. It's relatively simple.
  • 2. public class Notification implements PropertyBusinessObject { public final Property<String, Notification> id = new Property<>("id"); public final Property<User, Notification> user = new Property<>("user", User.class); public final Property<String, Notification> text = new Property<>("text"); public final Property<String, Notification> reaction = new Property<>("reaction"); public final IntProperty<Notification> reactionColor = new IntProperty<>("reactionColor"); public final LongProperty<Notification> date = new LongProperty<>("date"); public final BooleanProperty<Notification> wasRead = new BooleanProperty<>("wasRead"); private final PropertyIndex idx=new PropertyIndex(this,"Notification", id, user, text, reaction, reactionColor, date, wasRead); @Override public PropertyIndex getPropertyIndex() { return idx; } } FriendsContainer To support this page we'll need to add a few things into the data model. First we need to add a new Notification business object to the data package.
  • 3. public class Notification implements PropertyBusinessObject { public final Property<String, Notification> id = new Property<>("id"); public final Property<User, Notification> user = new Property<>("user", User.class); public final Property<String, Notification> text = new Property<>("text"); public final Property<String, Notification> reaction = new Property<>("reaction"); public final IntProperty<Notification> reactionColor = new IntProperty<>("reactionColor"); public final LongProperty<Notification> date = new LongProperty<>("date"); public final BooleanProperty<Notification> wasRead = new BooleanProperty<>("wasRead"); private final PropertyIndex idx=new PropertyIndex(this,"Notification", id, user, text, reaction, reactionColor, date, wasRead); @Override public PropertyIndex getPropertyIndex() { return idx; } } FriendsContainer The text of the notification should arrive from the server
  • 4. public class Notification implements PropertyBusinessObject { public final Property<String, Notification> id = new Property<>("id"); public final Property<User, Notification> user = new Property<>("user", User.class); public final Property<String, Notification> text = new Property<>("text"); public final Property<String, Notification> reaction = new Property<>("reaction"); public final IntProperty<Notification> reactionColor = new IntProperty<>("reactionColor"); public final LongProperty<Notification> date = new LongProperty<>("date"); public final BooleanProperty<Notification> wasRead = new BooleanProperty<>("wasRead"); private final PropertyIndex idx=new PropertyIndex(this,"Notification", id, user, text, reaction, reactionColor, date, wasRead); @Override public PropertyIndex getPropertyIndex() { return idx; } } FriendsContainer Reaction is the material icon associated with the notification e.g. a heart or thumbUp
  • 5. public class Notification implements PropertyBusinessObject { public final Property<String, Notification> id = new Property<>("id"); public final Property<User, Notification> user = new Property<>("user", User.class); public final Property<String, Notification> text = new Property<>("text"); public final Property<String, Notification> reaction = new Property<>("reaction"); public final IntProperty<Notification> reactionColor = new IntProperty<>("reactionColor"); public final LongProperty<Notification> date = new LongProperty<>("date"); public final BooleanProperty<Notification> wasRead = new BooleanProperty<>("wasRead"); private final PropertyIndex idx=new PropertyIndex(this,"Notification", id, user, text, reaction, reactionColor, date, wasRead); @Override public PropertyIndex getPropertyIndex() { return idx; } } FriendsContainer The background color can also come from the server as the original UI has different color for every notification reaction. This is all pretty simple.
  • 6. return null; } public static List<Notification> fetchNotifications( long since, int amount) { if(since < initTime - UIUtils.DAY) { return null; } List<Notification> response = new ArrayList<>(); response.add(new Notification().id.set("Notify-1"). user.set(dummyUsers[0]). text.set("liked Your Post"). date.set(initTime - 60000). reaction.set("" + FontImage.MATERIAL_FAVORITE). reactionColor.set(0xff0000)); response.add(new Notification().id.set("Notify-2"). user.set(dummyUsers[1]). text.set("commented on your post"). date.set(initTime - 600000000). reaction.set("" + FontImage.MATERIAL_CHAT). reactionColor.set(0xff00)); return response; } } ServerAPI To mock this in the UI we'll need a new method in the ServerAPI class
  • 7. return null; } public static List<Notification> fetchNotifications( long since, int amount) { if(since < initTime - UIUtils.DAY) { return null; } List<Notification> response = new ArrayList<>(); response.add(new Notification().id.set("Notify-1"). user.set(dummyUsers[0]). text.set("liked Your Post"). date.set(initTime - 60000). reaction.set("" + FontImage.MATERIAL_FAVORITE). reactionColor.set(0xff0000)); response.add(new Notification().id.set("Notify-2"). user.set(dummyUsers[1]). text.set("commented on your post"). date.set(initTime - 600000000). reaction.set("" + FontImage.MATERIAL_CHAT). reactionColor.set(0xff00)); return response; } } ServerAPI There can be a lot of notifications so we are asking for the notifications since a given time
  • 8. return null; } public static List<Notification> fetchNotifications( long since, int amount) { if(since < initTime - UIUtils.DAY) { return null; } List<Notification> response = new ArrayList<>(); response.add(new Notification().id.set("Notify-1"). user.set(dummyUsers[0]). text.set("liked Your Post"). date.set(initTime - 60000). reaction.set("" + FontImage.MATERIAL_FAVORITE). reactionColor.set(0xff0000)); response.add(new Notification().id.set("Notify-2"). user.set(dummyUsers[1]). text.set("commented on your post"). date.set(initTime - 600000000). reaction.set("" + FontImage.MATERIAL_CHAT). reactionColor.set(0xff00)); return response; } } ServerAPI We construct hardcoded notifications for every entry with a specific hardcoded reaction
  • 9. © Codename One 2017 all rights reserved Just so we are on the same page this is the UI of the notification tab And these are the reactions I was talking about!
  • 10. public class NotificationsContainer extends InfiniteContainer { private long lastTime; @Override public Component[] fetchComponents(int index, int amount) { if(index == 0) { lastTime = System.currentTimeMillis(); } List<Notification> response = ServerAPI.fetchNotifications(lastTime, amount); if(response == null) { return null; } Component[] notifications = new Component[response.size()]; int iter = 0; for(Notification n : response) { lastTime = n.date.getLong(); notifications[iter] = createNotificationEntry(n); iter++; } return notifications; NotificationsContainer Once we have all these changes in place the notification UI is pretty simple. We use an InfiniteContainer just like we did in the newsfeed and use the timestamp of the last entry to fetch more
  • 11. public class NotificationsContainer extends InfiniteContainer { private long lastTime; @Override public Component[] fetchComponents(int index, int amount) { if(index == 0) { lastTime = System.currentTimeMillis(); } List<Notification> response = ServerAPI.fetchNotifications(lastTime, amount); if(response == null) { return null; } Component[] notifications = new Component[response.size()]; int iter = 0; for(Notification n : response) { lastTime = n.date.getLong(); notifications[iter] = createNotificationEntry(n); iter++; } return notifications; NotificationsContainer We update the timestamp for the next request and create a notification component, the code is simple since there are no titles or special components
  • 12. notifications[iter] = createNotificationEntry(n); iter++; } return notifications; } private Container createNotificationEntry(Notification n) { Image avatar = n.user.get().getAvatar(13); Label icon = new Label("", "SmallBlueCircle"); icon.getAllStyles().setBorder(RoundBorder.create(). color(n.reactionColor.get())); FontImage.setMaterialIcon(icon, n.reaction.get().charAt(0), 2); Container avatarContainer = LayeredLayout.encloseIn( new Label(avatar, "HalfPaddedContainer"), FlowLayout.encloseRightBottom(icon)); RichTextView rt = new RichTextView("<b>" + n.user.get().fullName() + "</b> " + n.text.get()); Label time = new Label(UIUtils.formatTimeAgo(n.date.get()), "SmallBlueLabel"); Container yContainer = BoxLayout.encloseY(rt, time); yContainer.setUIID("HalfPaddedContainer"); return BorderLayout. centerEastWest(yContainer, null, avatarContainer); } } NotificationsContainer The reaction entry uses the blue circle UIID to annotate the reaction
  • 13. notifications[iter] = createNotificationEntry(n); iter++; } return notifications; } private Container createNotificationEntry(Notification n) { Image avatar = n.user.get().getAvatar(13); Label icon = new Label("", "SmallBlueCircle"); icon.getAllStyles().setBorder(RoundBorder.create(). color(n.reactionColor.get())); FontImage.setMaterialIcon(icon, n.reaction.get().charAt(0), 2); Container avatarContainer = LayeredLayout.encloseIn( new Label(avatar, "HalfPaddedContainer"), FlowLayout.encloseRightBottom(icon)); RichTextView rt = new RichTextView("<b>" + n.user.get().fullName() + "</b> " + n.text.get()); Label time = new Label(UIUtils.formatTimeAgo(n.date.get()), "SmallBlueLabel"); Container yContainer = BoxLayout.encloseY(rt, time); yContainer.setUIID("HalfPaddedContainer"); return BorderLayout. centerEastWest(yContainer, null, avatarContainer); } } NotificationsContainer Setting the color won't work correctly and might impact other borders. The solution is creating a new border instance
  • 14. notifications[iter] = createNotificationEntry(n); iter++; } return notifications; } private Container createNotificationEntry(Notification n) { Image avatar = n.user.get().getAvatar(13); Label icon = new Label("", "SmallBlueCircle"); icon.getAllStyles().setBorder(RoundBorder.create(). color(n.reactionColor.get())); FontImage.setMaterialIcon(icon, n.reaction.get().charAt(0), 2); Container avatarContainer = LayeredLayout.encloseIn( new Label(avatar, "HalfPaddedContainer"), FlowLayout.encloseRightBottom(icon)); RichTextView rt = new RichTextView("<b>" + n.user.get().fullName() + "</b> " + n.text.get()); Label time = new Label(UIUtils.formatTimeAgo(n.date.get()), "SmallBlueLabel"); Container yContainer = BoxLayout.encloseY(rt, time); yContainer.setUIID("HalfPaddedContainer"); return BorderLayout. centerEastWest(yContainer, null, avatarContainer); } } NotificationsContainer The avatar is placed in a layered layout and the reaction is placed above on the z-axis. We then use a flow layout to align the reaction to the bottom right
  • 15. notifications[iter] = createNotificationEntry(n); iter++; } return notifications; } private Container createNotificationEntry(Notification n) { Image avatar = n.user.get().getAvatar(13); Label icon = new Label("", "SmallBlueCircle"); icon.getAllStyles().setBorder(RoundBorder.create(). color(n.reactionColor.get())); FontImage.setMaterialIcon(icon, n.reaction.get().charAt(0), 2); Container avatarContainer = LayeredLayout.encloseIn( new Label(avatar, "HalfPaddedContainer"), FlowLayout.encloseRightBottom(icon)); RichTextView rt = new RichTextView("<b>" + n.user.get().fullName() + "</b> " + n.text.get()); Label time = new Label(UIUtils.formatTimeAgo(n.date.get()), "SmallBlueLabel"); Container yContainer = BoxLayout.encloseY(rt, time); yContainer.setUIID("HalfPaddedContainer"); return BorderLayout. centerEastWest(yContainer, null, avatarContainer); } } NotificationsContainer Just like the other forms we enclose the HTML label and the blue label below into a Y axis Container
  • 16. SmallBlueLabel { color: blue; font-size: 2mm; padding: 1mm; font-family: "native:MainLight"; } theme.css There is just one missing piece in the CSS from the the listing. The code here is pretty self explanatory, it's a small blue label. With that we only have one last tab to address...