Best E-Scooter Apps – Features And Cost To Develop An App

Numerous advancements and improvements have changed the worldwide economy in this day and age. There has been a worldwide pattern for a considerable length of time patterns like Mobile App Development, automated reasoning, IoT, or digital money. This bike-sharing assistance has additionally spoken to the worldwide local area.

Riding an e-bike gives a better and more reasonable method for moving around than pushing a cruiser. They have been presented as electric bikes (e-bikes). Additionally, the greatest advantage is that they are standing out enough to be noticed and prevalent. When in the commercial center, partners have upheld the ride mode to incorporate transportation choices for the whole metropolitan populace.



What is e-Scooter Sharing?

Shared versatility has been filling in noticeable quality throughout recent years. These android app development companies in Gurgaon have fast term rentals for bikes. While e-Scooter Sharing Mobile App Development is equivalent to vehicle and bicycle sharing, they are more affordable and are appropriate for more limited excursions.

Like different types of shared transportation, bike and bicycle sharing tackle different issues like stopping and mileage.

Sharing bikes for the last mile is a helpful option also. The main mile relates to how much time from the beginning of an excursion is like a transport terminal. The last stretch is the hole between the transport terminal and the objective. Suburbanites can seek after less expensive methods of transportation to get to work.



Features Of An E-e-Scooter Sharing Apps

How about we have a more critical gander at the rundown of fundamental elements that you should have in your electric bike application:

Enrollment and on-boarding
After enrolling yourself in the Mobile App Development, be it Android or iPhone app development services, enlisted clients can flawlessly utilize the application. This highlight execution in your electric bike assists with discovering its working.

Map joining
Maps joining empowers clients to search for the accessibility of e-bikes and electric bicycles in adjacent spots. This astonishing component allows clients to track down the most straightforward and briefest course to arrive at their objective.

QR Code Scanner
QR code scanner is one of the extraordinary highlights to execute in your e-bike application for your client’s comfort. Utilizing QR code scanners clients can begin and end their excursion most securely. Clients need to examine the QR code to open or lock the electric bike. Lime involves scanner SDKs for iOS and Android stages.

Payment System
An underlying payment framework empowers clients to pay for e-bikes safely. You can coordinate any payment modes like Stripe, PayPal, Braintree, and so forth.

GPS Tracking System
The continuous following allows clients to find electric bikes. It empowers the administrator to follow bikes and gather those which require upkeep.

Smart Locks
To open bikes using QR codes, add an IoT-empowered locking framework. The bikes should be coordinated with miniature regulators.

Ride History
This component empowers clients to follow rides. Ride details are expected to quantify the proficiency of client rides.

Booking
To book an electric bike, coordinating a booking framework empowers clients. You can likewise book an e-Scooter Sharing application for your family, companions, family members, and so forth.

Social Media Integration
A combination of social media accounts is perhaps the most effective way to draw in your clients and the clients’ base. This element empowers clients to share the subtleties and feelings of their rides.

Push Notifications
Message pop-ups are extremely useful for the accomplishment of any application. Adding pop-up messages feature in your application, you can send warnings to your application clients about limits, offers and exceptional occasions, and so on, and it likewise facilitates correspondence.

Cost Of Developing a Scooter Sharing App?

Thus, we are at the most anticipated segment of our article – the expense of e-Scooter Sharing application advancement. As per the several Android app development companies in Gurgaon, the expense of fostering an e-Scooter Sharing application likewise relies upon numerous pivotal elements. To give some examples, we have:

  • Project Management Cost
  • UI/UX Cost
  • Advancement Cost
  • Intricacy and Size of Project
  • Upgradation and Post-Sales Services

Aside from every one of those referenced above, there are a lot more factors that straightforwardly or by implication influence the general expense of e-Scooter Sharing application advancement. To find out about your undertaking, you can always visit our group.

Conclusion
Since you are familiar with the best electric bike applications that are doing amazingly well on the lookout, the elements you want to coordinate into your application, how to adapt your application, and its development cost, you can likewise start with developing your bike application.

Along these lines, if you have any concerns about fostering your own electric e-Scooter Sharing startup, then, we suggest you Hire Mobile App Developer now. Our group dominates in creating applications like Bird or Lime. We guarantee to create your creative mind in the real world.

Summary:
There is a lot of demand for scooter sharing business growth due to the low startup costs and the rise in compact and quicker modes of transportation. One should work to build an e-scooter software that functions like Bird or Lime. Check out the latest and must-have features with the cost of developing an e-scooter sharing application.


Source link

Getting Telescope's React Native App

Hello again! It’s me, Luigi again and today I am going to talk about the vision of Telescope getting a React Native App. This is a very big subject so I am going to go over as much as I can during this blog post. Things I am going to discuss are:

  • What is React Native?
  • React vs React Native?
  • What CLI we should use for our development?
  • Possible Telescope Goals
  • How can you get started to help?



What is React Native?



React Native?

React Native is a framework that allows programmers to write JavaScript code to build mobile applications. Some of the devices that React Native can build for currently is IOS, Android and Windows(Still new and buggy).



React vs React Native

React is a library in JavaScript that is used for building front-end web applications. React Native uses the React library to build the front-end for the application.



What React Native CLI Should we use for our Development?

React Native Expo



Expo CLI vs React Native CLI

When using React Native and starting a project you have the choice between two CLIs(Command Line Interfaces). You can choose between React Native’s or Expo’s. Both are awesome tools to build with but, each have their pros and cons.



Expo CLI

Pros:

  • Fast development setup
  • Quickest way to start development with React Native
  • Live reload in Development
  • Library linking
  • Can test app on apple/android devices (Expo builds apps)
  • Can eject/convert back into a React Native CLI

Cons:

  • Builds are done by Expo
  • Native modules are not supported
  • Expo apps are bigger because all libraries are included



React Native CLI

