GithubHelp home page GithubHelp logo

chukwu / ionic3-image-cache Goto Github PK

View Code? Open in Web Editor NEW
12.0 3.0 9.0 51 KB

A Simple Ionic Image Cache for all types of images with preview modal

TypeScript 100.00%
ionic3 ionicframework angular6 module component

ionic3-image-cache's Introduction

ionic3-Image-Cache

A rewrite of Ionic Image Loader library that fixes the SVG issues, local URL detection and base64 detection yet maintaining all other major features. This Ionic plugin also includes features such as image preview. Hats of to @riron for Image viewer

Ionic Module that loads images in a background thread and caches them for later use. Uses FileTransfer from cordova-plugin-filetransfer, and cordova-plugin-file via ionic-native wrappers. This module helps to save Http requests to the server all the time thereby saving bandwidth and other HTTP related issues.

Gif

Features

  • Downloads images via a native thread. Images will download faster and they will not use the Webview's resources.
  • Preview images on click or tap - (can be disabled)
  • Caches images for later use. Remote URLs are counter matched with the file system file and returned.
  • Shows a loading spinner while the images are loading. (can be disabled and customised with other spinner names in ionic)
  • Allows setting a fallback image to be displayed in case the image you're trying to show doesn't exist on the web. (optional)
  • Works with the WKWebView Engine (iOS), as the images are copied to the temporary directory, which is accessible form within the WebView

Installation

1. Install the NPM Package

npm install --save ionic3-image-cache

2. Install Required Plugins and Dependency

npm i --save @ionic-native/file
ionic cordova plugin add cordova-plugin-file
npm install --save @ionic-native/file-transfer
ionic cordova plugin add cordova-plugin-file-transfer
npm install --save ionic-img-viewer

3. Import IonicImageCacheModule module

Add IonicImageCacheModule.forRoot() in your app's root module

import {IonicImageCacheModule} from 'ionic3-image-cache';

// import the module
@NgModule({
  ...
  imports: [
    IonicImageCacheModule.forRoot()
  ]
})
export class AppModule {}

Usage

Basic Usage

This HTML code demonstrates basic usage of this module:

<ionic-image-cache [src]="this.sender.profile_image.url"></ionic-image-cache>

<ionic-image-cache [isAvatar]="'true'" [showPreview]="'false'" (tap)="whatever($event)" [src]="this.sender.profile_image.url" class="img-circle"></ionic-image-cache>

You can also listen to the load event to be notified when the image has been loaded:

<ionic-image-cache [src]="this.sender.profile_image.url" (loaded)="onImageLoad($event)"></ionic-image-cache>

...

