Merge branch 'enad-pre-live' of https://gitlab.com/haroon6138/mohemmionic5 into enad-pre-live
commit
9a70d4faaf
@ -1,13 +1,40 @@
|
||||
<input [id]="attachmentname" type="file" name="attachment" style="display:none" (change)='loadAttachment($event)'
|
||||
accept="image/*,video/*,audio/*">
|
||||
<ion-button (click)="openFile()" slot="end" expand="block" fill="outline">
|
||||
<ion-icon name="attach" slot="start"></ion-icon>
|
||||
{{'general,select-attachment' | translate}}
|
||||
</ion-button>
|
||||
<!-- <two-option-select (selected)="switchOptions($event)" [option1]="ts.trPK('settings','file')" [option2]="ts.trPK('settings','camera')"
|
||||
[isOption1]="true"></two-option-select> -->
|
||||
|
||||
<div *ngIf="inputFiles.length>0" class="uploader-icons">
|
||||
<ion-item *ngFor="let file of inputFiles; let i = index" lines="none">
|
||||
<p slot="start"> <img [src]="attachmentImg" /> {{file.name}}</p>
|
||||
<p slot="end"><img [src]="deleteImg" (click)="deleteFiles(i)"></p>
|
||||
</ion-item>
|
||||
</div>
|
||||
<!-- <input [id]="attachmentname" type="file" name="attachment" style="display:none" (change)='loadAttachment($event)'
|
||||
accept="jpg, jpeg, png, gif, pdf, doc, docx"> -->
|
||||
<ion-button (click)="openFile()" slot="end" expand="block" fill="outline" class="uploader">
|
||||
<ion-icon name="attach" slot="start" ></ion-icon>
|
||||
{{'general,select-attachment' | translate}}
|
||||
</ion-button>
|
||||
|
||||
<!-- <div class="uploader-icons">
|
||||
<ion-item lines="none">
|
||||
<p slot="start" class="file-name"> <img [src]="attachmentImg" /> {{file.name}}</p>
|
||||
<p slot="end" class="delete-cont"><img [src]="deleteImg" (click)="deleteFiles(i)"></p>
|
||||
</ion-item>
|
||||
</div> -->
|
||||
|
||||
<ion-slides>
|
||||
<ion-slide>
|
||||
<ion-grid class=" gridAH" *ngIf="inputFiles.length>0">
|
||||
|
||||
<ion-row>
|
||||
<ion-col lines="none" size="3" *ngFor="let file of inputFiles; let i = index">
|
||||
<div class="image-container">
|
||||
<div class="uploaded">
|
||||
<div class="closed" (click)="deleteFiles(i)">X</div>
|
||||
<img [src]="getImgContent(file.data) " />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ion-col>
|
||||
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-slide>
|
||||
</ion-slides>
|
||||
|
||||
<div *ngIf="errorMsg" class="error">
|
||||
{{errorMsg}}
|
||||
</div>
|
||||
@ -1,100 +1,288 @@
|
||||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { CommonService } from 'src/app/hmg-common/services/common/common.service';
|
||||
import { TranslatorService } from 'src/app/hmg-common/services/translator/translator.service';
|
||||
import { AlertController } from '@ionic/angular';
|
||||
import { Component, OnInit, Input, Output, EventEmitter, NgZone } from "@angular/core";
|
||||
import { CommonService } from "src/app/hmg-common/services/common/common.service";
|
||||
import { TranslatorService } from "src/app/hmg-common/services/translator/translator.service";
|
||||
import { AlertController, ActionSheetController, Platform } from "@ionic/angular";
|
||||
import {
|
||||
Camera,
|
||||
CameraOptions,
|
||||
PictureSourceType
|
||||
} from "@ionic-native/Camera/ngx";
|
||||
import { FileChooser } from "@ionic-native/file-chooser/ngx";
|
||||
import { File } from "@ionic-native/file/ngx";
|
||||
import { FilePath } from "@ionic-native/file-path/ngx";
|
||||
import { Base64 } from "@ionic-native/base64/ngx";
|
||||
import { IOSFilePicker } from '@ionic-native/file-picker/ngx';
|
||||
import { Location } from '@angular/common';
|
||||
import { DomSanitizer, SafeUrl } from "@angular/platform-browser";
|
||||
|
||||
|
||||
export interface CustomWindow extends Window {
|
||||
File: any;
|
||||
FileReader: any;
|
||||
}
|
||||
declare let window: CustomWindow;
|
||||
|
||||
@Component({
|
||||
selector: 'file-uploader',
|
||||
templateUrl: './file-uploader.component.html',
|
||||
styleUrls: ['./file-uploader.component.scss']
|
||||
selector: "file-uploader",
|
||||
templateUrl: "./file-uploader.component.html",
|
||||
styleUrls: ["./file-uploader.component.scss"]
|
||||
})
|
||||
export class FileUploaderComponent implements OnInit {
|
||||
@Input() multiupload = false;
|
||||
@Input() attachmentname = 'attachment-loader';
|
||||
@Input() attachmentname = "attachment-loader";
|
||||
public attachmentData: string;
|
||||
@Input() maxFileSize = 10 * 1024 * 1024;
|
||||
public errorMsg: string;
|
||||
public selectedOpn: number = 1;
|
||||
public allowdType: any = ["jpg", "jpeg", "png", "gif", "pdf", "doc", "docx"];
|
||||
@Input() maxFileSize = 5 * 1024 * 1024;
|
||||
@Output() fileSelected = new EventEmitter();
|
||||
public inputFiles: any = [];
|
||||
public attachmentImg = 'assets/icon/attachment.png';
|
||||
public deleteImg = 'assets/icon/delete.png';
|
||||
public attachmentImg = "assets/icon/attachment.png";
|
||||
public deleteImg = "assets/icon/delete.png";
|
||||
public nativePath: any;
|
||||
public actionSheet: any;
|
||||
public isActionSheetShown: boolean = false;
|
||||
@Input() selectedAttachment = [];
|
||||
constructor(
|
||||
public cs: CommonService,
|
||||
public ts: TranslatorService,
|
||||
public alertController: AlertController
|
||||
) {
|
||||
}
|
||||
public alertController: AlertController,
|
||||
private cameraController: Camera,
|
||||
private actionSheetController: ActionSheetController,
|
||||
private fileChooser: FileChooser,
|
||||
private file: File,
|
||||
private filePath: FilePath,
|
||||
public base64: Base64,
|
||||
public platform: Platform,
|
||||
private iOSfilePicker: IOSFilePicker,
|
||||
public ngzone: NgZone,
|
||||
public loc: Location,
|
||||
public sanitizer: DomSanitizer
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.platform.backButton.subscribeWithPriority(9999, () => {
|
||||
// You decide what happens
|
||||
if (this.isActionSheetShown)
|
||||
this.actionSheet.dismiss();
|
||||
else
|
||||
this.loc.back();
|
||||
});
|
||||
this.inputFiles = this.selectedAttachment;
|
||||
}
|
||||
|
||||
|
||||
public loadAttachment(changeEvent) {
|
||||
const fileInput = this.getFileElement();
|
||||
if (this.isFileSupported()) {
|
||||
if (fileInput.files != null && fileInput.files.length > 0) {
|
||||
const file = fileInput.files[0];
|
||||
const reader = new FileReader();
|
||||
if (file.size <= this.maxFileSize) {
|
||||
reader.onload = (data) => {
|
||||
if (this.multiupload) {
|
||||
this.inputFiles.push({name: file.name, data: data.target['result']});
|
||||
} else {
|
||||
this.inputFiles = [{name: file.name, data: data.target['result']}];
|
||||
}
|
||||
this.fileSelected.emit( {
|
||||
name: file.name ,
|
||||
data: data.target['result'],
|
||||
inputFiles: this.inputFiles
|
||||
});
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
this.attachmentData = null;
|
||||
changeEvent.target.value = ''; // remove current selection
|
||||
this.showFileExceededMaxSize();
|
||||
}
|
||||
} else {
|
||||
this.attachmentData = null;
|
||||
}
|
||||
}
|
||||
ngOnDestroy(): void {
|
||||
}
|
||||
async openFile() {
|
||||
if (this.platform.is('ios'))
|
||||
this.openiOSActionSheet();
|
||||
else
|
||||
this.openAndroidActionSheet();
|
||||
//this.openiOSActionSheet();
|
||||
|
||||
private isFileSupported() {
|
||||
return (window.FileReader && window.File);
|
||||
}
|
||||
async openAndroidActionSheet() {
|
||||
this.actionSheet = await this.actionSheetController.create({
|
||||
header: this.ts.trPK("itemforsale", "slect-source-file"), //"Select Image file",
|
||||
|
||||
private showFileExceededMaxSize() {
|
||||
this.cs.presentConfirmDialog(
|
||||
this.ts.trPK('general', 'large-file'),
|
||||
() => {
|
||||
this.openFile();
|
||||
},
|
||||
() => {
|
||||
}
|
||||
);
|
||||
buttons: [
|
||||
{
|
||||
text: this.ts.trPK("itemforsale", "from-library"),
|
||||
handler: () => {
|
||||
this.takePictureiOS();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: this.ts.trPK("itemforsale", "from-camera"),
|
||||
handler: () => {
|
||||
this.takePicture(this.cameraController.PictureSourceType.CAMERA);
|
||||
}
|
||||
},
|
||||
{
|
||||
text: this.ts.trPK("general", "cancel"),
|
||||
role: "cancel"
|
||||
}
|
||||
]
|
||||
});
|
||||
this.isActionSheetShown = true;
|
||||
await this.actionSheet.present();
|
||||
}
|
||||
|
||||
private getFileElement(): HTMLInputElement {
|
||||
return document.getElementById(this.attachmentname) as HTMLInputElement;
|
||||
async openiOSActionSheet() {
|
||||
this.actionSheet = await this.actionSheetController.create({
|
||||
header: this.ts.trPK("itemforsale", "slect-source-file"), //"Select Image file",
|
||||
buttons: [
|
||||
{
|
||||
text: this.ts.trPK("itemforsale", "from-library"),
|
||||
handler: () => {
|
||||
this.takePictureiOS();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: this.ts.trPK("itemforsale", "from-camera"),
|
||||
handler: () => {
|
||||
this.takePicture(this.cameraController.PictureSourceType.CAMERA);
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
text: this.ts.trPK("itemforsale", "from-icloud"),
|
||||
handler: () => {
|
||||
this.takePicture(this.cameraController.PictureSourceType.PHOTOLIBRARY);
|
||||
}
|
||||
},
|
||||
{
|
||||
text: this.ts.trPK("general", "cancel"),
|
||||
role: "cancel"
|
||||
}
|
||||
]
|
||||
});
|
||||
this.isActionSheetShown = true;
|
||||
await this.actionSheet.present();
|
||||
}
|
||||
|
||||
public openFile() {
|
||||
const fileInput = this.getFileElement();
|
||||
fileInput.click();
|
||||
public takePictureiOS() {
|
||||
const options: CameraOptions = {
|
||||
quality: 60,
|
||||
sourceType: this.cameraController.PictureSourceType.PHOTOLIBRARY,
|
||||
destinationType: this.cameraController.DestinationType.DATA_URL,
|
||||
encodingType: this.cameraController.EncodingType.JPEG,
|
||||
mediaType: this.cameraController.MediaType.PICTURE,
|
||||
correctOrientation: true,
|
||||
}
|
||||
this.cameraController.getPicture(options).then((imageData) => {
|
||||
const data = "data:image/jpeg;base64," + imageData;
|
||||
this.pushFiles(this.getFileName(), data);
|
||||
}, (err) => {
|
||||
});
|
||||
}
|
||||
|
||||
public deleteFiles(index: number) {
|
||||
this.inputFiles.splice(index, 1);
|
||||
this.fileSelected.emit( {
|
||||
this.fileSelected.emit({
|
||||
name: null,
|
||||
data: '',
|
||||
data: "",
|
||||
inputFiles: this.inputFiles
|
||||
});
|
||||
this.errorMsg = null;
|
||||
}
|
||||
public switchOptions($event) {
|
||||
this.selectedOpn = $event;
|
||||
}
|
||||
public takePicture(sourceType: PictureSourceType) {
|
||||
const options: CameraOptions = {
|
||||
quality: 50,
|
||||
destinationType: this.cameraController.DestinationType.DATA_URL,
|
||||
encodingType: this.cameraController.EncodingType.JPEG,
|
||||
sourceType: sourceType,
|
||||
mediaType: this.cameraController.MediaType.PICTURE,
|
||||
correctOrientation: true
|
||||
};
|
||||
if (sourceType === this.cameraController.PictureSourceType.PHOTOLIBRARY) {
|
||||
if (this.platform.is('android')) {
|
||||
this.fileChooser
|
||||
.open()
|
||||
.then(uri => {
|
||||
this.readFile(uri);
|
||||
})
|
||||
.catch(e => { });
|
||||
} else {
|
||||
this.iOSfilePicker.pickFile(['public.content']).then(uri => {
|
||||
|
||||
let correctPath = uri.substr(0, uri.lastIndexOf('/') + 1);
|
||||
let currentName = uri.substring(uri.lastIndexOf('/') + 1);
|
||||
this.nativePath = uri;
|
||||
|
||||
this.file.readAsDataURL("file:///" + correctPath, currentName).then(result => {
|
||||
this.pushFiles(currentName, result);
|
||||
}).catch(e => { });
|
||||
}).catch(e => { });
|
||||
}
|
||||
} else {
|
||||
this.cameraController.getPicture(options).then(imageData => {
|
||||
const data = "data:image/jpeg;base64," + imageData;
|
||||
this.pushFiles(this.getFileName(), data);
|
||||
});
|
||||
}
|
||||
}
|
||||
pushFiles(name, files) {
|
||||
this.ngzone.run(() => {
|
||||
if (this.multiupload) {
|
||||
this.inputFiles.push({ name: name, data: files });
|
||||
} else {
|
||||
this.inputFiles = [{ name: name, data: files }];
|
||||
}
|
||||
this.fileSelected.emit({
|
||||
name: name,
|
||||
data: files,
|
||||
inputFiles: this.inputFiles
|
||||
});
|
||||
});
|
||||
}
|
||||
readFile(fileUrl: any) {
|
||||
this.filePath.resolveNativePath(fileUrl).then(filePathResult => {
|
||||
this.nativePath = filePathResult;
|
||||
this.file.resolveLocalFilesystemUrl(this.nativePath).then(entry => {
|
||||
entry.getMetadata(metadata => {
|
||||
if (metadata.size <= this.maxFileSize) {
|
||||
this.errorMsg = null;
|
||||
this.encodeFiles(entry);
|
||||
} else {
|
||||
this.errorMsg = this.ts.trPK("general", "large-file");
|
||||
}
|
||||
}, (error) => {
|
||||
console.log(error)
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
getImgContent(imgFile, data): SafeUrl {
|
||||
console.log(imgFile);
|
||||
return this.sanitizer.bypassSecurityTrustUrl(imgFile);
|
||||
}
|
||||
|
||||
checkDuplicate(name: string) {
|
||||
return this.inputFiles.filter(a => {
|
||||
return a.name === name;
|
||||
});
|
||||
}
|
||||
encodeFiles(entry) {
|
||||
let fileName = entry.nativeURL.split('/').pop();
|
||||
let path = entry.nativeURL.substring(0, entry.nativeURL.lastIndexOf("/") + 1);
|
||||
|
||||
this.file.readAsDataURL(path, fileName)
|
||||
.then(base64File => {
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('Error reading file', err);
|
||||
})
|
||||
this.base64.encodeFile(this.nativePath).then(
|
||||
(base64File: string) => {
|
||||
const type = this.nativePath.substr(
|
||||
this.nativePath.lastIndexOf(".") + 1
|
||||
);
|
||||
if (this.allowdType.includes(type.toLowerCase())) {
|
||||
if (this.checkDuplicate(entry.name).length === 0) {
|
||||
this.pushFiles(entry.name, base64File);
|
||||
this.errorMsg = null;
|
||||
} else {
|
||||
this.errorMsg = this.ts.trPK("general", "file-name-exist");
|
||||
}
|
||||
} else {
|
||||
this.attachmentData = null;
|
||||
this.errorMsg = this.ts.trPK("general", "not-supported");
|
||||
}
|
||||
},
|
||||
err => {
|
||||
console.log(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
getFileName() {
|
||||
const date = new Date().valueOf();
|
||||
let text = "";
|
||||
const possibleText =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for (let i = 0; i < 5; i++) {
|
||||
text += possibleText.charAt(
|
||||
Math.floor(Math.random() * possibleText.length)
|
||||
);
|
||||
}
|
||||
const imageName = date + "." + text + ".jpeg";
|
||||
return imageName;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
<app-generic-header
|
||||
showImage="false"
|
||||
showBack="false"
|
||||
navigate="false"
|
||||
backlink="false"
|
||||
[headerText]="'general,filter-offers' | translate">
|
||||
</app-generic-header>
|
||||
|
||||
|
||||
<ion-content>
|
||||
<div class="container-icon" *ngIf="categories.length>0">
|
||||
|
||||
<ion-item lines="none" *ngFor="let key of categories" (click)="filterOffers(key)" [ngClass]="{'active':activeClass==key.title }">
|
||||
<ion-label *ngIf="direction =='ltr'">
|
||||
{{key.title}}
|
||||
</ion-label>
|
||||
<ion-label *ngIf="direction =='rtl'">
|
||||
{{key.title_ar}}
|
||||
</ion-label>
|
||||
<ion-thumbnail slot="start">
|
||||
<div class="top-filter" [innerHTML]="key.content | sanitizeHTMLPipe"></div>
|
||||
</ion-thumbnail>
|
||||
</ion-item>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<ion-footer >
|
||||
<div class="centerDiv">
|
||||
<ion-button class="footer-button" ion-button (click)="applyFilters()">
|
||||
{{ts.trPK('general','apply-filters')}} </ion-button>
|
||||
|
||||
</div>
|
||||
</ion-footer>
|
||||
</ion-content>
|
||||
@ -0,0 +1,38 @@
|
||||
ion-label{
|
||||
font-size: 14px !important;
|
||||
}
|
||||
ion-thumbnail img{
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 10px;
|
||||
}
|
||||
.active::before{
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 15px;
|
||||
padding: 0px;
|
||||
background: #3cc353;
|
||||
padding: 3px 2px 1px 3px;
|
||||
border-radius: 60%;
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
content: '✓';
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
z-index: 2;
|
||||
}
|
||||
ion-item{
|
||||
border-bottom: 1px solid #ccc;
|
||||
--padding-start: 0px;
|
||||
margin: 0 20px 4px 20px;
|
||||
}
|
||||
|
||||
.footer-button{
|
||||
background: var(--newgreen)!important;border-radius: 10px; --background: transparent;
|
||||
width: 80%;
|
||||
}
|
||||
ion-footer{
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FilterComponent } from './filter.component';
|
||||
|
||||
describe('FilterComponent', () => {
|
||||
let component: FilterComponent;
|
||||
let fixture: ComponentFixture<FilterComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ FilterComponent ],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FilterComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,56 @@
|
||||
import { AfterViewInit, Component, OnInit } from '@angular/core';
|
||||
import { CommonService } from 'src/app/hmg-common/services/common/common.service';
|
||||
import { TranslatorService } from 'src/app/hmg-common/services/translator/translator.service';
|
||||
import { ModalController } from '@ionic/angular';
|
||||
import { OfferDiscountService } from 'src/app/offersdiscount/services/service';
|
||||
import { ItemForSaleService } from '../services/service.service';
|
||||
@Component({
|
||||
selector: 'app-filter',
|
||||
templateUrl: './filter.component.html',
|
||||
styleUrls: ['./filter.component.scss'],
|
||||
})
|
||||
export class FilterComponent implements AfterViewInit {
|
||||
|
||||
segment: any = '1';
|
||||
categoriesObj: any;
|
||||
categories: any = [];
|
||||
offersData: any = [];
|
||||
activeClass: any;
|
||||
tempSearch: any = [];
|
||||
searchText: String;
|
||||
public activeKey = {}
|
||||
direction: any;
|
||||
|
||||
constructor(public ts: TranslatorService, public modalController: ModalController, public cs: CommonService, public offersService: OfferDiscountService) { }
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.direction = TranslatorService.getCurrentDirection();
|
||||
this.categories = this.cs.sharedService.getSharedData(OfferDiscountService.categories, false);
|
||||
|
||||
|
||||
// this.getOfferDiscount();
|
||||
}
|
||||
|
||||
|
||||
openDetails(offer) {
|
||||
// this.cs.sharedService.setSharedData(offer, OfferDiscountService.selected_offers);
|
||||
|
||||
// var related = this.offersData.filter((res) => res.rowID != offer.rowID);
|
||||
// this.cs.sharedService.setSharedData(related, OfferDiscountService.related_offers);
|
||||
|
||||
// this.cs.navigateForward('/offersdiscount/offer-details');
|
||||
}
|
||||
|
||||
|
||||
filterOffers(key) {
|
||||
this.activeKey = key
|
||||
this.activeClass = key.title;
|
||||
|
||||
}
|
||||
|
||||
|
||||
applyFilters() {
|
||||
this.cs.sharedService.setSharedData(this.activeKey, ItemForSaleService.selected_filters);
|
||||
this.cs.back();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
<svg height="512" viewBox="0 0 32 32" width="512" xmlns="http://www.w3.org/2000/svg"><g id="More_Select" data-name="More Select"><path d="m30 1h-24a1 1 0 0 0 -1 1v1h21a3 3 0 0 1 3 3v21h1a1 1 0 0 0 1-1v-24a1 1 0 0 0 -1-1z"/><path d="m26 5h-24a1 1 0 0 0 -1 1v24a1 1 0 0 0 1 1h24a1 1 0 0 0 1-1v-24a1 1 0 0 0 -1-1zm-4.747 9.344-8.728 8.726a1 1 0 0 1 -1.414 0l-4.364-4.363a1 1 0 0 1 1.414-1.414l3.657 3.656 8.021-8.019a1 1 0 0 1 1.414 1.414z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 449 B |
Loading…
Reference in New Issue