Pros:

  • Builds are done locally
  • Native modules are supported
  • You have more control over app size

Cons:

  • Slow development setup
  • No live reload in Development
  • No library linking (things need to be linked with react-native link)
  • Can’t turn into an expo app



Why I Recommend Expo as our Starting Point?

As someone who has worked with both, I think we should start development with Expo because it is easier/faster to setup for development, easier to develop in and can always be converted back into React Native CLI. This will encourage open source developers to learn and contribute because of how much easier it is to get involved with the project. Although React Native CLI provides native module support and control of the app size, I do not believe that those things are worth the frustration of working with the React Native CLI. If there are more pros or cons you know, please leave a comment in the description.



Telescope

Target that is red



Starting Point

I think the first goal we should have for functionality of the app is to have blog posts with basic user information display correctly. Although it sounds easy we are designing/developing/testing a new app that requires a lot of configuration, learning and fixing. A more detailed goal list would be:

  • Splash Screen
  • App Icon
  • Published on app store
  • Get time line of blogs to display with user information correctly
  • Basic navigation setup

Once we hit that goal we can add user authentication and eventually slowly layer more features onto the app and create better work flows with the power of Expo! If you have any ideas to add for goals please comment below!



How can you get started to help?

Community

Well now you’re wondering “How can I get involved?”. Well to start, you should review documentation and practice using Expo so when we start development you’re ready! The Expo Documentation is an amazing source for learning how to get started with react native! They teach you everything from installing react native to learning work flows. Once you feel a little comfortable you should make a small prototype! I feel like when I learn a new framework, I try to create a small project to help me understand how to practically use the tool. Some ideas are a TODO app, Book app that displays book information, News app and really anything that inspires you!


Source link

Anayo Debugging 1: java.lang.NoClassDefFoundError: <clinit> failed for class com.facebook.flipper.android.EventBase



Bug

Generating an Android build package(APK)from Android Studio builds successfully. But running the generated APK on a real device or device connected to Android Studio Crashes on launch and returns the following errors.

getWifiLinkLayerStats_1_3_Internal(l.973) failed .code = ERROR_NOT_SUPPORTED, .description = 

/? E/studio.deploy: Could not get package user id: run-as: unknown package: com....

/? E/studio.deploy: Could not find apks for this package: com....

/? E/Finsky: [2] VerifyPerSourceInstallationConsentInstallTask.d(2): Package name null is not an installed package

/? E/installd: Couldn't opendir /data/app/vmdl1184715882.tmp: No such file or directory

/? E/installd: Failed to delete /data/app/vmdl1184715882.tmp: No such file or directory

/? E/ssioncontrolle: Not starting debugger since process cannot load the jdwp agent.

java.lang.NoClassDefFoundError: <clinit> failed for class com.facebook.flipper.android.EventBase; see exception in other thread

I read through all, trying to understand each of them. But what stood out from these errors, and that has some sort of clarity is the last one:

java.lang.NoClassDefFoundError: <clinit> failed for class com.facebook.flipper.android.EventBase; see exception in other thread

I was a bit skeptical, because it’s getting really difficult to justify Flipper, a debug tool shouldn’t crash and block the development process.



How I solved it

After several trial and error, I was able to arrive at a solution that worked. I had to re-think, this particular error happens when after I try running the generated APK and not when I was generating a build. And I looked at how the Android build process works, the compiler converts the source code into DEX(whatever the name is) files, which include byte code that runs on android devices. So this would mean that while compiling, there was possibly a mix of old and new source code(which is possible since there is no such thing as a perfect compiler), or if there isn’t no issue, then there must be something wrong with the compiled files.

What is the best way to resolve something like this? As any other way, deleting the build and starting afresh as a new build.

This is what I did, and it worked.

Here is what I did, the steps I took:

  • Deleted android build file, you can find this file in:
    android>app inside app delete build folder
  • Then I cleaned the gradlew:
cd android &&./gradlew clean
  • Next I rebuilt the application again
  • Then I ran the APK

Voila! It solved all the above issues. I hope this will help you and save you time, if you face similar error or the same error.

If it helps you, like this post.

My name is Anayo Oleru, I specialise in Backend Development(NodeJS & ExpressJS), but I am experienced with Web frontend(ReactJS) and mobile(React-native). And I am open to offers in these fields.

You can follow me on Twitter at @AnayoOleru or send an email to: anayo_oleru@outlook.com

Cheers and take care.




Source link

UseEffect: Is it really Effective?



What Are Hooks

Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.



What is useEffect

If you have been working with class component you would have performed side effects in your component like updating Ui, fetching data from api or subscribing to any changes. Since the render method is too early to perform side effects we have lifecycle method in class component.

  1. ComponentDidMount
  2. ComponentDidUpdate
  3. ComponentWillUnmount

You must have been concerned about how useEffect would handle all of this. Let’s get started without further ado.

alright-then-jim-carrey.gif



How to use useEffect

UseEffect accept two arguments:

  • Callback: It is a function where we put write the side – effect logics.
  • Dependency : It is an optional array of dependency. Callback function got executed whenever these dependency changes.
  useEffect(() => 
  //Callback
  , [dependencies]);

Let’s have a look at all of the scenarios with some examples:

  • When the dependency is not provided: This side-effect runs after every rendering.
  useEffect(() => 
    console.log('App.js: useEffect');
  );

  return (
    <SafeAreaView style=backgroundStyle>
      <View>
        <Text style=styles.sectionTitle>Hi There count times</Text>
        <Button
          title="Press me"
          onPress=() => 
            setCount(count + 1);
          
        />
      </View>
    </SafeAreaView>
  );

If we check at the logs, we can see that the side-effect is called whenever the count changes.

 LOG  App.js: useEffect
 LOG  App.js: useEffect
 LOG  App.js: useEffect
 LOG  App.js: useEffect
  • When the dependency array is empty: This side-effect will call first time only.
 useEffect(() => 
    console.log('App.js: useEffect');
  , []);

If we look into logs, side-effect got called only one time

 LOG  Click Me
 LOG  Click Me
 LOG  Click Me
 LOG  Click Me

When configured in such a way, the useEffect() executes the callback just once, after initial mounting. We can say it will work like componentDidMount()

  • When the dependency array have some parameter: This side-effect runs whenever the parameter changes .
 const [count, setCount] = React.useState(0);
  const [countDown, setCountDown] = React.useState(100);
  useEffect(() => 
    console.log('App.js: useEffect');
  , [count]);
  return (
    <SafeAreaView style=flex:1>
      <View>
        <Text style=styles.sectionTitle>Hi There count times</Text>
        <Text style=styles.sectionTitle>Time is ticking countDown</Text>
        <Button
          title="Increment"
          onPress=() => 
            console.log('Increment Count');
            setCount(count + 1);
          
        />
        <Button
          title="Decrement"
          onPress=() => 
            console.log('Decrement Count');
            setCountDown(countDown - 1);
          
        />
      </View>
    </SafeAreaView>
  );

If you closely look into console, You will find whenever the value of count changes, useEffect got called only then.

 LOG  App.js: useEffect
 LOG  Decrement Count
 LOG  Decrement Count
 LOG  Decrement Count
 LOG  Decrement Count
 LOG  Increment Count
 LOG  App.js: useEffect
 LOG  Increment Count
 LOG  App.js: useEffect
 LOG  Increment Count
 LOG  App.js: useEffect

So you can see it will work the same way like ComponentDidUpdate work in class component

Now you must be thinking, what about side-effect cleanup? Class component has a separate method to deal with it.
tenor.com

  • Side-Effect Cleanup

Some side effects need a cleanup, like canceling any api call while un-mounting, closing connection or clearing timers.

We can achieve this by returning a cleanup function from
useEffect() callback
.

useEffect(() => 
  // This is your side-effect logic
  return function cleanup() 
    // Side-effect cleanup
  ;
,[dependencies]);

Cleanup works in following way:

  1. While mounting the component, useEffect() invokes the callback having the side-effect. cleanup function is not called.
  2. On later renderings, before invoking the next side-effect callback, useEffect() invokes the cleanup function from the previous side-effect execution, then runs the current side-effect.
  3. At the end, after unmounting the component, useEffect() invokes the cleanup function from the latest side-effect.

Let me show you some basic code to explain:

 const [count, setCount] = React.useState(0);
  useEffect(() => 
    console.log('App.js: useEffect');
    return function cleanup() 
      console.log('App.js: cleanup');
    ;
  , [count]);
  return (
    <SafeAreaView style=flex: 1>
      <View>
        <Text style=styles.sectionTitle>Hi There count times</Text>
        <Button
          title="Increment"
          onPress=() => 
            console.log('Increment Count');
            setCount(count + 1);
          
        />
      </View>
    </SafeAreaView>
  );

If you look into the logs, cleanup function is getting called every time before invoking the next side-effect.

 LOG  App.js: useEffect
 LOG  Increment Count
 LOG  App.js: cleanup
 LOG  App.js: useEffect
 LOG  Increment Count
 LOG  App.js: cleanup
 LOG  App.js: useEffect



Use case of useEffect()

  1. Updating Ui whenever the state changes.
  2. *When we want to perform any action once, especially when the app mount first time. We can prefer useEffect. *

    Let us consider an example , we want to fetch list of newsfeed while loading the newsfeed screen.

 const [newsFeed, setNewsFeed] = React.useState([]);
  async function fetchNewsFeed() 
    const response = await fetch('/employees');
    const newsFeedData = await response.json(response);
    setNewsFeed(newsFeedData);
  

  useEffect(() =>     //  can not be async
    fetchNewsFeed(); // Can invoke async function
  , []);



Conclusion

  1. useEffect(callback, dependencies) is the hook that manages the side-effects in functional components.

    • Callback argument is a function to put the side-effect logic.
    • Dependencies is a list of dependencies of your side-effect: being props or state values.
  2. useEffect(callback, dependencies) invokes the callback after initial mounting, and on later renderings, if any value inside dependencies has changed.

  3. useEffect(callback, dependencies) can be used in following ways

    • initial mounting(ComponentDidMount),
    • Managing state changes (ComponentDidUpdate)
    • For side-effect cleanup (ComponentWillUnmount)



Related Link

  1. React-Hooks-Documentation
  2. Hooks-API-Reference

thanks.gif

I hope this post helped you understand the basic idea of useEffect(). Feel free to add your suggestions.
Follow me on Twitter.

Happy coding




Source link

How to implement Material UI in React?

Material-UI is a library that provides React components for easy and fast web development. So, in this article, we will see how to implement Material UI in React.

How to implement Material UI in React?

We can easily put together really beautiful components and make them work according to our use as all the components are configurable. This saves a lot of time as we don’t have to struggle with CSS to make things presentable. Material-UI components work in isolation. They are self-supporting, and will only inject the styles they need to display.

You’ll learn how to set up and use Material-UI in your React web application as we build a demo ” Sign In ” application.

As you can see the user interface consists of material design elements. We’ll use Material-UI components to display a Sign In form to the user. The application consists of an App Bar on top which contains the title of the application. Then you can use two text fields to input email and password and a Button to Sign In.

Generating The React Project:

First, we need to create a new React project. This can be done by using the create-react-app script in the following way:

npx create-react-app signin-material-ui
After executing this command a new project directory sign in-material-UI is available. Change into the newly created project folder and you’ll find the React starter project. Start your React project by:

npm start
Installing Material-UI Library & Dependencies:
To use Material-UI components we have to make sure that we have installed them on our project which can be done by:

