Created
June 24, 2021 13:47
-
-
Save shannah/3df2ea9184fd2f2f8ab80e219c73b5c0 to your computer and use it in GitHub Desktop.
TwitterClone state after adding the Signup Page
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<border view-controller="com.example.tweetapp.controllers.SignupPageViewController" | |
uiid="SignupPage" | |
safeArea="true" | |
xsi:noNamespaceSchemaLocation="SignupPage.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |
<define-category name="NEXT"/> | |
<define-category name="USE_PHONE"/> | |
<define-category name="USE_EMAIL"/> | |
<define-category name="ENTER_PHONE_OR_EMAIL"/> | |
<define-tag name="name" value="Person.name"/> | |
<define-tag name="phone" value="Person.telephone"/> | |
<define-tag name="email" value="Person.email"/> | |
<define-tag name="birthDate" value="Person.birthDate" type="java.util.Date"/> | |
<define-tag name="useEmail" type="boolean"/> | |
<define-tag name="editingPhoneOrEmail" type="boolean"/> | |
<define-tag name="phoneFieldFocused" type="boolean"/> | |
<define-tag name="emailFieldFocused" type="boolean"/> | |
<!-- Properties for error messages --> | |
<define-tag name="nameErrorMessage"/> | |
<define-tag name="phoneOrEmailErrorMessage"/> | |
<define-tag name="birthDateErrorMessage"/> | |
<title> | |
<label iconUIID="TwitterIcon" fontIcon="(char)0xe902" ></label> | |
</title> | |
<y layout-constraint="center" uiid="SignupPageContent" scrollableY="true"> | |
<label uiid="SignupPageTitle">Create your account</label> | |
<radTextField | |
tag="name" | |
component.hint="Name" | |
component.uiid="TwitterTextField" | |
component.hintLabel.uiid="TwitterTextFieldHint" | |
/> | |
<radLabel tag="nameErrorMessage" | |
bind-hidden="${nameErrorMessage}.isEmpty()" | |
rad-transition="hidden 0.3s" | |
component.uiid="FieldErrorMessage" | |
/> | |
<button uiid="PhoneOrEmailButton" | |
text="Phone number or email address" | |
bind-hidden="${editingPhoneOrEmail}.bool" | |
> | |
<script> | |
it.addActionListener(evt -> { | |
evt.consume(); | |
it.getComponentForm().setFormBottomPaddingEditingMode(true); | |
${editingPhoneOrEmail}.setBoolean(true); | |
if (${useEmail}.bool) { | |
emailTextField.getComponent().startEditingAsync(); | |
} else { | |
phoneTextField.getComponent().startEditingAsync(); | |
} | |
}); | |
</script> | |
</button> | |
<radTextField | |
rad-var="phoneTextField" | |
tag="phone" | |
bind-component.focus="phoneFieldFocused" | |
bind-hidden="${useEmail}.bool || !${editingPhoneOrEmail}.bool" | |
component.hint="Phone number" | |
component.uiid="TwitterTextField" | |
component.hintLabel.uiid="TwitterTextFieldHint" | |
component.constraint="TextArea.PHONENUMBER" | |
/> | |
<radTextField | |
rad-var="emailTextField" | |
bind-hidden="!${useEmail}.bool || !${editingPhoneOrEmail}.bool" | |
tag="email" | |
component.hint="Email address" | |
component.uiid="TwitterTextField" | |
component.hintLabel.uiid="TwitterTextFieldHint" | |
component.constraint="TextArea.EMAILADDR" | |
bind-component.focus="emailFieldFocused" | |
> | |
</radTextField> | |
<radLabel tag="phoneOrEmailErrorMessage" | |
bind-hidden="${phoneOrEmailErrorMessage}.isEmpty()" | |
rad-transition="hidden 0.3s" | |
component.uiid="FieldErrorMessage" | |
/> | |
<radDatePicker | |
tag="birthDate" | |
component.text="Date of birth" | |
component.uiid="TwitterDatePicker" | |
/> | |
<radLabel tag="birthDateErrorMessage" | |
bind-hidden="${birthDateErrorMessage}.isEmpty()" | |
rad-transition="hidden 0.3s" | |
component.uiid="FieldErrorMessage" | |
/> | |
</y> | |
<border layout-constraint="south" uiid="SignupPageSouth"> | |
<x layout-constraint="west"> | |
<button text="Use Email Address" | |
bind-hidden="!${phoneFieldFocused}.bool" | |
uiid="TextFieldToggleButton" | |
> | |
<script> | |
it.addActionListener(evt->{ | |
${useEmail}.setBoolean(true); | |
emailTextField.startEditingAsync(); | |
}); | |
</script> | |
</button> | |
<button text="Use Phone" | |
bind-hidden="!${emailFieldFocused}.bool" | |
uiid="TextFieldToggleButton" | |
> | |
<script> | |
it.addActionListener(evt->{ | |
${useEmail}.setBoolean(false); | |
phoneTextField.startEditingAsync(); | |
}); | |
</script> | |
</button> | |
</x> | |
<x layout-constraint="east"> | |
<button uiid="TwitterNextButton" text="Next"> | |
<bind-action category="NEXT"/> | |
</button> | |
</x> | |
</border> | |
</border> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.tweetapp.controllers; | |
import com.codename1.components.InfiniteProgress; | |
import com.codename1.components.ToastBar; | |
import com.codename1.rad.controllers.Controller; | |
import com.codename1.rad.controllers.ViewController; | |
import com.codename1.rad.nodes.ActionNode; | |
import com.codename1.rad.util.NonNull; | |
import com.codename1.ui.Dialog; | |
import com.example.tweetapp.services.TweetAppClient; | |
import com.example.tweetapp.views.SignupPage; | |
import com.example.tweetapp.views.SignupPageModel; | |
import com.example.tweetapp.views.SignupPageModelWrapper; | |
import com.example.tweetapp.views.HomePageController; | |
public class SignupPageViewController extends ViewController { | |
/** | |
* Creates a new ViewController with the given parent controller. | |
* | |
* @param parent | |
*/ | |
public SignupPageViewController(Controller parent) { | |
super(parent); | |
} | |
@Override | |
protected void initControllerActions() { | |
super.initControllerActions(); | |
ActionNode.builder() | |
.addToController(this, SignupPage.NEXT, this::handleSubmit); | |
} | |
/** | |
* Handles the registration form submission | |
* @param evt | |
*/ | |
private void handleSubmit(ActionNode.ActionNodeEvent evt) { | |
// Get reference to the view's model via the event. | |
SignupPageModel viewModel = SignupPageModelWrapper.wrap(evt.getEntity()); | |
// Do some validation | |
boolean failedValidation = false; | |
if (viewModel.isUseEmail() && NonNull.empty(viewModel.getEmail())) { | |
viewModel.setPhoneOrEmailErrorMessage("Email address cannot be empty"); | |
failedValidation = true; | |
} else if (!viewModel.isUseEmail() && NonNull.empty(viewModel.getPhone())) { | |
viewModel.setPhoneOrEmailErrorMessage("Phone cannot be empty"); | |
failedValidation = true; | |
} else { | |
viewModel.setPhoneOrEmailErrorMessage(""); | |
} | |
if (NonNull.empty(viewModel.getName())) { | |
viewModel.setNameErrorMessage("Name cannot be empty"); | |
failedValidation = true; | |
} else { | |
viewModel.setNameErrorMessage(""); | |
} | |
if (NonNull.empty(viewModel.getBirthDate())) { | |
viewModel.setBirthDateErrorMessage("Birthdate cannot be empty"); | |
failedValidation = true; | |
} else { | |
viewModel.setBirthDateErrorMessage(""); | |
} | |
if (failedValidation) { | |
return; | |
} | |
// Get reference to the webservice client | |
TweetAppClient client = lookup(TweetAppClient.class); | |
TweetAppClient.SignupRequest request = client.createSignupRequest() | |
.name(viewModel.getName()) | |
.birthDate(viewModel.getBirthDate()); | |
if (viewModel.isUseEmail()) { | |
request.email(viewModel.getEmail()); | |
} else { | |
request.phone(viewModel.getPhone()); | |
} | |
InfiniteProgress progess = new InfiniteProgress(); | |
Dialog progressDialog = progess.showInfiniteBlocking(); | |
request.signup().onResult((res, err) -> { | |
progressDialog.dispose(); | |
if (err != null) { | |
ToastBar.showErrorMessage(err.getMessage()); | |
return; | |
} | |
new HomePageController(getApplicationController()).show(); | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Constants { | |
includeNativeBool: true; | |
defaultFontSizeInt:'18'; | |
} | |
/* Global Overrides */ | |
TitleArea { | |
border:none; | |
background-color:white; | |
margin:0; | |
} | |
@font-face { | |
font-family: 'icomoon'; | |
src: url('fonts/icomoon.ttf'); | |
} | |
WelcomePage { | |
padding: 10vw; | |
background-color: white; | |
} | |
TwitterButton { | |
cn1-derive: Button; | |
background-color: #1DA1F2; | |
color: white; | |
border: cn1-pill-border; | |
padding: 0.7rem; | |
font-size:1rem; | |
} | |
TwitterHeading1 { | |
font-size: 1.5rem; | |
font-family: 'native:MainBold'; | |
color: black; | |
margin-bottom: 1rem; | |
} | |
TwitterSmallLabel { | |
cn1-derive: Label; | |
font-size: 0.7rem; | |
font-family: 'native:MainRegular'; | |
padding:0; | |
margin:0; | |
color: #66757f; | |
margin-right: 1mm; | |
} | |
TwitterSmallLink { | |
cn1-derive: Button; | |
font-size: 0.7rem; | |
font-family: 'native:MainRegular'; | |
padding:0; | |
margin:0; | |
color: #1DA1F2; | |
} | |
TwitterIcon { | |
font-family: icomoon; | |
font-size: 1.4rem; | |
color: #1DA1F2; | |
} | |
/** Signup Page Styles */ | |
SignupPage { | |
background-color:white; | |
margin:0; | |
} | |
SignupPageContent { | |
padding: 8vw; | |
} | |
SignupPageSouth { | |
padding:2mm; | |
padding-left: 8vw; | |
padding-right: 8vw; | |
margin:0; | |
border-top: 1px solid gray; | |
} | |
SignupPageTitle { | |
cn1-derive: Label; | |
font-size: 1.2rem; | |
font-family: "native:MainBold"; | |
text-align:center; | |
margin-bottom: 1.7rem; | |
color: black; | |
} | |
TwitterNextButton { | |
cn1-derive: Button; | |
background-color: #1DA1F2; | |
color: white; | |
border: cn1-pill-border; | |
padding: 0.5rem 0.75rem; | |
font-size: 0.7rem; | |
margin-right: 0; | |
} | |
TwitterTextField, TwitterTextFieldHint { | |
padding-top: 0.7rem; | |
padding-bottom: 0.7rem; | |
font-size: 0.8rem; | |
font-family: "native:MainLight"; | |
color: gray; | |
} | |
TwitterTextField { | |
cn1-derive: TextField; | |
border: none; | |
border-bottom: 0.8pt solid #ccc; | |
color: #333333; | |
margin-top: 1rem; | |
margin-bottom: 0.5mm; | |
} | |
TwitterDatePicker { | |
cn1-derive: TwitterTextField; | |
color: gray; | |
} | |
PhoneOrEmailButton { | |
cn1-derive: TwitterTextField; | |
color: gray; | |
} | |
TwitterTextFieldHint { | |
color: #66757f; | |
} | |
TextFieldToggleButton { | |
cn1-derive: Button; | |
color: #1DA1F2; | |
border: none; | |
padding: 0.5rem 0.75rem; | |
font-size: 0.7rem; | |
margin:0; | |
} | |
FieldErrorMessage { | |
cn1-derive: Label; | |
font-size: 0.7rem; | |
color: white; | |
background-color:red; | |
padding: 1.5mm; | |
margin-top: 0; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.tweetapp; | |
import static com.codename1.rad.util.NonNull.with; | |
import static com.codename1.ui.CN.*; | |
import com.codename1.rad.controllers.ControllerEvent; | |
import com.codename1.rad.nodes.ActionNode; | |
import com.codename1.rad.ui.ActionStyle; | |
import com.codename1.ui.*; | |
import com.codename1.ui.events.ActionEvent; | |
import com.codename1.ui.layouts.*; | |
import com.codename1.io.*; | |
import com.codename1.ui.plaf.*; | |
import com.codename1.ui.util.Resources; | |
import com.codename1.rad.controllers.ApplicationController; | |
import com.example.tweetapp.services.TweetAppClient; | |
import com.example.tweetapp.views.WelcomePageController; | |
/** | |
* This file was generated by <a href="https://www.codenameone.com/">Codename One</a> for the purpose | |
* of building native mobile applications using Java. | |
*/ | |
public class Tweetapp extends ApplicationController { | |
@Override | |
protected void initControllerActions() { | |
super.initControllerActions(); | |
} | |
@Override | |
protected void onStartController() { | |
super.onStartController(); | |
/** | |
* Add a TweetAppClient as a lookup so that it will be available throughout | |
* the app via {@link #lookup(Class)} | |
*/ | |
addLookup(new TweetAppClient()); | |
} | |
public void actionPerformed(ControllerEvent evt) { | |
with(evt, StartEvent.class, startEvent -> { | |
if (!startEvent.isShowingForm()) { | |
startEvent.setShowingForm(true); | |
new WelcomePageController(this).show(); | |
} | |
}); | |
super.actionPerformed(evt); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.tweetapp.services; | |
import com.codename1.rad.util.NonNull; | |
import com.codename1.util.AsyncResource; | |
import java.util.Date; | |
/** | |
* A client for interacting with the server. | |
*/ | |
public class TweetAppClient { | |
/** | |
* Flag to indicate that we are currently logged in. | |
*/ | |
private boolean loggedIn; | |
/** | |
* The currently logged in user Id. In this mock implementation the user Id | |
* is just the email address or phone number. | |
*/ | |
private String loggedInUserId; | |
public boolean isLoggedIn(){ | |
return loggedIn; | |
} | |
public String getLoggedInUserId() { | |
return loggedInUserId; | |
} | |
/** | |
* A response object that is passed to the SignupRequest callback | |
* upon completion. | |
*/ | |
public static class SignupResponse { | |
/** | |
* Whether the signup was successful | |
*/ | |
private boolean success; | |
/** | |
* Reference to request that this response is for. | |
*/ | |
private SignupRequest request; | |
/** | |
* The response code. 200 for success. | |
* Make up error codes to fit needs. | |
*/ | |
private int responseCode; | |
/** | |
* A message related to the response code. Contains error message | |
* in case of errors. | |
*/ | |
private String message; | |
public boolean isSuccess() { | |
return success; | |
} | |
public SignupRequest getRequest() { | |
return request; | |
} | |
public int getResponseCode() { | |
return responseCode; | |
} | |
public String getMessage() { | |
return message; | |
} | |
} | |
/** | |
* Encapsulates a signup request to send to the server. Modify this | |
* class to include the information you require in your signup process. | |
* | |
*/ | |
public class SignupRequest extends AsyncResource<SignupResponse> { | |
/** | |
* The email address of the user. | |
*/ | |
private String email, | |
/** | |
* The phone number of the user. | |
*/ | |
phone, | |
/** | |
* The name of the user. | |
*/ | |
name; | |
/** | |
* The birth date of the user. | |
*/ | |
private Date birthDate; | |
/** | |
* Send the signup request. | |
* @return | |
*/ | |
public SignupRequest signup() { | |
return TweetAppClient.this.signup(this); | |
} | |
public SignupRequest email(String email) { | |
this.email = email; | |
return this; | |
} | |
public SignupRequest phone(String phone) { | |
this.phone = phone; | |
return this; | |
} | |
public SignupRequest birthDate(Date birthDate) { | |
this.birthDate = birthDate; | |
return this; | |
} | |
public SignupRequest name(String name) { | |
this.name = name; | |
return this; | |
} | |
} | |
/** | |
* Creates a new signup request. | |
* @return | |
*/ | |
public SignupRequest createSignupRequest() { | |
return new SignupRequest(); | |
} | |
/** | |
* Sends a signup request to the server. | |
* @param request | |
* @return | |
*/ | |
private SignupRequest signup(SignupRequest request) { | |
// This is just mocking the signup process. | |
// Change this to contact the server and sign up. | |
SignupResponse response = new SignupResponse(); | |
response.responseCode = 200; | |
response.message = "Success"; | |
response.request = request; | |
response.success = true; | |
request.complete(response); | |
// To log in we set the loggedInUserId and loggedIn | |
// boolean flag. | |
loggedInUserId = NonNull.nonNull(request.email, request.phone); | |
loggedIn = true; | |
return request; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<borderAbsolute | |
safeArea="true" | |
uiid="WelcomePage" | |
xsi:noNamespaceSchemaLocation="WelcomePage.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |
<title hidden="true"/> | |
<center layout-constraint="north"> | |
<label iconUIID="TwitterIcon" fontIcon="(char)0xe902" ></label> | |
</center> | |
<y layout-constraint="center" uiid="TwitterContentPane"> | |
<spanLabel textUIID="TwitterHeading1">See what's happening in the world right now.</spanLabel> | |
<button uiid="TwitterButton" rad-href="#SignupPage">Create account</button> | |
</y> | |
<flow layout-constraint="south"> | |
<label uiid="TwitterSmallLabel">Have an account already?</label> | |
<button uiid="TwitterSmallLink">Log in</button> | |
</flow> | |
</borderAbsolute> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment