Higher Order Components and Render PropsNitish Phanse
Talk given at React foo Hyderabad 2018. Outlines the differences between higher order components and render props. Both being design patterns used primarily to aid reusability of components across a codebase.
C++ Please I am posting the fifth time and hoping to get th.pdfjaipur2
C++
"Please I am posting the fifth time and hoping to get this resolved. I want the year to
change from 2014 to 2015 but the days of the month change to 32 rather than 1/1/2015.
Also, Please I want personal information in the heading as well Name: Last: and Course
Name:"
Modify the Time class(attached) to be able to work with Date class. The Time object should
always
remain in a consistent state.
Modify the Date class(attached) to include a Time class object as a composition, a tick member
function that increments the time stored in a Date object by one second, and increaseADay
function to
increase day, month and year when it is proper. Please use CISP400V10A4.cpp that tests the tick
member function in a loop that prints the time in standard format during iteration of the loop to
illustrate that the tick member function works correctly. Be aware that we are testing the following
cases:
a) Incrementing into the next minute.
b) Incrementing into the next hour.
c) Incrementing into the next day (i.e., 11:59:59 PM to 12:00:00 AM).
d) Incrementing into the next month and next year.
Time class
The Time class has three private integer data members, hour (0 - 23 (24-hour clock format)),
minute (0
59), and second (0 59).
It also has Time, setTime, setHour, setMinute, setSecond, getHour(), getMinute,
getSecond,~Time,
printUniversal, and printStandard public functions.
1. The Time function is a default constructor. It takes three integers and they all have 0 as default
values. It also displays "Time object constructor is called." message and calls
printStandard
and printUniversal functions.
2. The setTime function takes three integers but does not return any value. It initializes the
private data members (hour, minute and second) data.
3. The setHour function takes one integer but doesnt return anything. It validates and stores the
integer to the hour private data member.
4. The setMinute function takes one integer but doesnt return anything. It validates and stores
the integer to the minute private data member.
5. The setSecond function takes one integer but doesnt return anything. It validates and stores
the integer to the second private data member.
Page 3 of 11 CISP400V10A4
6. The getHour constant function returns one integer but doesnt take anything. It returns the
private data member hours data.
7. The getMinute constant function returns one integer but doesnt take anything. It returns the
private data member minutes data.
8. The getSecond constant function returns one integer but doesnt take anything. It returns the
private data member seconds data.
9. The Time destructor does not take anything. It displays "Time object destructor is
called."
message and calls printStandard and printUniversal functions.
10. The printUniversal constant function does not return or accept anything. It displays time in
universal-time format.
11. The printStandard constant function does not return or accept anything. It displays time in
standard-ti.
From object oriented to functional domain modelingCodemotion
"From object oriented to functional domain modeling" by Mario Fusco
Malgrado l'introduzione delle lambda, la gran parte degli sviluppatori Java non è ancora abituata agli idiomi della programmazione funzionale e quindi non è pronta a sfruttare a pieno le potenzialità di Java 8. In particolare non è ancora comune vedere dati e funzioni usate insieme quando si modella un dominio di business. Lo scopo del talk è mostrare come alcuni principi di programmazione funzionale quali l'impiego di oggetti e strutture dati immutabili, l'uso di funzioni senza side-effect e il loro reuso mediante composizione, possono anche essere validi strumenti di domain modelling.
JAVA.Q4 Create a Time class. This class will represent a point in.pdfkarymadelaneyrenne19
JAVA.
Q4: Create a Time class. This class will represent a point in time, such as a departure time. It
should contain 2 constructors, 2 instance variables (hour and minute), and 10 methods (see
below). All methods but toString should be in terms of the 24 hour format. [30 points]
default constructor: Creates a Time object for 12:00AM.
overloaded constructor: Creates a Time object at a specific hour and minute.
getHour(): Returns an integer representing the hour of the Time object.
getMinute(): Returns an integer representing the minute of the Time object.
addHours(...): Updates the object by moving it forward a number of hours.
addMinute(...): Updates the object by moving it forward a number of minutes. (Hint: Be careful
that you don\'t allow minutes to be more than 59.)
addTime(...): Updates the object by moving it forward by the hour and minute from another
Time object.
getCopy(...): Returns a new Time object that has the same hour and minute of the existing Time
object.
isEarlierThan(...): Returns true if this Time object is earlier than another Time object.
isSameTime(...): Returns true if this Time object is the same as another Time object.
isLaterThan(...): Returns true if this Time object is later than another Time object.
toString(): Returns a string representing the Time object. Uses 12 hour AM/PM format and pads
minutes to be two digits. See the sample output for an example.
Q5: Create a Flight class that uses the Plane and Time class. This class will represent a flight
between two airports, using a specific Plane, and departing at a specific Time. It should contain a
constructor, 7 instance variables (plane, flight number, cost, departure, duration, source,
destination), and 9 methods (see below). [25 points]
overloaded constructor: Creates a Flight object that is setup up with a Plane, a flight number, a
cost, a departure Time, a duration time, a source Airport, and a destination Airport.
getPlane(): Returns the Plane that operates this flight.
getNumber(): Returns the flight number.
getCost(): Returns the flight cost.
getDestination(): Returns the destination Airport.
getDeparture(): Returns the departure Time.
getArrival(): Returns a Time object with the arrival time (computed from the departure time and
duration).
getSource(): Returns a Airport object for the departure location.
toOverviewString(): Returns a String representing an overview of the flight. Use NumberFormat
to display the price. See the sample output for an example.
toDetailedString(): Returns a String representing the flight\'s detail information. See the sample
output for an example.
Included below is an overall UML diagram that describes the three classes you will be
constructing. It provides a useful summary of all of the methods you are expected to implement,
and their corresponding types and visibility. Notice that one private method is listed here
(formatDigits in Time) that isn\'t mentioned above. This is a method that was in our solution, you
may not need.
An object of class StatCalc can be used to compute several simp.pdfaravlitraders2012
/*
An object of class StatCalc can be used to compute several simple statistics
for a set of numbers. Numbers are entered into the dataset using
the enter(double) method. Methods are provided to return the following
statistics for the set of numbers that have been entered: The number
of items, the sum of the items, the average, the standard deviation,
the maximum, and the minimum.
*/
public class Stats {
private int count; // Number of numbers that have been entered.
private double sum; // The sum of all the items that have been entered.
private double squareSum; // The sum of the squares of all the items.
private double max = Double.NEGATIVE_INFINITY; // Largest item seen.
private double min = Double.POSITIVE_INFINITY; // Smallest item seen.
int[] myList;
public int getCount() {
System.out.println(myList.size());
count = myList.size().
// Return number of items that have been entered.
return count;
}
public double getSum() {
int sum = 0;
for (int i = 0; i < myList.length; i++)
{
sum +=mylist[i];
}
return sum;
}
public double getMean() {
int sum = 0;
for (int i = 0; i < myList.length; i++)
{
sum +=mylist[i];
}
if(count > 0)
return sum / count;
else
return -1;
}
public double getMin() {
int smallest = myList[0];
int largetst = myList[0];
for(int i=1; i< mylist.length; i++)
{
if(mylist[i] > largetst)
largetst = numbers[i];
else if (mylist[i] < smallest)
smallest = numbers[i];
}
return smallest;
}
public double getMax() {
int smallest = myList[0];
int largetst = myList[0];
for(int i=1; i< mylist.length; i++)
{
if(mylist[i] > largetst)
largetst = numbers[i];
else if (mylist[i] < smallest)
smallest = numbers[i];
}
return largetst;
}
stats(int [] data)
{
if(data.count <= count)
{
if(myList.size() > 0)
System.arraycopy( myList, 0, data, 0, count );
}
}
stats()
{
Scanner s = new Scanner(System.in);
int count = s.nextInt();
s.nextLine(); // throw away the newline.
int [] numbers = new int[count];
Scanner numScanner = new Scanner(s.nextLine());
for (int i = 0; i < count; i++) {
if (numScanner.hasNextInt()) {
numbers[i] = numScanner.nextInt();
} else {
System.out.println(\"You didn\'t provide enough numbers\");
break;
}
}
System.arraycopy( myList, 0, numbers, 0, count );
}
stats(int size)
{
setValue(size);
}
private void setValue(int size)
{
count = size;
myList = new int[size];
}
} // end class StatCalc
public class SimpleStats {
public static void main(String[] args) {
Stat calc; // Computes stats for numbers entered by user.
calc = new Stat(100);
int arry[] = {20.20.40,30.80,,70,4,5,6,7,10}
calc.setvalue(array);
double item; // One number entered by the user.
TextIO.putln(\"Enter your numbers. Enter 0 to end.\");
TextIO.putln();
do {
TextIO.put(\"? \");
item = TextIO.getlnDouble();
if (item != 0)
calc.enter(item);
} while ( item != 0 );
TextIO.putln(\"\ Statistics about your calc:\ \");
TextIO.putln(\" Count: \" + calc.getCount());
TextIO.putln(\" Sum: \" + calc.getSum());
TextIO.putln(\" Minimum: \" + calc.getMin());
TextIO.putln(\" Maximum: \" + ca.
Higher Order Components and Render PropsNitish Phanse
Talk given at React foo Hyderabad 2018. Outlines the differences between higher order components and render props. Both being design patterns used primarily to aid reusability of components across a codebase.
C++ Please I am posting the fifth time and hoping to get th.pdfjaipur2
C++
"Please I am posting the fifth time and hoping to get this resolved. I want the year to
change from 2014 to 2015 but the days of the month change to 32 rather than 1/1/2015.
Also, Please I want personal information in the heading as well Name: Last: and Course
Name:"
Modify the Time class(attached) to be able to work with Date class. The Time object should
always
remain in a consistent state.
Modify the Date class(attached) to include a Time class object as a composition, a tick member
function that increments the time stored in a Date object by one second, and increaseADay
function to
increase day, month and year when it is proper. Please use CISP400V10A4.cpp that tests the tick
member function in a loop that prints the time in standard format during iteration of the loop to
illustrate that the tick member function works correctly. Be aware that we are testing the following
cases:
a) Incrementing into the next minute.
b) Incrementing into the next hour.
c) Incrementing into the next day (i.e., 11:59:59 PM to 12:00:00 AM).
d) Incrementing into the next month and next year.
Time class
The Time class has three private integer data members, hour (0 - 23 (24-hour clock format)),
minute (0
59), and second (0 59).
It also has Time, setTime, setHour, setMinute, setSecond, getHour(), getMinute,
getSecond,~Time,
printUniversal, and printStandard public functions.
1. The Time function is a default constructor. It takes three integers and they all have 0 as default
values. It also displays "Time object constructor is called." message and calls
printStandard
and printUniversal functions.
2. The setTime function takes three integers but does not return any value. It initializes the
private data members (hour, minute and second) data.
3. The setHour function takes one integer but doesnt return anything. It validates and stores the
integer to the hour private data member.
4. The setMinute function takes one integer but doesnt return anything. It validates and stores
the integer to the minute private data member.
5. The setSecond function takes one integer but doesnt return anything. It validates and stores
the integer to the second private data member.
Page 3 of 11 CISP400V10A4
6. The getHour constant function returns one integer but doesnt take anything. It returns the
private data member hours data.
7. The getMinute constant function returns one integer but doesnt take anything. It returns the
private data member minutes data.
8. The getSecond constant function returns one integer but doesnt take anything. It returns the
private data member seconds data.
9. The Time destructor does not take anything. It displays "Time object destructor is
called."
message and calls printStandard and printUniversal functions.
10. The printUniversal constant function does not return or accept anything. It displays time in
universal-time format.
11. The printStandard constant function does not return or accept anything. It displays time in
standard-ti.
From object oriented to functional domain modelingCodemotion
"From object oriented to functional domain modeling" by Mario Fusco
Malgrado l'introduzione delle lambda, la gran parte degli sviluppatori Java non è ancora abituata agli idiomi della programmazione funzionale e quindi non è pronta a sfruttare a pieno le potenzialità di Java 8. In particolare non è ancora comune vedere dati e funzioni usate insieme quando si modella un dominio di business. Lo scopo del talk è mostrare come alcuni principi di programmazione funzionale quali l'impiego di oggetti e strutture dati immutabili, l'uso di funzioni senza side-effect e il loro reuso mediante composizione, possono anche essere validi strumenti di domain modelling.
JAVA.Q4 Create a Time class. This class will represent a point in.pdfkarymadelaneyrenne19
JAVA.
Q4: Create a Time class. This class will represent a point in time, such as a departure time. It
should contain 2 constructors, 2 instance variables (hour and minute), and 10 methods (see
below). All methods but toString should be in terms of the 24 hour format. [30 points]
default constructor: Creates a Time object for 12:00AM.
overloaded constructor: Creates a Time object at a specific hour and minute.
getHour(): Returns an integer representing the hour of the Time object.
getMinute(): Returns an integer representing the minute of the Time object.
addHours(...): Updates the object by moving it forward a number of hours.
addMinute(...): Updates the object by moving it forward a number of minutes. (Hint: Be careful
that you don\'t allow minutes to be more than 59.)
addTime(...): Updates the object by moving it forward by the hour and minute from another
Time object.
getCopy(...): Returns a new Time object that has the same hour and minute of the existing Time
object.
isEarlierThan(...): Returns true if this Time object is earlier than another Time object.
isSameTime(...): Returns true if this Time object is the same as another Time object.
isLaterThan(...): Returns true if this Time object is later than another Time object.
toString(): Returns a string representing the Time object. Uses 12 hour AM/PM format and pads
minutes to be two digits. See the sample output for an example.
Q5: Create a Flight class that uses the Plane and Time class. This class will represent a flight
between two airports, using a specific Plane, and departing at a specific Time. It should contain a
constructor, 7 instance variables (plane, flight number, cost, departure, duration, source,
destination), and 9 methods (see below). [25 points]
overloaded constructor: Creates a Flight object that is setup up with a Plane, a flight number, a
cost, a departure Time, a duration time, a source Airport, and a destination Airport.
getPlane(): Returns the Plane that operates this flight.
getNumber(): Returns the flight number.
getCost(): Returns the flight cost.
getDestination(): Returns the destination Airport.
getDeparture(): Returns the departure Time.
getArrival(): Returns a Time object with the arrival time (computed from the departure time and
duration).
getSource(): Returns a Airport object for the departure location.
toOverviewString(): Returns a String representing an overview of the flight. Use NumberFormat
to display the price. See the sample output for an example.
toDetailedString(): Returns a String representing the flight\'s detail information. See the sample
output for an example.
Included below is an overall UML diagram that describes the three classes you will be
constructing. It provides a useful summary of all of the methods you are expected to implement,
and their corresponding types and visibility. Notice that one private method is listed here
(formatDigits in Time) that isn\'t mentioned above. This is a method that was in our solution, you
may not need.
An object of class StatCalc can be used to compute several simp.pdfaravlitraders2012
/*
An object of class StatCalc can be used to compute several simple statistics
for a set of numbers. Numbers are entered into the dataset using
the enter(double) method. Methods are provided to return the following
statistics for the set of numbers that have been entered: The number
of items, the sum of the items, the average, the standard deviation,
the maximum, and the minimum.
*/
public class Stats {
private int count; // Number of numbers that have been entered.
private double sum; // The sum of all the items that have been entered.
private double squareSum; // The sum of the squares of all the items.
private double max = Double.NEGATIVE_INFINITY; // Largest item seen.
private double min = Double.POSITIVE_INFINITY; // Smallest item seen.
int[] myList;
public int getCount() {
System.out.println(myList.size());
count = myList.size().
// Return number of items that have been entered.
return count;
}
public double getSum() {
int sum = 0;
for (int i = 0; i < myList.length; i++)
{
sum +=mylist[i];
}
return sum;
}
public double getMean() {
int sum = 0;
for (int i = 0; i < myList.length; i++)
{
sum +=mylist[i];
}
if(count > 0)
return sum / count;
else
return -1;
}
public double getMin() {
int smallest = myList[0];
int largetst = myList[0];
for(int i=1; i< mylist.length; i++)
{
if(mylist[i] > largetst)
largetst = numbers[i];
else if (mylist[i] < smallest)
smallest = numbers[i];
}
return smallest;
}
public double getMax() {
int smallest = myList[0];
int largetst = myList[0];
for(int i=1; i< mylist.length; i++)
{
if(mylist[i] > largetst)
largetst = numbers[i];
else if (mylist[i] < smallest)
smallest = numbers[i];
}
return largetst;
}
stats(int [] data)
{
if(data.count <= count)
{
if(myList.size() > 0)
System.arraycopy( myList, 0, data, 0, count );
}
}
stats()
{
Scanner s = new Scanner(System.in);
int count = s.nextInt();
s.nextLine(); // throw away the newline.
int [] numbers = new int[count];
Scanner numScanner = new Scanner(s.nextLine());
for (int i = 0; i < count; i++) {
if (numScanner.hasNextInt()) {
numbers[i] = numScanner.nextInt();
} else {
System.out.println(\"You didn\'t provide enough numbers\");
break;
}
}
System.arraycopy( myList, 0, numbers, 0, count );
}
stats(int size)
{
setValue(size);
}
private void setValue(int size)
{
count = size;
myList = new int[size];
}
} // end class StatCalc
public class SimpleStats {
public static void main(String[] args) {
Stat calc; // Computes stats for numbers entered by user.
calc = new Stat(100);
int arry[] = {20.20.40,30.80,,70,4,5,6,7,10}
calc.setvalue(array);
double item; // One number entered by the user.
TextIO.putln(\"Enter your numbers. Enter 0 to end.\");
TextIO.putln();
do {
TextIO.put(\"? \");
item = TextIO.getlnDouble();
if (item != 0)
calc.enter(item);
} while ( item != 0 );
TextIO.putln(\"\ Statistics about your calc:\ \");
TextIO.putln(\" Count: \" + calc.getCount());
TextIO.putln(\" Sum: \" + calc.getSum());
TextIO.putln(\" Minimum: \" + calc.getMin());
TextIO.putln(\" Maximum: \" + ca.
"Impact of front-end architecture on development cost", Viktor TurskyiFwdays
I have heard many times that architecture is not important for the front-end. Also, many times I have seen how developers implement features on the front-end just following the standard rules for a framework and think that this is enough to successfully launch the project, and then the project fails. How to prevent this and what approach to choose? I have launched dozens of complex projects and during the talk we will analyze which approaches have worked for me and which have not.
Transcript: Selling digital books in 2024: Insights from industry leaders - T...BookNet Canada
The publishing industry has been selling digital audiobooks and ebooks for over a decade and has found its groove. What’s changed? What has stayed the same? Where do we go from here? Join a group of leading sales peers from across the industry for a conversation about the lessons learned since the popularization of digital books, best practices, digital book supply chain management, and more.
Link to video recording: https://bnctechforum.ca/sessions/selling-digital-books-in-2024-insights-from-industry-leaders/
Presented by BookNet Canada on May 28, 2024, with support from the Department of Canadian Heritage.
КАТЕРИНА АБЗЯТОВА «Ефективне планування тестування ключові аспекти та практ...QADay
Lviv Direction QADay 2024 (Professional Development)
КАТЕРИНА АБЗЯТОВА
«Ефективне планування тестування ключові аспекти та практичні поради»
https://linktr.ee/qadayua
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf91mobiles
91mobiles recently conducted a Smart TV Buyer Insights Survey in which we asked over 3,000 respondents about the TV they own, aspects they look at on a new TV, and their TV buying preferences.
The Art of the Pitch: WordPress Relationships and SalesLaura Byrne
Clients don’t know what they don’t know. What web solutions are right for them? How does WordPress come into the picture? How do you make sure you understand scope and timeline? What do you do if sometime changes?
All these questions and more will be explored as we talk about matching clients’ needs with what your agency offers without pulling teeth or pulling your hair out. Practical tips, and strategies for successful relationship building that leads to closing the deal.
UiPath New York Community Day in-person eventDianaGray10
UiPath Community Day is a unique gathering designed to foster collaboration, learning, and networking with automation enthusiasts. Whether you're an automation developer, business analyst, IT professional, solution architect, CoE lead, practitioner or a student/educator excited about the prospects of artificial intelligence and automation technologies in the United States, then the UiPath Community Day is definitely the place you want to be.
Join UiPath leaders, experts from the industry, and the amazing community members and let's connect over expert sessions, demos and use cases around AI in automation as we highlight our technology with a special speaker on Document Understanding.
📌Agenda
3:00 PM Registrations
3:30 PM Welcome note and Introductions | Corina Gheonea (Senior Director of Global UiPath Community)
4:00 PM Introduction to Document Understanding
How to build and deploy Document Understanding process
Where would Document Understanding be used.
Demo
Q&A
4:45 PM Customer/Partner showcase
Accelirate
Intro to Accelirate and history with UiPath
Why are we excited about the new AI features of UiPath?
Customer highlight
a. Document Understanding – BJs Case Study
b. Document Understanding + generative AI
5.30 PM Networking
UiPath Test Automation using UiPath Test Suite series, part 3DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 3. In this session, we will cover desktop automation along with UI automation.
Topics covered:
UI automation Introduction,
UI automation Sample
Desktop automation flow
Pradeep Chinnala, Senior Consultant Automation Developer @WonderBotz and UiPath MVP
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
State of ICS and IoT Cyber Threat Landscape Report 2024 previewPrayukth K V
The IoT and OT threat landscape report has been prepared by the Threat Research Team at Sectrio using data from Sectrio, cyber threat intelligence farming facilities spread across over 85 cities around the world. In addition, Sectrio also runs AI-based advanced threat and payload engagement facilities that serve as sinks to attract and engage sophisticated threat actors, and newer malware including new variants and latent threats that are at an earlier stage of development.
The latest edition of the OT/ICS and IoT security Threat Landscape Report 2024 also covers:
State of global ICS asset and network exposure
Sectoral targets and attacks as well as the cost of ransom
Global APT activity, AI usage, actor and tactic profiles, and implications
Rise in volumes of AI-powered cyberattacks
Major cyber events in 2024
Malware and malicious payload trends
Cyberattack types and targets
Vulnerability exploit attempts on CVEs
Attacks on counties – USA
Expansion of bot farms – how, where, and why
In-depth analysis of the cyber threat landscape across North America, South America, Europe, APAC, and the Middle East
Why are attacks on smart factories rising?
Cyber risk predictions
Axis of attacks – Europe
Systemic attacks in the Middle East
Download the full report from here:
https://sectrio.com/resources/ot-threat-landscape-reports/sectrio-releases-ot-ics-and-iot-security-threat-landscape-report-2024/
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Ramesh Iyer
In today's fast-changing business world, Companies that adapt and embrace new ideas often need help to keep up with the competition. However, fostering a culture of innovation takes much work. It takes vision, leadership and willingness to take risks in the right proportion. Sachin Dev Duggal, co-founder of Builder.ai, has perfected the art of this balance, creating a company culture where creativity and growth are nurtured at each stage.
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Tobias Schneck
As AI technology is pushing into IT I was wondering myself, as an “infrastructure container kubernetes guy”, how get this fancy AI technology get managed from an infrastructure operational view? Is it possible to apply our lovely cloud native principals as well? What benefit’s both technologies could bring to each other?
Let me take this questions and provide you a short journey through existing deployment models and use cases for AI software. On practical examples, we discuss what cloud/on-premise strategy we may need for applying it to our own infrastructure to get it to work from an enterprise perspective. I want to give an overview about infrastructure requirements and technologies, what could be beneficial or limiting your AI use cases in an enterprise environment. An interactive Demo will give you some insides, what approaches I got already working for real.
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualityInflectra
In this insightful webinar, Inflectra explores how artificial intelligence (AI) is transforming software development and testing. Discover how AI-powered tools are revolutionizing every stage of the software development lifecycle (SDLC), from design and prototyping to testing, deployment, and monitoring.
Learn about:
• The Future of Testing: How AI is shifting testing towards verification, analysis, and higher-level skills, while reducing repetitive tasks.
• Test Automation: How AI-powered test case generation, optimization, and self-healing tests are making testing more efficient and effective.
• Visual Testing: Explore the emerging capabilities of AI in visual testing and how it's set to revolutionize UI verification.
• Inflectra's AI Solutions: See demonstrations of Inflectra's cutting-edge AI tools like the ChatGPT plugin and Azure Open AI platform, designed to streamline your testing process.
Whether you're a developer, tester, or QA professional, this webinar will give you valuable insights into how AI is shaping the future of software delivery.
3. public class NewsfeedContainer extends InfiniteContainer {
private long lastTime;
@Override
public Component[] fetchComponents(int index, int amount) {
List<Component> components = new ArrayList<>();
if(index == 0) {
lastTime = System.currentTimeMillis();
components.add(createPostBar());
components.add(UIUtils.createSpace());
}
List<Post> response = ServerAPI.fetchTimelinePosts(lastTime, amount);
if(response == null) {
return null;
}
for(Post p : response) {
components.add(createNewsItem(p.user.get(), p));
components.add(UIUtils.createHalfSpace());
lastTime = p.date.getLong();
}
Component[] cmps = new Component[components.size()];
components.toArray(cmps);
NewsfeedContainer
Now that we have a sense of what we are building lets look at the high level class skeleton then fill in the pieces.
We use the last time value when invoking fetchTimelinePosts so the latest data arrives
4. public class NewsfeedContainer extends InfiniteContainer {
private long lastTime;
@Override
public Component[] fetchComponents(int index, int amount) {
List<Component> components = new ArrayList<>();
if(index == 0) {
lastTime = System.currentTimeMillis();
components.add(createPostBar());
components.add(UIUtils.createSpace());
}
List<Post> response = ServerAPI.fetchTimelinePosts(lastTime, amount);
if(response == null) {
return null;
}
for(Post p : response) {
components.add(createNewsItem(p.user.get(), p));
components.add(UIUtils.createHalfSpace());
lastTime = p.date.getLong();
}
Component[] cmps = new Component[components.size()];
components.toArray(cmps);
NewsfeedContainer
This method is invoked when the user scrolls and needs more data or when pull-to-refresh is used
5. public class NewsfeedContainer extends InfiniteContainer {
private long lastTime;
@Override
public Component[] fetchComponents(int index, int amount) {
List<Component> components = new ArrayList<>();
if(index == 0) {
lastTime = System.currentTimeMillis();
components.add(createPostBar());
components.add(UIUtils.createSpace());
}
List<Post> response = ServerAPI.fetchTimelinePosts(lastTime, amount);
if(response == null) {
return null;
}
for(Post p : response) {
components.add(createNewsItem(p.user.get(), p));
components.add(UIUtils.createHalfSpace());
lastTime = p.date.getLong();
}
Component[] cmps = new Component[components.size()];
components.toArray(cmps);
NewsfeedContainer
It's hard to tell how many components we'll return so we'll use a list and convert it to an array when we are done
6. public class NewsfeedContainer extends InfiniteContainer {
private long lastTime;
@Override
public Component[] fetchComponents(int index, int amount) {
List<Component> components = new ArrayList<>();
if(index == 0) {
lastTime = System.currentTimeMillis();
components.add(createPostBar());
components.add(UIUtils.createSpace());
}
List<Post> response = ServerAPI.fetchTimelinePosts(lastTime, amount);
if(response == null) {
return null;
}
for(Post p : response) {
components.add(createNewsItem(p.user.get(), p));
components.add(UIUtils.createHalfSpace());
lastTime = p.date.getLong();
}
Component[] cmps = new Component[components.size()];
components.toArray(cmps);
NewsfeedContainer
If this is the first entry we reset the value of lastTime before making the request
7. public class NewsfeedContainer extends InfiniteContainer {
private long lastTime;
@Override
public Component[] fetchComponents(int index, int amount) {
List<Component> components = new ArrayList<>();
if(index == 0) {
lastTime = System.currentTimeMillis();
components.add(createPostBar());
components.add(UIUtils.createSpace());
}
List<Post> response = ServerAPI.fetchTimelinePosts(lastTime, amount);
if(response == null) {
return null;
}
for(Post p : response) {
components.add(createNewsItem(p.user.get(), p));
components.add(UIUtils.createHalfSpace());
lastTime = p.date.getLong();
}
Component[] cmps = new Component[components.size()];
components.toArray(cmps);
NewsfeedContainer
The top is always the same component: the post bar. That's where we can add a new post
8. public class NewsfeedContainer extends InfiniteContainer {
private long lastTime;
@Override
public Component[] fetchComponents(int index, int amount) {
List<Component> components = new ArrayList<>();
if(index == 0) {
lastTime = System.currentTimeMillis();
components.add(createPostBar());
components.add(UIUtils.createSpace());
}
List<Post> response = ServerAPI.fetchTimelinePosts(lastTime, amount);
if(response == null) {
return null;
}
for(Post p : response) {
components.add(createNewsItem(p.user.get(), p));
components.add(UIUtils.createHalfSpace());
lastTime = p.date.getLong();
}
Component[] cmps = new Component[components.size()];
components.toArray(cmps);
NewsfeedContainer
We check with the server if there are more posts, if we reached the end null is returned and we return that too
9. components.add(UIUtils.createSpace());
}
List<Post> response = ServerAPI.fetchTimelinePosts(lastTime, amount);
if(response == null) {
return null;
}
for(Post p : response) {
components.add(createNewsItem(p.user.get(), p));
components.add(UIUtils.createHalfSpace());
lastTime = p.date.getLong();
}
Component[] cmps = new Component[components.size()];
components.toArray(cmps);
return cmps;
}
private Container createPostBar() {
Button avatar = new Button(ServerAPI.me().getAvatar(6.5f), "Label");
Button writePost = new Button("What's on your mind?",
"NewPostButton");
Button gallery = new Button("Photo", "GalleryButton");
FontImage.setMaterialIcon(gallery,
FontImage.MATERIAL_PHOTO_LIBRARY, 2.9f);
gallery.setTextPosition(BOTTOM);
Container c = BorderLayout.centerEastWest(writePost, gallery, avatar);
c.setUIID("HalfPaddedContainer");
NewsfeedContainer
Otherwise we loop over the responses and create a news item for each post, we add it with a space separator. Notice the usage of createNewsItem() in the code
10. components.add(UIUtils.createSpace());
}
List<Post> response = ServerAPI.fetchTimelinePosts(lastTime, amount);
if(response == null) {
return null;
}
for(Post p : response) {
components.add(createNewsItem(p.user.get(), p));
components.add(UIUtils.createHalfSpace());
lastTime = p.date.getLong();
}
Component[] cmps = new Component[components.size()];
components.toArray(cmps);
return cmps;
}
private Container createPostBar() {
Button avatar = new Button(ServerAPI.me().getAvatar(6.5f), "Label");
Button writePost = new Button("What's on your mind?",
"NewPostButton");
Button gallery = new Button("Photo", "GalleryButton");
FontImage.setMaterialIcon(gallery,
FontImage.MATERIAL_PHOTO_LIBRARY, 2.9f);
gallery.setTextPosition(BOTTOM);
Container c = BorderLayout.centerEastWest(writePost, gallery, avatar);
c.setUIID("HalfPaddedContainer");
NewsfeedContainer
We update the lastTime value to the last element so the next request continues from the last place
11. components.add(UIUtils.createSpace());
}
List<Post> response = ServerAPI.fetchTimelinePosts(lastTime, amount);
if(response == null) {
return null;
}
for(Post p : response) {
components.add(createNewsItem(p.user.get(), p));
components.add(UIUtils.createHalfSpace());
lastTime = p.date.getLong();
}
Component[] cmps = new Component[components.size()];
components.toArray(cmps);
return cmps;
}
private Container createPostBar() {
Button avatar = new Button(ServerAPI.me().getAvatar(6.5f), "Label");
Button writePost = new Button("What's on your mind?",
"NewPostButton");
Button gallery = new Button("Photo", "GalleryButton");
FontImage.setMaterialIcon(gallery,
FontImage.MATERIAL_PHOTO_LIBRARY, 2.9f);
gallery.setTextPosition(BOTTOM);
Container c = BorderLayout.centerEastWest(writePost, gallery, avatar);
c.setUIID("HalfPaddedContainer");
NewsfeedContainer
We convert the list to an array and return that data
12. Component[] cmps = new Component[components.size()];
components.toArray(cmps);
return cmps;
}
private Container createPostBar() {
Button avatar = new Button(ServerAPI.me().getAvatar(6.5f), "Label");
Button writePost = new Button("What's on your mind?",
"NewPostButton");
Button gallery = new Button("Photo", "GalleryButton");
FontImage.setMaterialIcon(gallery,
FontImage.MATERIAL_PHOTO_LIBRARY, 2.9f);
gallery.setTextPosition(BOTTOM);
Container c = BorderLayout.centerEastWest(writePost, gallery, avatar);
c.setUIID("HalfPaddedContainer");
return c;
}
private Container createNewsTitle(User u, Post p) {
Button avatar = new Button("", u.getAvatar(6.5f), "CleanButton");
Button name = new Button(u.fullName(), "PostTitle");
Button postTime = new Button(UIUtils.formatTimeAgo(p.date.get()),
"PostSubTitle");
Button menu = new Button("", "Label");
FontImage.setMaterialIcon(menu, FontImage.MATERIAL_MORE_HORIZ);
Container titleArea = BorderLayout.centerEastWest(
FlowLayout.encloseMiddle(BoxLayout.encloseY(name, postTime)),
NewsfeedContainer
We referenced createPostBar() & createNewsItem() lets look at the former first, it's a relatively simple method.
13. Component[] cmps = new Component[components.size()];
components.toArray(cmps);
return cmps;
}
private Container createPostBar() {
Button avatar = new Button(ServerAPI.me().getAvatar(6.5f), "Label");
Button writePost = new Button("What's on your mind?",
"NewPostButton");
Button gallery = new Button("Photo", "GalleryButton");
FontImage.setMaterialIcon(gallery,
FontImage.MATERIAL_PHOTO_LIBRARY, 2.9f);
gallery.setTextPosition(BOTTOM);
Container c = BorderLayout.centerEastWest(writePost, gallery, avatar);
c.setUIID("HalfPaddedContainer");
return c;
}
private Container createNewsTitle(User u, Post p) {
Button avatar = new Button("", u.getAvatar(6.5f), "CleanButton");
Button name = new Button(u.fullName(), "PostTitle");
Button postTime = new Button(UIUtils.formatTimeAgo(p.date.get()),
"PostSubTitle");
Button menu = new Button("", "Label");
FontImage.setMaterialIcon(menu, FontImage.MATERIAL_MORE_HORIZ);
Container titleArea = BorderLayout.centerEastWest(
FlowLayout.encloseMiddle(BoxLayout.encloseY(name, postTime)),
NewsfeedContainer
There are 3 buttons here none of which look like a button & each one should take us to a different Form in the finished app
14. Component[] cmps = new Component[components.size()];
components.toArray(cmps);
return cmps;
}
private Container createPostBar() {
Button avatar = new Button(ServerAPI.me().getAvatar(6.5f), "Label");
Button writePost = new Button("What's on your mind?",
"NewPostButton");
Button gallery = new Button("Photo", "GalleryButton");
FontImage.setMaterialIcon(gallery,
FontImage.MATERIAL_PHOTO_LIBRARY, 2.9f);
gallery.setTextPosition(BOTTOM);
Container c = BorderLayout.centerEastWest(writePost, gallery, avatar);
c.setUIID("HalfPaddedContainer");
return c;
}
private Container createNewsTitle(User u, Post p) {
Button avatar = new Button("", u.getAvatar(6.5f), "CleanButton");
Button name = new Button(u.fullName(), "PostTitle");
Button postTime = new Button(UIUtils.formatTimeAgo(p.date.get()),
"PostSubTitle");
Button menu = new Button("", "Label");
FontImage.setMaterialIcon(menu, FontImage.MATERIAL_MORE_HORIZ);
Container titleArea = BorderLayout.centerEastWest(
FlowLayout.encloseMiddle(BoxLayout.encloseY(name, postTime)),
NewsfeedContainer
We lay out the entire title area in a border layout, this allows the writePost field to grow and occupy the available space
15. Container c = BorderLayout.centerEastWest(writePost, gallery, avatar);
c.setUIID("HalfPaddedContainer");
return c;
}
private Container createNewsTitle(User u, Post p) {
Button avatar = new Button("", u.getAvatar(6.5f), "CleanButton");
Button name = new Button(u.fullName(), "PostTitle");
Button postTime = new Button(UIUtils.formatTimeAgo(p.date.get()),
"PostSubTitle");
Button menu = new Button("", "Label");
FontImage.setMaterialIcon(menu, FontImage.MATERIAL_MORE_HORIZ);
Container titleArea = BorderLayout.centerEastWest(
FlowLayout.encloseMiddle(BoxLayout.encloseY(name, postTime)),
FlowLayout.encloseIn(menu), avatar);
titleArea.setUIID("HalfPaddedContainer");
return titleArea;
}
private Container createPostStats(Post p) {
Container stats=new Container(new BorderLayout(), "PaddedContainer");
if(p.likes.size() > 0) {
Label thumbUp = new Label("", "SmallBlueCircle");
FontImage.setMaterialIcon(thumbUp, FontImage.MATERIAL_THUMB_UP);
Label count = new Label("" + p.likes.size(), "SmallLabel");
stats.add(WEST, BoxLayout.encloseX(thumbUp, count));
}
NewsfeedContainer
Next we have the createNewsTitle() method which is very similar in some regards
16. Container c = BorderLayout.centerEastWest(writePost, gallery, avatar);
c.setUIID("HalfPaddedContainer");
return c;
}
private Container createNewsTitle(User u, Post p) {
Button avatar = new Button("", u.getAvatar(6.5f), "CleanButton");
Button name = new Button(u.fullName(), "PostTitle");
Button postTime = new Button(UIUtils.formatTimeAgo(p.date.get()),
"PostSubTitle");
Button menu = new Button("", "Label");
FontImage.setMaterialIcon(menu, FontImage.MATERIAL_MORE_HORIZ);
Container titleArea = BorderLayout.centerEastWest(
FlowLayout.encloseMiddle(BoxLayout.encloseY(name, postTime)),
FlowLayout.encloseIn(menu), avatar);
titleArea.setUIID("HalfPaddedContainer");
return titleArea;
}
private Container createPostStats(Post p) {
Container stats=new Container(new BorderLayout(), "PaddedContainer");
if(p.likes.size() > 0) {
Label thumbUp = new Label("", "SmallBlueCircle");
FontImage.setMaterialIcon(thumbUp, FontImage.MATERIAL_THUMB_UP);
Label count = new Label("" + p.likes.size(), "SmallLabel");
stats.add(WEST, BoxLayout.encloseX(thumbUp, count));
}
NewsfeedContainer
We need to format the time as something that's more human readable such as "3 minutes ago"
17. Container c = BorderLayout.centerEastWest(writePost, gallery, avatar);
c.setUIID("HalfPaddedContainer");
return c;
}
private Container createNewsTitle(User u, Post p) {
Button avatar = new Button("", u.getAvatar(6.5f), "CleanButton");
Button name = new Button(u.fullName(), "PostTitle");
Button postTime = new Button(UIUtils.formatTimeAgo(p.date.get()),
"PostSubTitle");
Button menu = new Button("", "Label");
FontImage.setMaterialIcon(menu, FontImage.MATERIAL_MORE_HORIZ);
Container titleArea = BorderLayout.centerEastWest(
FlowLayout.encloseMiddle(BoxLayout.encloseY(name, postTime)),
FlowLayout.encloseIn(menu), avatar);
titleArea.setUIID("HalfPaddedContainer");
return titleArea;
}
private Container createPostStats(Post p) {
Container stats=new Container(new BorderLayout(), "PaddedContainer");
if(p.likes.size() > 0) {
Label thumbUp = new Label("", "SmallBlueCircle");
FontImage.setMaterialIcon(thumbUp, FontImage.MATERIAL_THUMB_UP);
Label count = new Label("" + p.likes.size(), "SmallLabel");
stats.add(WEST, BoxLayout.encloseX(thumbUp, count));
}
NewsfeedContainer
Again we place the elements in a border layout but this time we wrap them in flow layouts within so they vertically align properly. This is subtle and hard to notice in the
image. Notice that the name jots up just a little bit in the unaligned version but this can be more obvious when the font is smaller or the icon is larger. Also notice the
placement of the menu button.
18. FlowLayout.encloseIn(menu), avatar);
titleArea.setUIID("HalfPaddedContainer");
return titleArea;
}
private Container createPostStats(Post p) {
Container stats=new Container(new BorderLayout(), "PaddedContainer");
if(p.likes.size() > 0) {
Label thumbUp = new Label("", "SmallBlueCircle");
FontImage.setMaterialIcon(thumbUp, FontImage.MATERIAL_THUMB_UP);
Label count = new Label("" + p.likes.size(), "SmallLabel");
stats.add(WEST, BoxLayout.encloseX(thumbUp, count));
}
if(p.comments.size() > 0) {
stats.add(EAST,new Label(p.comments.size() +
" comments","SmallLabel"));
}
return stats;
}
private Container createNewsItem(User u, Post p) {
Container titleArea = createNewsTitle(u, p);
Component body;
if(p.content.get().indexOf('<') > -1) {
body = new RichTextView(p.content.get());
} else {
body = new SpanLabel(p.content.get());
}
NewsfeedContainer
Next up is createPostStats it's again a very simple method. I broke it out just to keep the code size smaller so we can review the blocks more easily.
19. FlowLayout.encloseIn(menu), avatar);
titleArea.setUIID("HalfPaddedContainer");
return titleArea;
}
private Container createPostStats(Post p) {
Container stats=new Container(new BorderLayout(), "PaddedContainer");
if(p.likes.size() > 0) {
Label thumbUp = new Label("", "SmallBlueCircle");
FontImage.setMaterialIcon(thumbUp, FontImage.MATERIAL_THUMB_UP);
Label count = new Label("" + p.likes.size(), "SmallLabel");
stats.add(WEST, BoxLayout.encloseX(thumbUp, count));
}
if(p.comments.size() > 0) {
stats.add(EAST,new Label(p.comments.size() +
" comments","SmallLabel"));
}
return stats;
}
private Container createNewsItem(User u, Post p) {
Container titleArea = createNewsTitle(u, p);
Component body;
if(p.content.get().indexOf('<') > -1) {
body = new RichTextView(p.content.get());
} else {
body = new SpanLabel(p.content.get());
}
NewsfeedContainer
The stats bar appears above the like button. It's only there if there are likes or comments otherwise it shouldn't show.
20. FlowLayout.encloseIn(menu), avatar);
titleArea.setUIID("HalfPaddedContainer");
return titleArea;
}
private Container createPostStats(Post p) {
Container stats=new Container(new BorderLayout(), "PaddedContainer");
if(p.likes.size() > 0) {
Label thumbUp = new Label("", "SmallBlueCircle");
FontImage.setMaterialIcon(thumbUp, FontImage.MATERIAL_THUMB_UP);
Label count = new Label("" + p.likes.size(), "SmallLabel");
stats.add(WEST, BoxLayout.encloseX(thumbUp, count));
}
if(p.comments.size() > 0) {
stats.add(EAST,new Label(p.comments.size() +
" comments","SmallLabel"));
}
return stats;
}
private Container createNewsItem(User u, Post p) {
Container titleArea = createNewsTitle(u, p);
Component body;
if(p.content.get().indexOf('<') > -1) {
body = new RichTextView(p.content.get());
} else {
body = new SpanLabel(p.content.get());
}
NewsfeedContainer
I could have made this code better so it will write "1 comment" and "2 comments" etc. but I wanted to keep the code simple
21. " comments","SmallLabel"));
}
return stats;
}
private Container createNewsItem(User u, Post p) {
Container titleArea = createNewsTitle(u, p);
Component body;
if(p.content.get().indexOf('<') > -1) {
body = new RichTextView(p.content.get());
} else {
body = new SpanLabel(p.content.get());
}
body.setUIID("HalfPaddedContainer");
Button like = new Button("Like", "CleanButton");
Button comment = new Button("Comment", "CleanButton");
Button share = new Button("Share", "CleanButton");
FontImage.setMaterialIcon(like, FontImage.MATERIAL_THUMB_UP);
FontImage.setMaterialIcon(comment, FontImage.MATERIAL_COMMENT);
FontImage.setMaterialIcon(share, FontImage.MATERIAL_SHARE);
Container buttonBar = GridLayout.encloseIn(3, like, comment, share);
buttonBar.setUIID("HalfPaddedContainer");
return BoxLayout.encloseY(titleArea, body,
createPostStats(p), buttonBar);
}
}
NewsfeedContainer
With that we are ready for the final method in this class createNewsItem
22. " comments","SmallLabel"));
}
return stats;
}
private Container createNewsItem(User u, Post p) {
Container titleArea = createNewsTitle(u, p);
Component body;
if(p.content.get().indexOf('<') > -1) {
body = new RichTextView(p.content.get());
} else {
body = new SpanLabel(p.content.get());
}
body.setUIID("HalfPaddedContainer");
Button like = new Button("Like", "CleanButton");
Button comment = new Button("Comment", "CleanButton");
Button share = new Button("Share", "CleanButton");
FontImage.setMaterialIcon(like, FontImage.MATERIAL_THUMB_UP);
FontImage.setMaterialIcon(comment, FontImage.MATERIAL_COMMENT);
FontImage.setMaterialIcon(share, FontImage.MATERIAL_SHARE);
Container buttonBar = GridLayout.encloseIn(3, like, comment, share);
buttonBar.setUIID("HalfPaddedContainer");
return BoxLayout.encloseY(titleArea, body,
createPostStats(p), buttonBar);
}
}
NewsfeedContainer
This method assembles the post entry from the pieces we already built, the title entry. The rich text view or span label etc.
23. " comments","SmallLabel"));
}
return stats;
}
private Container createNewsItem(User u, Post p) {
Container titleArea = createNewsTitle(u, p);
Component body;
if(p.content.get().indexOf('<') > -1) {
body = new RichTextView(p.content.get());
} else {
body = new SpanLabel(p.content.get());
}
body.setUIID("HalfPaddedContainer");
Button like = new Button("Like", "CleanButton");
Button comment = new Button("Comment", "CleanButton");
Button share = new Button("Share", "CleanButton");
FontImage.setMaterialIcon(like, FontImage.MATERIAL_THUMB_UP);
FontImage.setMaterialIcon(comment, FontImage.MATERIAL_COMMENT);
FontImage.setMaterialIcon(share, FontImage.MATERIAL_SHARE);
Container buttonBar = GridLayout.encloseIn(3, like, comment, share);
buttonBar.setUIID("HalfPaddedContainer");
return BoxLayout.encloseY(titleArea, body,
createPostStats(p), buttonBar);
}
}
NewsfeedContainer
The three like/comment/share buttons are packaged in a grid so they will have the same size and align properly
24. " comments","SmallLabel"));
}
return stats;
}
private Container createNewsItem(User u, Post p) {
Container titleArea = createNewsTitle(u, p);
Component body;
if(p.content.get().indexOf('<') > -1) {
body = new RichTextView(p.content.get());
} else {
body = new SpanLabel(p.content.get());
}
body.setUIID("HalfPaddedContainer");
Button like = new Button("Like", "CleanButton");
Button comment = new Button("Comment", "CleanButton");
Button share = new Button("Share", "CleanButton");
FontImage.setMaterialIcon(like, FontImage.MATERIAL_THUMB_UP);
FontImage.setMaterialIcon(comment, FontImage.MATERIAL_COMMENT);
FontImage.setMaterialIcon(share, FontImage.MATERIAL_SHARE);
Container buttonBar = GridLayout.encloseIn(3, like, comment, share);
buttonBar.setUIID("HalfPaddedContainer");
return BoxLayout.encloseY(titleArea, body,
createPostStats(p), buttonBar);
}
}
NewsfeedContainer
Everything else is packaged together on a Y axis Container with good padding
26. NewPostButton {
border: 1px #cccccc cn1-pill-border;
background-color: white;
padding: 1mm 2mm 1mm 2mm;
margin: 1mm;
color: black;
font-family: "native:MainLight";
font-size: 2.6mm;
}
GalleryButton {
color: #4B4F56;
font-family: "native:MainLight";
font-size: 1.5mm;
text-align: center;
padding: 0px 2mm 0px 2mm;
margin: 0px;
}
HalfPaddedContainer {
padding: 1.5mm;
margin: 0mm;
background: transparent;
}
theme.css
The button looks like a text field, when we press it we go directly to the post editing form
27. NewPostButton {
border: 1px #cccccc cn1-pill-border;
background-color: white;
padding: 1mm 2mm 1mm 2mm;
margin: 1mm;
color: black;
font-family: "native:MainLight";
font-size: 2.6mm;
}
GalleryButton {
color: #4B4F56;
font-family: "native:MainLight";
font-size: 1.5mm;
text-align: center;
padding: 0px 2mm 0px 2mm;
margin: 0px;
}
HalfPaddedContainer {
padding: 1.5mm;
margin: 0mm;
background: transparent;
}
theme.css
The gallery button has small font and padding so it can fit in the same row as the other elements
28. color: #4B4F56;
font-family: "native:MainLight";
font-size: 1.5mm;
text-align: center;
padding: 0px 2mm 0px 2mm;
margin: 0px;
}
HalfPaddedContainer {
padding: 1.5mm;
margin: 0mm;
background: transparent;
}
CleanButton {
cn1-derive: BaseButton;
font-family: "native:MainLight";
font-size: 2.5mm;
margin: 0px;
color: #4B4F56;
}
PostTitle {
font-family: "native:MainRegular";
font-size: 3.5mm;
}
PostSubTitle {
font-family: "native:MainRegular";
theme.css
The PaddedContainer UIID is often too heavily padded for some UI elements, this uses 1.5mm instead of 3mm in the standard padding
29. color: #4B4F56;
font-family: "native:MainLight";
font-size: 1.5mm;
text-align: center;
padding: 0px 2mm 0px 2mm;
margin: 0px;
}
HalfPaddedContainer {
padding: 1.5mm;
margin: 0mm;
background: transparent;
}
CleanButton {
cn1-derive: BaseButton;
font-family: "native:MainLight";
font-size: 2.5mm;
margin: 0px;
color: #4B4F56;
}
PostTitle {
font-family: "native:MainRegular";
font-size: 3.5mm;
}
PostSubTitle {
font-family: "native:MainRegular";
theme.css
We'll use this in several places as we go on, here it doesn't matter as much as it mostly shows an icon
30. cn1-derive: BaseButton;
font-family: "native:MainLight";
font-size: 2.5mm;
margin: 0px;
color: #4B4F56;
}
PostTitle {
font-family: "native:MainRegular";
font-size: 3.5mm;
}
PostSubTitle {
font-family: "native:MainRegular";
font-size: 2mm;
color: #aaaaaa;
}
SmallBlueCircle {
border: cn1-round-border;
background-color: blue;
padding: 0.5mm;
margin: 0px 2mm 0px 1mm;
color: white;
font-family: "native:MainLight";
font-size: 2mm;
}
SmallLabel {
theme.css
The title and subtitle use regular font which makes them standout next to the light font used in the rest of the app
31. color: #4B4F56;
}
PostTitle {
font-family: "native:MainRegular";
font-size: 3.5mm;
}
PostSubTitle {
font-family: "native:MainRegular";
font-size: 2mm;
color: #aaaaaa;
}
SmallBlueCircle {
border: cn1-round-border;
background-color: blue;
padding: 0.5mm;
margin: 0px 2mm 0px 1mm;
color: white;
font-family: "native:MainLight";
font-size: 2mm;
}
SmallLabel {
font-family: "native:MainLight";
font-size: 2mm;
}
theme.css
This is literally a round blue circle with enough padding to show the thumb within the circle
32. color: #4B4F56;
}
PostTitle {
font-family: "native:MainRegular";
font-size: 3.5mm;
}
PostSubTitle {
font-family: "native:MainRegular";
font-size: 2mm;
color: #aaaaaa;
}
SmallBlueCircle {
border: cn1-round-border;
background-color: blue;
padding: 0.5mm;
margin: 0px 2mm 0px 1mm;
color: white;
font-family: "native:MainLight";
font-size: 2mm;
}
SmallLabel {
font-family: "native:MainLight";
font-size: 2mm;
}
theme.css
I just need a label with a font small enough to fit. That's all the CSS entries we need so we can lean back, press play in the IDE and watch the first form element in the
application come to life!