npm install @material-ui/core
Implementing The Sample Application: Before starting building our project we need to delete the default contents of the project responsible for the start screen by:

Select all files in the src folder and delete them.
Create a new file index.js in the src folder.
So, now we can add our own code to the index.js file.

Example:

Create Signing function: First, we will create a container element inside the SignIn function. Also, this will be used in wrapping all the components.

function SignIn()
return(

.
.
.

)

ReactDOM.render(, document.getElementById(“root”));

Creating an App Bar component:

Sign In

Creating Sign In form component: The form will contain two text fields each for email and password, a remember me checkbox, a Sign In button, and some links.

      // Email Textfield


      // Password Textfield


      // Remember Me Checkbox
      }
        label="Remember me"
      /&gt;

      // Sign In button

        Sign In




          // Forgot Password link

            Forgot password?




          // Sign Up Link

            "Don't have an account? Sign Up"

Complete Code:

So, this is index.js if you clear the src folder and create a single indes.js file.

import React from “react”;
import ReactDOM from “react-dom”;
import AppBar from “@material-ui/core/AppBar”;
import Toolbar from “@material-ui/core/Toolbar”;
import Button from “@material-ui/core/Button”;
import TextField from “@material-ui/core/TextField”;
import FormControlLabel from “@material-ui/core/FormControlLabel”;
import Checkbox from “@material-ui/core/Checkbox”;
import Link from “@material-ui/core/Link”;
import Grid from “@material-ui/core/Grid”;
import Typography from “@material-ui/core/Typography”;
import Container from “@material-ui/core/Container”;

function SignIn()
return (

Sign In

variant=”outlined”
margin=”normal”
required
fullWidth
id=”email”
label=”Email Address”
name=”email”
autoComplete=”email”
autoFocus
/>

variant=”outlined”
margin=”normal”
required
fullWidth
name=”password”
label=”Password”
type=”password”
id=”password”
autoComplete=”current-password”
/>

control=
color=”primary” />
label=”Remember me”
/>

fullWidth variant=”contained”
color=”primary”>
Sign In

Forgot password?

“Don’t have an account? Sign Up”

);

ReactDOM.render(, document.getElementById(“root”));

Conclusion:

So, in this article, we have been through how to implement Material UI in React. Also, feel free to comment with your suggestions and feedback on the post. Moreover, at BOSC Tech Labs, we have a team of highly experienced React JS developers. They can assist you in developing your customized web app. So contact us to hire experienced React JS developers.

Content Source: https://bosctechlabs.com/how-to-implement-material-ui/


Source link

Create a custom hook for Show/Hide Password Visibility in React Native

Building login and signup forms in a React Native app comprise input fields and buttons. One field that you will often find yourself adding to these forms is the password field. This password field is composed of using React Native’s TextInput component.

The common behavior of this field is to hide a user’s password behind obscure characters.

Take a look at an example of the TextInput component that is used to create a password field.

import React,  useState  from 'react';
import  StyleSheet, TextInput, View  from 'react-native';

export default function App() 
  const [password, setPassword] = useState('');

  return (
    <View style=styles.container>
      <View style=styles.inputContainer>
        <TextInput
          style=styles.inputField
          name='password'
          placeholder='Enter password'
          autoCapitalize='none'
          autoCorrect=false
          textContentType='newPassword'
          secureTextEntry
          value=password
          enablesReturnKeyAutomatically
          onChangeText=text => setPassword(text)
        />
      </View>
    </View>
  );


const styles = StyleSheet.create(
  container: 
    flex: 1,
    backgroundColor: '#F5EEDC',
    alignItems: 'center',
    justifyContent: 'center',
    paddingHorizontal: 12
  ,
  inputContainer: 
    backgroundColor: 'white',
    width: '100%',
    borderRadius: 8,
    flexDirection: 'row',
    alignItems: 'center',
    borderWidth: 4,
    borderColor: '#d7d7d7'
  ,
  inputField: 
     padding: 14,
    fontSize: 22,
    width: '90%'
  
  
});

It uses the secureTextEntry prop such that when a text value is entered in the input field, it is unclear what is being entered in that field.

Here is the output of the above snippet on a device:

ss1

However, giving an option to a user to let them see the current value they enter could lead to a good experience and might be necessary in some cases.



Show or Hide Password Visibility Hook

To add the ability to show or hide the password field’s visibility, let’s create a custom hook in a new file called useTogglePasswordVisibility.js.js.

Start by importing the useState hook from React library. You will need to create two different state variables to toggle between the field’s visibility and change the icon.

Then define a function called useTogglePasswordVisibility. Inside this function, create two new state variables. The first one is called passwordVisibility. Its initial value is set to boolean true. The reason is that this variable will be the value of the prop secureTextEntry on the TextInput component. You would want to hide the password field initially when the user enters the password in the input field.

The second state variable defined is called rightIcon. It has a default value of eye. This value depends on the Icon Library you’re using in your React Native app. For this example, I’m using MaterialCommunityIcons from Expo Vector Icons.

export const useTogglePasswordVisibility = () => 
  const [passwordVisibility, setPasswordVisibility] = useState(true);
  const [rightIcon, setRightIcon] = useState('eye');

  // ...
;

Next, add a method called handlePasswordVisibility that will allow the app user to toggle the password field’s visibility between shown and hidden state.

Lastly, do not forget to return all the variables and the handler method.

export const useTogglePasswordVisibility = () => 
  const [passwordVisibility, setPasswordVisibility] = useState(true);
  const [rightIcon, setRightIcon] = useState('eye');

  const handlePasswordVisibility = () => 
    if (rightIcon === 'eye') 
      setRightIcon('eye-off');
      setPasswordVisibility(!passwordVisibility);
     else if (rightIcon === 'eye-off') 
      setRightIcon('eye');
      setPasswordVisibility(!passwordVisibility);
    
  ;

  return 
    passwordVisibility,
    rightIcon,
    handlePasswordVisibility
  ;