onImageLoad(data) { // do something with the loader }


## HTML attributes
The `<ionic-image-cache>` component takes many attributes that allows you to customize the image. You can use the following table as a reference:
Attribute Name Type Description Default Value
src string The image URL N/A
isAvatar boolean Sets an avatar image as a placeholder rather than image placeholder false
showPreview boolean Displays a full screen version of the image with gestures. true
imgCssClass string You can inject css classes to the image N/A
highResSrc string Set a highres image to use for image preview on click when showPreview is set to true Original Src
fallbackUrl string Sets a custom placeholder image Url while awaiting cache load N/A
spinnerName string Set a spinner name from the list of ionic spinners list dots
spinnerColor string Set a spinner color from your variable set at variables.scss e.g primary Default
alt string Sets an alternative text when image fails on browser N/A
enableSpinner boolean Enable or disable spinner true

Note: Upcoming features. Please contribute your features.

  • Typescript options from controller
  • Clear cache
  • Max cache settings
  • Cache lifespan



Contribution

  • Having an issue? or looking for support? Open an issue and we will get you the help you need.
  • Got a new feature or a bug fix? Fork the repo, make your changes, and submit a pull request.

Support this project

If you find this project useful, please star the repo to let people know that it's reliable. Also, share it with friends and colleagues that might find this useful as well. Thank you 😄

ionic3-image-cache's People

Contributors

chukwu avatar mkhmylife avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ionic3-image-cache's Issues

Not allowed to load local resource:

Screenshot 2019-11-26 at 23 44 57

Not allowed to load local resource: file:///storage/emulated/0/Android/data/uk.co.mobile.csf/files/cache_assets/csfpageemail_management.jpg

ERROR not allowed to load local resource

"Not allowed to load local resource"

is informing me that I am not allowed to view. But no permission was requested.

Could not return a BLOB URL?

let blob = new Blob([new Uint8Array(arquivo)]); this.src = this.sanitize.bypassSecurityTrustUrl( URL.createObjectURL(blob));

The fallbackUrl Attribute

Hi,
I'm using this plugin and i'm happy with it.
In order to customize the default image loader, i guess i shoudld use [fallbackUrl]

But i still have the default image.
Can anyone help me out, please?

Here is what i did in my html file

<ionic-image-cache [fallbackUrl]="'assets/imgs/holder.jpg'" [src]="getApiUrlDataloc+''+p.eventcom_cover"></ionic-image-cache>

Can't resolve all parameters for IonicImageCacheHelperProvider

I follow install instructions and after install all plugins and add module into my app.module.ts my app starts with this error:

Uncaught Error: Can't resolve all parameters for IonicImageCacheHelperProvider: ([object Object], ?, ?, [object Object]).
    at syntaxError (compiler.js:486)
    at CompileMetadataResolver._getDependenciesMetadata (compiler.js:15706)
    at CompileMetadataResolver._getTypeMetadata (compiler.js:15541)
    at CompileMetadataResolver._getInjectableMetadata (compiler.js:15521)
    at CompileMetadataResolver.getProviderMetadata (compiler.js:15881)
    at compiler.js:15792
    at Array.forEach (<anonymous>)
    at CompileMetadataResolver._getProvidersMetadata (compiler.js:15752)
    at compiler.js:15224
    at Array.forEach (<anonymous>)

$ ionic info

Ionic:

   ionic (Ionic CLI)  : 4.10.1 (/usr/local/lib/node_modules/ionic)
   Ionic Framework    : ionic-angular 3.9.2
   @ionic/app-scripts : 3.2.1

Cordova:

   cordova (Cordova CLI) : 8.0.0
   Cordova Platforms     : android 7.0.0, browser 5.0.4, ios 4.5.5
   Cordova Plugins       : cordova-plugin-ionic-webview 2.3.1, cordova-plugin-ionic-wkkeyboard 1.1.1, (and 16 other plugins)

System:

   ios-deploy : 2.0.0
   NodeJS     : v8.12.0 (/usr/local/bin/node)
   npm        : 6.4.1
   OS         : macOS Mojave
   Xcode      : Xcode 10.1 Build version 10B61

This plugin isnt working in IONIC3 due to file & filetransfer libraries versions

I've done exactly as in README.md and even took the versions from package.json and I'm still in dependency hell. If its not a problem of file plugin version, its android version. If that is ok then its IonicImageCacheHelperProvider problem.

I know versions of everything changes each second, but at least if you provide a configuration that works we can base on that.

Android issue - resolveDirectoryUrl FileError {code: 1, message: "NOT_FOUND_ERR"}

I have used ionic3-image-cache for cache image from firebase database.
But there is an issue when run the app on android, it gives me some errors.

  • resolveDirectoryUrl FileError
  • Create directory fail FileError {code: 12, message: "PATH_EXISTS_ERR"}

I have used diagnostic plugin for the permission of external storage like this.
this.diagnostic.requestExternalStorageAuthorization().then(() => {
//User gave permission
}).catch(error => {
//Handle error
});

but still same error,
If someone has the issue like this, please help me.
Thanks.

ios problem

Hello,
i updated my project with wkwebview and the plugin no longer works. The image is not shown but undefined is shown

can you help me?
Thanks!

Error when using construct (private filePath: FilePath)

Hello, when I use private filePath: FilePath in the constructor I have the following error. Thank you very much in advance

core.js:9110 ERROR Error: Uncaught (in promise): Error: Can't resolve all parameters for CadastroAnexarComprovantePage: ([object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], ?).
Error: Can't resolve all parameters for CadastroAnexarComprovantePage: ([object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], ?).
    at syntaxError (compiler.js:2175)
    at CompileMetadataResolver._getDependenciesMetadata (compiler.js:20166)
    at CompileMetadataResolver._getTypeMetadata (compiler.js:20061)
    at CompileMetadataResolver.getNonNormalizedDirectiveMetadata (compiler.js:19690)
    at CompileMetadataResolver._getEntryComponentMetadata (compiler.js:20261)
    at compiler.js:20253
    at Array.forEach (<anonymous>)
    at CompileMetadataResolver._getEntryComponentsFromProvider (compiler.js:20252)
    at compiler.js:20223
    at Array.forEach (<anonymous>)
    at resolvePromise (zone-evergreen.js:797)
    at resolvePromise (zone-evergreen.js:754)
    at zone-evergreen.js:858
    at ZoneDelegate.invokeTask (zone-evergreen.js:391)
    at Object.onInvokeTask (core.js:34182)
    at ZoneDelegate.invokeTask (zone-evergreen.js:390)
    at Zone.runTask (zone-evergreen.js:168)
    at drainMicroTaskQueue (zone-evergreen.js:559)
    at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:469)
    at invokeTask (zone-evergreen.js:1603)

