Saturday, 2 May 2020

ionic react FileSystem save

snap a photo

image is saved in camera directory
 //hooks/usePhoteGallery.tsx

import { useState, useEffect } from "react";
import { useCamera } from '@ionic/react-hooks/camera';
import { useFilesystem, base64FromPath } from '@ionic/react-hooks/filesystem';
import { useStorage } from '@ionic/react-hooks/storage';
import { isPlatform } from '@ionic/react';
import {
    CameraResultType, CameraSource, CameraPhoto,
    Capacitor, FilesystemDirectory
} from "@capacitor/core";

export interface Photo {
    filepath: string;
    webviewPath?: string;
    base64?: string;
}

export function usePhotoGallery() {
    const [photos, setPhotos] = useState<Photo[]>([]);
    const { getPhoto } = useCamera();
    const { deleteFile, getUri, readFile, writeFile } = useFilesystem();

    const takePhoto = async () => {
        const cameraPhoto = await getPhoto({
            resultType: CameraResultType.Uri,
            source: CameraSource.Camera,
            quality: 100
        });

        const fileName = new Date().getTime() + '.jpeg';

        const savedFileImage = await savePicture(cameraPhoto, fileName);

        const newPhotos = [savedFileImage, ...photos];
        setPhotos(newPhotos)
    };

  //CameraPhoto represents newly captured photo
    const savePicture = async (photo: CameraPhoto, fileName: string): Promise<Photo> => {
        const base64Data = await base64FromPath(photo.webPath!);
        const savedFile = await writeFile({
          path: fileName,
          data: base64Data,
          directory: FilesystemDirectory.Data
        });
   
        // Use webPath to display the new image instead of base64 since it's
        // already loaded into memory
        return {
          filepath: fileName,
          webviewPath: photo.webPath
        };
      };

    return {
        photos,
        takePhoto
    };
}

reference:
https://ionicframework.com/docs/react/your-first-app/3-saving-photos
http://chuanshuoge2.blogspot.com/2020/05/ionic-react-camera.html

Friday, 1 May 2020

ionic react camera

app opens, press camera button

choose camera

snap a picture

picture is stored temporarily

take another picture

//hooks/usePhotoGallery.tsx

import { useState, useEffect } from "react";
import { useCamera } from '@ionic/react-hooks/camera';
import { useFilesystem, base64FromPath } from '@ionic/react-hooks/filesystem';
import { useStorage } from '@ionic/react-hooks/storage';
import { isPlatform } from '@ionic/react';
import {
    CameraResultType, CameraSource, CameraPhoto,
    Capacitor, FilesystemDirectory
} from "@capacitor/core";

export interface Photo {
    filepath: string;
    webviewPath?: string;
    base64?: string;
}

export function usePhotoGallery() {
    const [photos, setPhotos] = useState<Photo[]>([]);
    const { getPhoto } = useCamera();

    const takePhoto = async () => {
        const cameraPhoto = await getPhoto({
            resultType: CameraResultType.Uri,
            source: CameraSource.Camera,
            quality: 100
        });

        const fileName = new Date().getTime() + '.jpeg';
        const newPhotos = [{
            filepath: fileName,
            webviewPath: cameraPhoto.webPath
        }, ...photos];
        setPhotos(newPhotos)
    };

    return {
        photos,
        takePhoto
    };
}

-------------------------------------
//pages/tab2.tsx

import React from 'react';
import {
  IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonButton,
  IonGrid, IonRow, IonCol, IonImg, IonFab, IonFabButton, IonIcon
} from '@ionic/react';
import ExploreContainer from '../components/ExploreContainer';
import './Tab2.css';
import { usePhotoGallery } from '../hooks/usePhotoGallery';
import { camera } from 'ionicons/icons';