;



Use the Password Visibility Hook

Start by updating import statements in the App.js file:

import React,  useState  from 'react';
import  StyleSheet, Pressable, TextInput, View  from 'react-native';
import  MaterialCommunityIcons  from '@expo/vector-icons';

import  useTogglePasswordVisibility  from './hooks/useTogglePasswordVisibility';

Next, access the required variables and method from the useTogglePasswordVisibility hook. Add the following line at the top of the App component:

export default function App() 
  const  passwordVisibility, rightIcon, handlePasswordVisibility  =
    useTogglePasswordVisibility();
  const [password, setPassword] = useState('');

  // ...

Modify the TextInput component’s prop. Make sure to add the passwordVisibility as the value to the secureTextEntry prop.

<TextInput
  secureTextEntry=passwordVisibility
  // ... rest of the props remain unchanged
/>

Inside the View component that wraps the TextInput, add a button using the Pressable component. This button will allow the user to toggle between the hidden and shown state of the password field.

This button wraps the icon component.

<View style=styles.inputContainer>
  /* After TextInput component */
  <Pressable onPress=handlePasswordVisibility>
    <MaterialCommunityIcons name=rightIcon size=22 color="#232323" />
  </Pressable>
</View>

That’s all! Here is the output after this step:

ss2

Here is the complete code for the App.js file:

import React,  useState  from 'react';
import  StyleSheet, Pressable, TextInput, View  from 'react-native';
import  MaterialCommunityIcons  from '@expo/vector-icons';

import  useTogglePasswordVisibility  from './hooks/useTogglePasswordVisibility';

export default function App() 
  const  passwordVisibility, rightIcon, handlePasswordVisibility  =
    useTogglePasswordVisibility();
  const [password, setPassword] = useState('');

  return (
    <View style=styles.container>
      <View style=styles.inputContainer>
        <TextInput
          style=styles.inputField
          name="password"
          placeholder="Enter password"
          autoCapitalize="none"
          autoCorrect=false
          textContentType="newPassword"
          secureTextEntry=passwordVisibility
          value=password
          enablesReturnKeyAutomatically
          onChangeText=text => setPassword(text)
        />
        <Pressable onPress=handlePasswordVisibility>
          <MaterialCommunityIcons name=rightIcon size=22 color="#232323" />
        </Pressable>
      </View>
    </View>
  );


const styles = StyleSheet.create(
  container: 
    flex: 1,
    backgroundColor: '#F5EEDC',
    alignItems: 'center',
    justifyContent: 'center',
    paddingHorizontal: 12
  ,
  inputContainer: 
    backgroundColor: 'white',
    width: '100%',
    borderRadius: 8,
    flexDirection: 'row',
    alignItems: 'center',
    borderWidth: 4,
    borderColor: '#d7d7d7'
  ,
  inputField: 
    padding: 14,
    fontSize: 22,
    width: '90%'
  
);




Source link

Building a Twitter Spaces clone in React Native

In the mood to learn something new over the weekend?🧑‍💻

100ms 🤝 GeekyAnts

Join speaker 🎙 Vipul Bhardwaj, Senior Engineer at #NativeBase, for a webinar 🎥 with #100ms on how to build a Twitter Spaces clone with #React Native.

What would you learn?

  • What is NativeBase and how to build consistent UI with it
  • What is Twitter Spaces and how does it work
  • How to build Twitter Spaces with 100ms React Native SDK

Sounds exciting? then register now 👇
Tune in on 🗓 18th December

https://www.100ms.live/events/twitter-spaces-clone


Source link

Applicable React Redux example step by step from scratch

A simple example of React Redux

Step 0: Create a react app and install redux

npx create-react-app reactapp
cd reactapp
yarn add react-redux

Step 1: Create actions

ACTIONS -> INCREMENT (describes what you want to do!) it’s a simple function
In src create a folder name it actions and add file named index.js



src/actions/index.js
export const increment = (number) => 
    return 
        type: "INCREMENT",
        payload: number,
    ;
;

export const decrement = () => 
    return 
        type: "DECREMENT",
    ;
;

Step 2: Create reducers

REDUCERS -> here an action transfer from one state to another state, it gonna modify our store.
You can have many reducers (Authentication reducer, Movielist reducer etc …)

Create a folder called reducers
inside reducers create counter.js file



src/reducers/counter.js
const counterReducer = (state = 0, action) => 
    switch (action.type) 
        case "INCREMENT":
            return state + action.payload;
        case "DECREMENT":
            return state - 1;
        default:
            return state;
    
;

export default counterReducer;

inside reducers create a second reducer named isLogged.js file.



src/reducers/isLogged.js
const loggedReducer = (state = false, action) => 
    switch (action.type) 
        case "SIGN_IN":
            return !state;
        default:
            return state;
    
;

export default loggedReducer;

inside reducers create a index file to export them.



src/reducers/index.js
import counterReducer from "./counter";
import loggedReducer from "./isLogged";
import  combineReducers  from "redux";

const allReducers = combineReducers(
    //you can name it anything
    //counterReducer (this means counterReducer:counterReducer )
    counter: counterReducer,
    isLogged: loggedReducer,
);

export default allReducers;

Step 3: Create your Store

Store -> You can add your store in app.js.
You can only have one store



src/app.js
import React from "react";
import  useSelector, useDispatch  from "react-redux";
import  increment, decrement  from "./actions";

function App() 
    const counter = useSelector((state) => state.counter);
    const isLogged = useSelector((state) => state.isLogged);
    const dispatch = useDispatch();

    return (
        <div className="App">
            <h1>Counter counter </h1>
            <button onClick=() => dispatch(increment(5))>+</button>
            <button onClick=() => dispatch(decrement())> -</button>
            isLogged ? <h3>Valuable Information I shouldn't see</h3> : ""
        </div>
    );