my page.ts

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { HttpService } from '../service/http.service';
import { Camera, CameraOptions, PictureSourceType } from '@ionic-native/camera/ngx';
import { ActionSheetController, ToastController, Platform, LoadingController } from '@ionic/angular';
import { File, FileEntry } from '@ionic-native/File/ngx';
import { WebView } from '@ionic-native/ionic-webview/ngx';
import { Storage } from '@ionic/storage';
import { FilePath } from '@ionic-native/file-path/ngx';

const STORAGE_KEY = 'my_images';

@Component({
  selector: 'app-cadastro-anexar-comprovante',
  templateUrl: './cadastro-anexar-comprovante.page.html',
  styleUrls: ['./cadastro-anexar-comprovante.page.scss'],
})
export class CadastroAnexarComprovantePage implements OnInit {

  images = [];

  constructor(
    private camera: Camera,
    private file: File,
    private http: HttpService,
    private webview: WebView,
    private actionSheetController: ActionSheetController,
    private toastController: ToastController,
    private storage: Storage,
    private platform: Platform,
    private loadingController: LoadingController,
    private ref: ChangeDetectorRef,
    private filePath: FilePath
  ) { }

  ngOnInit() {
    this.platform.ready().then(() => {
      this.loadStoredImages();
    });
  }

  async presentToast(text: string, duration: number) {
    const toast = await this.toastController.create({
      message: text,
      position: 'bottom',
      duration
    });
    toast.present();
  }

  loadStoredImages() {
    this.storage.get(STORAGE_KEY).then(images => {
      if (images !== null) {
        const arr = JSON.parse(images);
        this.images = [];
        for (const img of arr) {
          const filePath = this.file.dataDirectory + img;
          const resPath = this.pathForImage(filePath);
          this.images.push({
            name: img,
            path: resPath,
            filePath,
          });
        }
      }
    });
  }

  pathForImage(img: any) {
    if (img === null) {
      return '';
    } else {
      const converted = this.webview.convertFileSrc(img);
      return converted;
    }
  }

  async selectImage() {
    const actionSheet = await this.actionSheetController.create({
      header: 'Select Image source',
      buttons: [
        {
          text: 'Carregar da Galeria',
          handler: () => {
            this.takePicture(this.camera.PictureSourceType.PHOTOLIBRARY);
          }
        },
        {
          text: 'Usar a Camera',
          handler: () => {
            this.takePicture(this.camera.PictureSourceType.CAMERA);
          }
        },
        {
          text: 'Cancelar',
          role: 'cancel'
        }
      ]
    });
    await actionSheet.present();
  }

  takePicture(sourceType: PictureSourceType) {
    const options: CameraOptions = {
      quality: 100,
      sourceType,
      saveToPhotoAlbum: false,
      correctOrientation: true
    };
    // this.camera.getPicture(options)
    //   .then(imagePath => {
    //     const currentName = imagePath.substr(imagePath.lastIndexOf('/') + 1);
    //     const correctPath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
    //     this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
    //   });
    this.camera.getPicture(options).then(imagePath => {
      if (this.platform.is('android') && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY) {
        this.filePath.resolveNativePath(imagePath)
          .then((filePath: string) => {
            const correctPath = filePath.substr(0, filePath.lastIndexOf('/') + 1);
            const currentName = imagePath.substring(imagePath.lastIndexOf('/') + 1, imagePath.lastIndexOf('?'));
            this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
          });
      } else {
        const currentName = imagePath.substr(imagePath.lastIndexOf('/') + 1);
        const correctPath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
        this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
      }
    });
  }

  copyFileToLocalDir(namePath: any, currentName: any, newFileName: any) {
    this.file.copyFile(namePath, currentName, this.file.dataDirectory, newFileName).then(_ => {
      this.updateStorageImage(newFileName);
    }, error => {
      this.presentToast('Erro ao carregar o arquivo', 2000);
    });
  }

  createFileName() {
    const d = new Date(),
      n = d.getTime(),
      newFilename = n + '.jpg';
    return newFilename;
  }

  updateStorageImage(name: any) {
    this.storage.get(STORAGE_KEY).then(images => {
      const arr = JSON.parse(images);
      if (!arr) {
        const newImages = [name];
        this.storage.set(STORAGE_KEY, JSON.stringify(newImages));
      } else {
        arr.push(name);
        this.storage.set(STORAGE_KEY, JSON.stringify(arr));
      }

      const filePath = this.file.dataDirectory + name;
      const resPath = this.pathForImage(filePath);

      const newEntry = {
        name,
        path: resPath,
        filePath
      };

      this.images = [newEntry, ...this.images];
      this.ref.detectChanges();
    });
  }