const Tab2: React.FC = () => {
  const { photos, takePhoto } = usePhotoGallery();

  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>Camera Example</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent>
        <IonFab vertical='bottom' horizontal='center' slot='fixed'>
          <IonFabButton onClick={() => takePhoto()}>
            <IonIcon icon={camera} />
          </IonFabButton>
        </IonFab>
        <IonGrid>
          <IonRow>
            {photos.map((photo, index) => (
              <IonCol size="6" key={index}>
                <IonImg src={photo.webviewPath} />
              </IonCol>
            ))}
          </IonRow>
        </IonGrid>
      </IonContent>
    </IonPage>
  );
};

export default Tab2;

reference:
taking photos
https://ionicframework.com/docs/react/your-first-app/2-taking-photos

ionic react-hooks
https://github.com/ionic-team/ionic-react-hooks

fab
http://chuanshuoge2.blogspot.com/2020/04/ionic-react-fab.html
http://chuanshuoge2.blogspot.com/2020/04/ionic-react-fab-2.html

Wednesday, 29 April 2020

android studio run ionic on android phone

settings => about phone => tap build number 7 times => system => developer options

enable usb debug

cmd => cd ionic project => npx cap open android
android studio opens => tools => sdk manager

check device android versions

sdk tools => check google driver => apply
close sdk manager => select device => run

ionic app installed on smart phone

app runs on smart phone
reference:
http://chuanshuoge2.blogspot.com/2020/04/ionic-react-android-studio.html
https://chuanshuoge2.blogspot.com/2020/04/capacitor-new-way-to-build-native.html



white screen after splash
https://forum.ionicframework.com/t/after-splash-screen-display-white-screen-long-time/80162/46

Yes, I could observe this white splash screen behavior on low-mid android smartphones, a little bit older tablets regardless of what the app developers intended. Some apps will be stuck at white splash screen on start and will not progress to home page at all.

I carry eight android testing devices including two tablets, one 12 inch android book, five smartphones of all kinds. This problem is a legitimate & observable problem of Cordova. This thread has been visited 18,000 times since it started in early 2017. That tells everything.

Thankfully, Ionic team is now working on developing their own native layer which will replace Cordova. I hope this problem gets solved soon.

Tuesday, 28 April 2020

ionic react android studio run on simulator

//cmd

//create ionic app
ionic start ionicApp

framework: react
start template: tabs
android support: yes

//build ionic app
ionic build -prod

//convert ionic react to java and open in android studio
npx cap add android
npx cap sync
npx cap open android

in android studio, click open avd manager to add virtual device

added pixel 2 as virtual device, click run

virtual device opens, wait for app to install. app runs

reference:
connect smartphone with android studio
https://javatutorial.net/connect-android-device-android-studio

ionic capacitor open android studio
https://capacitor.ionicframework.com/docs/android#next-steps

gradle module not support error
https://github.com/ionic-team/capacitor/issues/349

Monday, 27 April 2020

ionic react toolbar


import React, { useState } from 'react';
import {
  IonContent, IonHeader, IonPage, IonTitle, IonToolbar,
  IonAlert, IonButton, IonCard, IonCardHeader,
  IonCardSubtitle, IonCardTitle, IonCardContent,
  IonItem, IonIcon, IonLabel, IonBadge, IonList,
  IonItemDivider, IonCheckbox, IonChip, IonAvatar,
  IonGrid, IonRow, IonCol, IonInput, IonToggle,
  IonModal, IonRefresher, IonRefresherContent,
  IonTextarea, IonSelect, IonListHeader,
  IonSelectOption, IonButtons, IonBackButton,
  IonMenuButton, IonSegment, IonSearchbar,
  IonSegmentButton,
} from '@ionic/react';
import ExploreContainer from '../components/ExploreContainer';
import './Tab1.css';
import {
  personCircle, search, ellipsisHorizontal,
  ellipsisVertical, helpCircle, star, create
} from 'ionicons/icons';
import { RefresherEventDetail } from '@ionic/core';
import axios from 'axios'