export default App;

Testing it
Option 1: check the console in inspect to see how it increments and decrements.
Option.
Option 2: Install Redux Devtool chrome extension.
https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en

Github repo:
https://github.com/Byusa/learn-redux

Reference:
https://react-redux.js.org/
https://redux.js.org/tutorials/fundamentals/part-5-ui-react
https://www.youtube.com/watch?v=CVpUuw9XSjY


Source link

Understand React Redux from scrach on one page

Redux a popular React and React Native state management library.
Here is all component of redux in one page

npx create-react-app reactapp

cd reactapp

yarn add react-redux

Add this in index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import  createStore  from "redux";
import allReducer from "./reducers";

//ACTION  -> INCREMENT (describes what you want to do!) it's a simple function

const increment = () => 
    return 
        type: "INCREMENT",
    ;
;

const decrement = () => 
    return 
        type: "DECREMENT",
    ;
;

//REDUCER -> (action transfer from one state to another state, it gonna modify our store)
//You can have many reducers (Auth reducer, Movielist reducer etc ...)
const counter = (state = 0, action) => 
    switch (action.type) 
        case "INCREMENT":
            return state + 1;
        case "DECREMENT":
            return state - 1;
    
;

//STORE  -> Globalized STATE
let store = createStore(counter);

//Display it in the console.
store.subscribe(() => console.log(store.getState()));

//DISPATCH (DISPATTCH this action to the reducer)
store.dispatch(increment());
store.dispatch(decrement());
store.dispatch(increment());

ReactDOM.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
    document.getElementById("root")
);

reportWebVitals();

Testing it: check the console in inspect to see how it increments and decrements.

Check this repo for more advanced way of doing it:

https://github.com/Byusa/learn-redux

This repo shows the use of redux it could be one a proper way with the store and multiple reducers their own folders.

Reference:
https://www.youtube.com/watch?v=CVpUuw9XSjY


Source link

Build a mobile audio chat app in an afternoon with React Native

At Daily, one of our primary focuses has been supporting audio-only apps with our APIs. Lately, we’ve been hearing more and more discussions about how to help app users avoid Zoom fatigue — the feeling of being burnt out from sitting in video calls all day long.

Audio-only apps are a great solution to this issue as they typically require less cognitive resources to participate in. They are also a great option for larger calls or calls on mobile devices as they tend to have lower CPU requirements. (So you and your devices need to think less. 😉)

To help our customers support their audio-only use cases, we launched an audio starter kit (a.k.a. Party Line) earlier this year, which includes demo apps in React (web), iOS, Android, and React Native.

In today’s tutorial, we’ll be doing a deeper dive into how the React Native version of Party Line works.

By the end of this tutorial, you’ll know how to build a Clubhouse-esque Daily audio app using our react-native-daily-js library and Daily’s customizable call object.



Who is this tutorial for?

To get the most out of this tutorial, some basic React Native knowledge is useful. If you’ve never used React Native before but are familiar with React and React hooks, you should be able to follow along.

Note: React and React Native code is fairly similar but does have some differences, so we’ll do our best to explain those differences as they come up!



Getting set up locally

To run the Party Line app locally, follow the instructions located in the Github repo’s README. Instructions for both iOS and Android are included, depending which OS you prefer to primarily test React Native apps.



Feature set and backlog

Party Line app views

Let’s start by describing which audio call features will (and won’t) be included.

Party Line will include two views:

  1. A home screen with a form to join or create an audio call
  2. An in-call view once a call has been joined

Let’s review some of the basic functionality:

  • From the home screen, the local user can fill out their name in the form and either specify a room code or leave the code blank. If they leave the code blank, Party Line will automatically create a new room and join it when the form is submitted.
  • Each room created in Party Line will expire after 10 minutes. The expiry is set when the room is created via the Daily REST API and something we’ve included to avoid long-living demo rooms. This can be adjusted in the room settings to match your use case, however.
  • Once the room is joined, the room code can be shared with anyone. Rooms created from one app are compatible with any of our other Party Line apps (iOS, Android, React/web, or React Native).

We’ll allow for three different types of participants: moderator, speaker, listener.

Participant types are handled as follows:

  • The room creator is the moderator
  • Moderators are indicated in the UI by a star next to their initials
  • Moderators can promote listeners to speakers, speakers to listeners, and anyone to a moderator
  • Listeners can raise (or lower) their hands to indicate they would like to speak
  • Speakers and moderators can mute/unmute themselves, but only mute others
  • When a moderator leaves the call and there are no other moderators present, the call ends for everyone

Moderator updating their local audio settings

In terms of constraints, we will not:

  • Use any external account management or authentication
  • Have a database, though we recommend handling the participant types with a database for production-level apps (❗)
  • Have a backend aside from serverless functions, which call the Daily REST API
  • Offer a list of rooms to join; the participant will need to know the code for the room they want to join. This would be a great feature to add, though 😉

We’ll cover how most of this works below or share links to existing resources for anything we don’t have time to go over.



Component structure

Before we dive into the code, let’s plan the structure we’re going to use for our components.

Component structure

Here, we have our App component as the top-level parent component. It will render the Header component with the app title and information. It will also conditionally render either the InCall component, which handles the Daily audio call, or the PreJoinRoom, which has a form to join a Daily audio call, depending on our app state.

Our InCall component has the most complexity because it handles our Daily call.

InCall contains the following components:

  • One Counter component, which displays how much time is left in the call
  • A CopyLinkBox to copy and share the room code
  • A Tray to control your local microphone, raise your hand, or leave the call
  • A Participant component for each participant. It renders:
    • Participant UI, with each participant represented by a box with their initials and a “show more” menu button that renders the Menu component in certain conditions. (More on that below)
    • The DailyMenuView component, which provides the participant’s audio for the call.
      Note: In a React project, you would just render an <audio> element.