  deleteImage(imgEntry: any, position: any) {
    this.images.splice(position, 1);
    this.storage.get(STORAGE_KEY).then(images => {
      const arr = JSON.parse(images);
      const filtered = arr.filter(name => name !== imgEntry.name);
      this.storage.set(STORAGE_KEY, JSON.stringify(filtered));

      const correctPath = imgEntry.filePath.substr(0, imgEntry.filePath.lastIndexOf('/') + 1);

      this.file.removeFile(correctPath, imgEntry.name).then(res => {
        this.presentToast('Arquivo removido.', 2000);
      });
    });
  }

  startUpload(imgEntry: any) {
    this.file.resolveLocalFilesystemUrl(imgEntry.filePath)
      .then(entry => {
        (entry as FileEntry).file(file => this.readFile(file));
      })
      .catch(err => {
        this.presentToast('Erro ao ler o arquivo.', 2000);
      });
  }

  readFile(file: any) {
    console.log(file);
    const reader = new FileReader();
    reader.onloadend = () => {
      const imgBlob = new Blob([reader.result], {
        type: file.type
      });
      const formData = new FormData();
      formData.append('file', imgBlob, file.name);
      this.uploadImageData(formData);
    };
    reader.readAsArrayBuffer(file);
  }

  async uploadImageData(formData: FormData) {
    /* (await this.http.uploadImageData(formData))
       .subscribe(res => {
         ''
         if (res.success) {
           this.presentToast(res.message, 2000);
         } else {
           this.presentToast(res.message, 2000);
         }
       });*/
  }

}

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';

import { HttpClientModule } from '@angular/common/http';
import { File } from '@ionic-native/File/ngx';
import { FileOpener } from '@ionic-native/file-opener/ngx';
import { FileTransfer } from '@ionic-native/file-transfer/ngx';
import { DocumentViewer } from '@ionic-native/document-viewer/ngx';

import { SQLite, SQLiteObject } from '@ionic-native/sqlite/ngx';
import { DatabaseService } from './service/database.service';

import { Keyboard } from '@ionic-native/keyboard/ngx';
import { InAppBrowser } from '@ionic-native/in-app-browser/ngx';

import { AppVersion } from '@ionic-native/app-version/ngx';
import { Geolocation } from '@ionic-native/geolocation/ngx';

import { FCM } from '@ionic-native/fcm/ngx';

import { Clipboard } from '@ionic-native/Clipboard/ngx';


import { IonicStorageModule } from '@ionic/storage';
import { Camera } from '@ionic-native/camera/ngx';
import { WebView } from '@ionic-native/ionic-webview/ngx';
import { FilePath } from '@ionic-native/file-path/ngx';

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    HttpClientModule,
    IonicStorageModule.forRoot(),
  ],
  providers: [
    StatusBar,
    SplashScreen,
    Keyboard,
    AppVersion,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
    File,
    FileOpener,
    // tslint:disable-next-line: deprecation
    FileTransfer,
    DocumentViewer,
    SQLite,
    DatabaseService,
    InAppBrowser,
    Geolocation,
    FCM,
    Clipboard,
    Camera,
    WebView,
    FilePath
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

ionic info

Ionic:

   Ionic CLI                     : 6.2.0 (C:\Users\jonathan.brambati\AppData\Roaming\npm\node_modules\@ionic\cli)
   Ionic Framework               : @ionic/angular 4.11.10
   @angular-devkit/build-angular : 0.803.25
   @angular-devkit/schematics    : 8.1.3
   @angular/cli                  : 8.1.3
   @ionic/angular-toolkit        : 2.0.0

Cordova:

   Cordova CLI       : 9.0.0 ([email protected])
   Cordova Platforms : android 8.1.0
   Cordova Plugins   : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 4.1.3, (and 16 other plugins)  

Utility:

   cordova-res : 0.9.0
   native-run  : 0.3.0

System:

   Android SDK Tools : 26.1.1 (C:\Users\jonathan.brambati\AppData\Local\Android\Sdk)
   NodeJS            : v12.16.0 (C:\Program Files\nodejs\node.exe)
   npm               : 6.13.7
   OS                : Windows 10

ios problem

Hello,
in my android app the plugin works fine. For ios the images do not appear and the word undefined is shown.
Can you help me?

Thank you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.