const Tab1: React.FC = () => {

  return (
    <IonPage>
      <IonContent>
        <IonToolbar>
          <IonTitle>Toolbar Example</IonTitle>
        </IonToolbar>

        <IonToolbar>
          <IonButtons slot="start">
            <IonBackButton defaultHref="/" />
          </IonButtons>
          <IonTitle>Back Button</IonTitle>
        </IonToolbar>

        <IonToolbar>
          <IonTitle size="small">Small Title above a Default Title</IonTitle>
        </IonToolbar>
        <IonToolbar>
          <IonTitle>Default Title</IonTitle>
        </IonToolbar>

        <IonToolbar>
          <IonButtons slot="secondary">
            <IonButton>
              <IonIcon slot="icon-only" icon={personCircle} />
            </IonButton>
            <IonButton>
              <IonIcon slot="icon-only" icon={search} />
            </IonButton>
          </IonButtons>
          <IonButtons slot="primary">
            <IonButton color="secondary">
              <IonIcon slot="icon-only" ios={ellipsisHorizontal} md={ellipsisVertical} />
            </IonButton>
          </IonButtons>
          <IonTitle>Default Buttons</IonTitle>
        </IonToolbar>

        <IonToolbar>
          <IonButtons slot="secondary">
            <IonButton fill="solid">
              <IonIcon slot="start" icon={personCircle} />
        Contact
      </IonButton>
          </IonButtons>
          <IonTitle>Solid Buttons</IonTitle>
          <IonButtons slot="primary">
            <IonButton fill="solid" color="secondary">
              Help
        <IonIcon slot="end" icon={helpCircle} />
            </IonButton>
          </IonButtons>
        </IonToolbar>

        <IonToolbar>
          <IonButtons slot="secondary">
            <IonButton fill="outline">
              <IonIcon slot="start" icon={star} />
        Star
      </IonButton>
          </IonButtons>
          <IonTitle>Outline Buttons</IonTitle>
          <IonButtons slot="primary">
            <IonButton color="danger" fill="outline">
              Edit
        <IonIcon slot="end" icon={create} />
            </IonButton>
          </IonButtons>
        </IonToolbar>

        <IonToolbar>
          <IonButtons slot="secondary">
            <IonButton>Account</IonButton>
          </IonButtons>
          <IonButtons slot="primary">
            <IonButton color="danger">Edit</IonButton>
          </IonButtons>
          <IonTitle>Text Only Buttons</IonTitle>
        </IonToolbar>

        <IonToolbar>
          <IonButtons slot="start">
            <IonMenuButton autoHide={false} />
          </IonButtons>
          <IonButtons slot="secondary">
            <IonButton>
              <IonIcon slot="icon-only" icon={star} />
            </IonButton>
          </IonButtons>
          <IonTitle>Left side menu toggle</IonTitle>
        </IonToolbar>

        <IonToolbar>
          <IonButtons slot="primary">
            <IonButton onClick={() => { }}>
              <IonIcon slot="icon-only" icon={star} />
            </IonButton>
          </IonButtons>
          <IonTitle>Right side menu toggle</IonTitle>
          <IonButtons slot="end">
            <IonMenuButton autoHide={false} />
          </IonButtons>
        </IonToolbar>

        <IonToolbar>
          <IonButtons slot="primary">
            <IonButton onClick={() => { }}>
              <IonIcon slot="icon-only" icon={search} />
            </IonButton>
          </IonButtons>
          <IonSearchbar placeholder="Search Favorites" />
        </IonToolbar>

        <IonToolbar>
          <IonSegment>
            <IonSegmentButton value="all">
              All
      </IonSegmentButton>
            <IonSegmentButton value="favorites">Favorites</IonSegmentButton>
          </IonSegment>
        </IonToolbar>

        <IonToolbar color="secondary">
          <IonButtons slot="secondary">
            <IonButton>
              <IonIcon slot="icon-only" icon={personCircle} />
            </IonButton>
            <IonButton>
              <IonIcon slot="icon-only" icon={search} />
            </IonButton>
          </IonButtons>
          <IonButtons slot="primary">
            <IonButton color="primary">
              <IonIcon slot="icon-only" ios={ellipsisHorizontal} md={ellipsisVertical} />
            </IonButton>
          </IonButtons>
          <IonTitle>Secondary Toolbar</IonTitle>
        </IonToolbar>

        <IonToolbar color="dark">
          <IonButtons slot="secondary">
            <IonButton>
              <IonIcon slot="icon-only" icon={personCircle} />
            </IonButton>
            <IonButton>
              <IonIcon slot="icon-only" icon={search} />
            </IonButton>
          </IonButtons>
          <IonButtons slot="primary">
            <IonButton color="danger">
              <IonIcon slot="icon-only" ios={ellipsisHorizontal} md={ellipsisVertical} />
            </IonButton>
          </IonButtons>
          <IonTitle>Dark Toolbar</IonTitle>
        </IonToolbar>
      </IonContent>
    </IonPage>
  );
};