CallProvider.jsx: The brain of this operation 🧠

To keep our logic organized and in (mostly) one place, we are using the React Context API, which helps us store global app state. Our App component wraps its contents in the CallProvider component (our context), which means all of our app’s contents can access the data set in our call context.

// App.jsx
function App() 
   return (
       <CallProvider>
          <AppContent />
       </CallProvider>
   );

Note: The Context API can be used by any React app (not just React Native). In fact, we did just that in the web version of this app!

Now, let’s spend some time understanding what’s happening in CallProvider. (We can’t cover every detail here, so let us know if you have questions.)

There are several actions (i.e. methods) we define in CallProvider:

Starting with our app state, let’s look at which values we’ll initialize and export to be used throughout our app.

// CallProvider.jsx
export const CallProvider = (children) =>  in-call
 const [callFrame, setCallFrame] = useState(null);
 const [participants, setParticipants] = useState([]);
 const [room, setRoom] = useState(null);
 const [error, setError] = useState(null);
 const [roomExp, setRoomExp] = useState(null);
 const [activeSpeakerId, setActiveSpeakerId] = useState(null);
 const [updateParticipants, setUpdateParticipants] = useState(null);
 
return (
   <CallContext.Provider
     value=
       getAccountType,
       changeAccountType,
       handleMute,
       handleUnmute,
       displayName,
       joinRoom,
       leaveCall,
       endCall,
       removeFromCall,
       raiseHand,
       lowerHand,
       activeSpeakerId,
       error,
       participants,
       room,
       roomExp,
       view,
     >
     children
   </CallContext.Provider>
 );
;



How updating a participant type works using sendAppMessage

In this demo, we manage participant types (moderator, speaker, or listener) by appending a string to the end of each participant’s username, which is not shown in the UI (e.g. $username_MOD for moderators).

❗Note: For production-level apps, we recommend building a backend for participant type management. This current solution is meant to keep the code client-side for demo purposes.

That said, let’s look at how participant type management works.

Whenever a moderator updates another participant’s account type, that update will be communicated to other participants with the Daily method sendAppMessage.

All participants will receive that app message via the app-message event listener, which is added in CallProvider:
callFrame.on('app-message', handleAppMessage);

This will use the callback method handleAppMessage, which will update the appended string on the username to the new account type (e.g._LISTENER to _SPEAKER).

// CallProvider.jsx
 const handleAppMessage = async (evt) => 
     console.log('[APP MESSAGE]', evt);
     try 
       switch (evt.data.msg) 
         case MSG_MAKE_MODERATOR:
           console.log('[LEAVING]');
           await callFrame.leave();
           console.log('[REJOINING AS MOD]');

           let userName = evt?.data?.userName;
           // Remove the raised hand emoji
           if (userName?.includes('')) 
             const split = userName.split('');
             userName = split.length === 2 ? split[1] : split[0];
           
           joinRoom(
             moderator: true,
             userName,
             name: room?.name,
           );
           break;
         case MSG_MAKE_SPEAKER:
           updateUsername(SPEAKER);
           break;
         case MSG_MAKE_LISTENER:
           updateUsername(LISTENER);
           break;
         case FORCE_EJECT:
           //seeya
           leaveCall();
           break;
       
      catch (e) 
       console.error(e);
     
   ;

Promoting a listener to speaker

Making someone a moderator is slightly more complicated because they need to rejoin the call with a Daily token, which will give them the owner privileges they need to be able to mute other participants. To do this, we kick them out of the call quietly (callFrame.leave()) and then immediately rejoin them as a moderator with an owner token.

Note: To make a participant a meeting owner with a meeting token, the is_owner token property must be true. See our token configuration docs for more information.

As we go through specific components below, we’ll loop back to some of the other specific methods outlined in CallProvider as they’re used.



PreJoinRoom form

The PreJoinRoom component is a form with three inputs (first name, last name, join code), and a button to submit the form. Only the first name is a required field; the last name is optional and if no join code is provided, we take that to mean the user wants to create a new room to join.

Let’s focus on what happens when you submit the form:

// PreJoinRoom.jsx
const PreJoinRoom = (handleLinkPress) => {
 const joinRoom, error = useCallState();
 const [firstName, setFirstName] = useState('');
 const [lastName, setLastName] = useState('');
 const [roomName, setRoomName] = useState('');
 const [submitting, setSubmitting] = useState(false);
 const [required, setRequired] = useState(false);

 const submitForm = useCallback(
   (e) =>  '');

     let name = '';
     if (roomName?.trim()?.length) 
       name = roomName;
       /**
        * We track the account type by appending it to the username.
        * This is a quick solution for a demo; not a production-worthy solution!
        */
       userName = `$userName_$LISTENER`;
      else 
       userName = `$userName_$MOD`;
     
     joinRoom(userName, name);
   ,
   [firstName, lastName, roomName, joinRoom],
 );

In submitForm, we first make sure the first name is filled out. If not, we update our required state value, which blocks the form from being submitted.

Next, we get the local user’s username by joining the first and optional last name values:

let userName = firstName?.trim() + (lastName?.trim() ?  $lastName?.trim() : '');

If there’s a room code (roomName) provided in the form, we assign that to our name variable and update the username to have _LISTENER appended to it.

If there is no room code, we don’t set a room name and append _MOD to the username. As mentioned, the person creating the room is the moderator by default so we track that in the name.

if (roomName?.trim()?.length) 
    name = roomName;

    userName = `$userName_$LISTENER`;
 else 
    userName = `$userName_$MOD`;

Once we have our userName and optional room name, we can then call joinRoom, a method from CallProvider.

const joinRoom = async (userName, name, moderator) => 
   if (callFrame) 
     callFrame.leave();
   

   let roomInfo = name;
   /**
    * The first person to join will need to create the room first
    */
   if (!name && !moderator) 
     roomInfo = await createRoom();
   
   setRoom(roomInfo);

   /**
    * When a moderator makes someone else a moderator,
    * they first leave and then rejoin with a token.
    * In that case, we create a token for the new mod here.
    */
   let newToken;
   if (moderator) 
     // create a token for new moderators
     newToken = await createToken(room?.name);
   
   const call = Daily.createCallObject(videoSource: false);

   const options = 
     // This can be changed to your Daily domain
     url: `https://devrel.daily.co/$roomInfo?.name`,
     userName,
   ;
   if (roomInfo?.token) 
     options.token = roomInfo?.token;
   
   if (newToken?.token) 
     options.token = newToken.token;
   

   await call
     .join(options)
     .then(() => 
       setError(false);
       setCallFrame(call);
       call.setLocalAudio(false); 
       setView(INCALL);
     )
     .catch((err) => 
       if (err) 
         setError(err);
       
     );
 ;

joinRoom has the following steps:

  • It leaves the current room if you’re somehow already in one. (This is mostly defensive programming for those terrible, horrible, no good, very bad code bug days.)
  • It creates a new room with our createRoom method mentioned above if a room name isn’t provided
  • It creates a token if the participant joining is a moderator. This can happen if they are the first person to join or if they’re rejoining as a moderator after being upgraded
  • Next, we create our local Daily call object instance:
    const call = Daily.createCallObject(videoSource: false);
    (We’ll go into more detail about the videoSource property below.)
  • We also set our call options that we’ll need before joining the call (room URL being joined, username, and optional token for moderators
const options = 
  url: `https://devrel.daily.co/$roomInfo?.name`,
  userName,
;
  • Finally, we join the call and update our local state accordingly, including updating our view value to incall
await call
    .join(options)
    .then(() => 
       setError(false);
       setCallFrame(call);
       /**
        * Now mute, so everyone joining is muted by default.
        */
       call.setLocalAudio(false);
       setView(INCALL);
    )

Once this is complete, we’ll be brought to our InCall component because of this condition in App.js:

view === INCALL && <InCall handleLinkPress=handleLinkPress />



The in-call experience: Moderators and the rest of us

Now that we know how to get into a call, let’s focus on how we actually use the react-native-daily-js library to get our audio working.

The InCall component renders a Participant component for each participant in the call, and displays them in the UI based on who can speak. Moderators and speakers are shown at the top and listeners are at the bottom.

Speakers and listeners in-call

Let’s look at how we render the Speakers section, which includes moderators and speakers, i.e. anyone who can unmute themselves.

// InCall.jsx
 const mods = useMemo(() => participants?.filter((p) => p?.owner), [
   participants,
   getAccountType,
 ]);

 const speakers = useMemo(
   (p) =>
     participants?.filter((p) => 
        return getAccountType(p?.user_name) === SPEAKER;
   ),
   [participants, getAccountType],
 );

The individual participant UI includes details like their name, initials, a star emoji if they’re a moderator, and a “more” menu with some actions depending on their participant type.

Participant UI

The most important aspect of the Participant component is not visible in the UI, though: the DailyMediaView component!

// Participant.jsx
import DailyMediaView from '@daily-co/react-native-daily-js';

const Participant = (participant, local, modCount, zIndex) => {
...

audioTrack && (
    <DailyMediaView
        id=`audio-$participant.user_id`
        videoTrack=null
        audioTrack=audioTrack
    />
)
...

This is a component imported from react-native-daily-js and accepts audio and/or video tracks from your participants list, also provided by Daily’s call object (recall: callObject.participants()). Since this is an audio-only app, we set videoTrack to null, and audioTrack to each participant’s audio track:

// Participant.jsx
const audioTrack = useMemo(
   () =>
     participant?.tracks?.audio?.state === 'playable'
       ? participant?.tracks?.audio?.track
       : null,
   [participant?.tracks?.audio?.state],
 );

Once the audio track is set, you will be able to hear the participant. 👂



Sir, this is an Arby’s: Letting moderators mute speakers

Now that we have the audio playing, let’s take a quick look at how we mute participants.

As mentioned, only participants who joined with an owner meeting token are permitted to mute others. (And, by the way, we don’t recommend ever letting participants unmute other participants. It’s a bit invasive! 😬)

To do this, we can take advantage of Daily’s updateParticipant method:

CallProvider.jsx
const handleMute = useCallback(
   (p) => 
     if (!callFrame) return;
     console.log('[MUTING]');

     if (p?.user_id === 'local') 
       callFrame.setLocalAudio(false);
      else 
       callFrame.updateParticipant(p?.session_id, 
         setAudio: false,
       );
     
     setUpdateParticipants(`unmute-$p?.user_id-$Date.now()`);
   ,
   [callFrame],
 );

Here in CallProvider, we have one handleMute method for participants to mute themselves or others. If they’re muting themselves, they call setLocalAudio(false). If they’re muting someone else, they call updateParticipant with the to-be-muted participant’s session_id and a properties object with setAudio equal to false.



You, you, you, oughta know

One important aspect of audio-only apps to be aware of is device permissions. Since Daily’s React Native library is compatible with audio and video apps, it will ask for microphone and camera permissions, unless we intervene.

Device permission requests

If you don’t address this issue, your app users will see both of these device permission requests, which may be a bit of a red flag 🚩 for them. (Why would you need camera permissions for an audio app? 🤔)

To help your apps seem less — well — creepy, you can simply set videoSource to false when you create the local call object instance.

const call = Daily.createCallObject(videoSource: false);

Adding this one detail means your users are only asked for microphone permissions. 💫



Resources

We hope this overview of the Party Line app helps you better understand how it works under the hood. We couldn’t cover every detail, so check out these existing tutorials/resources that cover related topics:

In our next React Native tutorial, we’ll focus on building a video call app, so stay tuned for that!

As always, if you have any questions, let us know!


Source link