export default Tab1;

Sunday, 26 April 2020

ionic react toggle


import React, { useState } from 'react';
import {
  IonContent, IonHeader, IonPage, IonTitle, IonToolbar,
  IonAlert, IonButton, IonCard, IonCardHeader,
  IonCardSubtitle, IonCardTitle, IonCardContent,
  IonItem, IonIcon, IonLabel, IonBadge, IonList,
  IonItemDivider, IonCheckbox, IonFab, IonFabButton,
  IonFabList, IonItemGroup, IonItemSliding,
  IonItemOptions, IonItemOption, IonNote, IonMenu,
  IonRouterOutlet, IonListHeader, IonMenuToggle,
  IonButtons, IonMenuButton, IonInput, IonSplitPane,
  IonPopover, IonSpinner, IonRadioGroup, IonRadio,
  IonRange, IonSearchbar, IonFooter, IonSegmentButton,
  IonSegment, IonToast, IonToggle
} from '@ionic/react';
import ExploreContainer from '../components/ExploreContainer';
import './Tab3.css';
import {
  call, home, heart, pin, star,
  globe, basket, camera, bookmark
} from 'ionicons/icons';

const Tab3: React.FC = () => {
  const [checked, setChecked] = useState(false);

  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>Toggle Example</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent>
        <IonList>

          <IonItemDivider>Default Toggle</IonItemDivider>
          <IonItem>
            <IonLabel>Checked: {JSON.stringify(checked)}</IonLabel>
            <IonToggle checked={checked} onIonChange={e => setChecked(e.detail.checked)} />
          </IonItem>

          <IonItemDivider>Disabled Toggle</IonItemDivider>
          <IonItem><IonToggle disabled /></IonItem>

          <IonItemDivider>Checked Toggle</IonItemDivider>
          <IonItem><IonToggle checked /></IonItem>

          <IonItemDivider>Toggle Colors</IonItemDivider>
          <IonItem><IonToggle color="primary" /></IonItem>
          <IonItem><IonToggle color="secondary" /></IonItem>
          <IonItem><IonToggle color="danger" /></IonItem>
          <IonItem><IonToggle color="light" /></IonItem>
          <IonItem><IonToggle color="dark" /></IonItem>

          <IonItemDivider>Toggles in a List</IonItemDivider>
          <IonItem>
            <IonLabel>Pepperoni</IonLabel>
            <IonToggle value="pepperoni" />
          </IonItem>

          <IonItem>
            <IonLabel>Sausage</IonLabel>
            <IonToggle value="sausage" disabled={true} />
          </IonItem>

          <IonItem>
            <IonLabel>Mushrooms</IonLabel>
            <IonToggle value="mushrooms" />
          </IonItem>
        </IonList>
      </IonContent>
    </IonPage>

  );
};

export default Tab3;