Ionic 2 / Ionic 3 / Ionic 4 : (Lazy) Loading spinner for pictures - mobile

I'm using ion-img in my ionic2 application to load my pictures correctly. However, I wonder if there is a way to indicate to the user that the picture is actually loading.
Thank you for your help!
EDIT : Here is the answer if you absolutely need to use the ion-img tag. If not, you should use ionic-image-loader as AdminDev826 suggested.
I finally solved that problem with CSS! When an image is loading in ionic 2, the ion-img tag doesn't have any class. However, when the image is finally loaded, the ion-img tag get the class "img-loaded".
Here is my solution :
<ion-img [src]="img.src"></ion-img>
<ion-spinner></ion-spinner>
And my CSS :
.img-loaded + ion-spinner {
display:none;
}
I hope it can help someone!

I finally solved that problem with CSS! When an image is loading in ionic 2, the ion-img tag doesn't have any class. However, when the image is finally loaded, the ion-img tag get the class "img-loaded".
Here is my solution :
<ion-img [src]="img.src"></ion-img>
<ion-spinner></ion-spinner>
And my CSS :
.img-loaded + ion-spinner {
display:none;
}
I hope it can help someone!

If you want to use the img tag instead of ion-img here is the solution:
<img src="{{image.src}}" (load)="loaded = true" [ngClass]="{'img-loaded':loaded}" [hidden]="!loaded" *ngIf="image_exists" />
<ion-spinner [ngClass]="{'center':true}" *ngIf="!loaded"></ion-spinner>
In your CSS file you should write the following:
.img-loaded + ion-spinner {
display:none;
}
// .center in my case to make the spinner at the center
.center{
margin-left: auto;
margin-right: auto;
display: block;
}
loaded is a boolean variable with false default value you have to define in your component.

Please use ionic-image-loader plugin
Install the NPM Package
npm install --save ionic-image-loader
Install Required Plugins
npm i --save #ionic-native/file
ionic plugin add cordova-plugin-file --save
npm i --save #ionic-native/transfer
ionic plugin add cordova-plugin-file-transfer --save
Import IonicImageLoader module
Add IonicImageLoader.forRoot() in your app's root module
import { IonicImageLoader } from 'ionic-image-loader';
// import the module
#NgModule({
...
imports: [
IonicImageLoader.forRoot()
]
})
export class AppModule {}
Then add IonicImageLoader in your child/shared module(s)
import { IonicImageLoader } from 'ionic-image-loader';
#NgModule({
...
imports: [
IonicImageLoader
]
})
export class SharedModule {}

Your solution is not the best one because the app still downloads all the images, For example in a Facebook like app, You will be downloading all the images from the Feed to your app, This will make everything super slow.
Use this:
https://github.com/NathanWalker/ng2-image-lazy-load

ionic-image-loader not works in ionic4+. You must create a component:
HTML
<ion-spinner name="dots" [hidden]="viewImage" color="primary"></ion-spinner>
<ion-img #image alt=""(ionImgDidLoad)="loadImage()" (ionError)="errorLoad()"></ion-img>
Typescript
#Component({
selector: 'preloader-img',
templateUrl: './preloader-img.component.html',
styles: [`
ion-spinner {
display: block;
margin: auto;
}
`],
})
export class PreloaderImgComponent implements AfterViewInit {
viewImage = false;
#Input() url: string;
#ViewChild('image', { static: false }) imageRef: IonImg;
ngAfterViewInit() {
this.imageRef.src = this.url;
}
loadImage() {
this.viewImage = true;
}
errorLoad() {
this.imageRef.src = '<your_default_img>';
}
}

Related

I'm having this weird webpack.cache.PackageCacheStrategy

Below is the error on my console
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info - Using webpack 5. Reason: no custom webpack configuration in next.config.js https://nextjs.org/docs/messages/webpack5
warn - You have enabled the JIT engine which is currently in preview.
warn - Preview features are not covered by semver, may introduce breaking changes, and can change at any time.
<w> [webpack.cache.PackFileCacheStrategy] Skipped not serializable cache item 'Compilation/modules|C:\Users\J.Andrew\Documents\WebDev\nextjs-boilerplate\node_modules\next\dist\compiled\css-loader\cjs.js??ruleSet[1].rules[2].oneOf[7].use[1]!C:\Users\J.Andrew\Documents\WebDev\nextjs-boilerplate\node_modules\next\dist\compiled\postcss-loader\cjs.js??ruleSet[1].rules[2].oneOf[7].use[2]!C:\Users\J.Andrew\Documents\WebDev\nextjs-boilerplate\node_modules\next\dist\compiled\resolve-url-loader\index.js??ruleSet[1].rules[2].oneOf[7].use[3]!C:\Users\J.Andrew\Documents\WebDev\nextjs-boilerplate\node_modules\next\dist\compiled\sass-loader\cjs.js??ruleSet[1].rules[2].oneOf[7].use[4]!C:\Users\J.Andrew\Documents\WebDev\nextjs-boilerplate\styles\globals.scss': No serializer registered for CssSyntaxError
<w> while serializing webpack/lib/cache/PackFileCacheStrategy.PackContentItems -> webpack/lib/NormalModule -> webpack/lib/ModuleBuildError -> CssSyntaxError
error - ./styles/globals.scss:1:1
Syntax error: Unknown word
wait - compiling...
error - ./styles/globals.scss:1:1
Syntax error: Unknown word
Here is global.scss mentioned in the error. When I try to removed the tailwind imports, it compiles without a problem. But I needed those in order for tailwind to work.
#import '~tailwindcss/base';
#import '~tailwindcss/components';
#import '~tailwindcss/utilities';
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
a {
color: inherit;
text-decoration: none;
}
* {
box-sizing: border-box;
}
My tailwind.config.js
module.exports = {
mode: 'jit',
purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
darkMode: false, // or 'media' or 'class'
important: true,
theme: {
container: {
center: true,
padding: '1.5rem',
},
extend: {
colors: {
// 'nav-bg': '#383E4C',
},
},
},
variants: {
extend: {},
},
plugins: [require('#tailwindcss/forms')],
}
And my postcss.config.js which is default
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Please help...
Today I had the same problem. My code was working just fine, until I created a React component that had a function that uses querySelector, something like this:
const handleSomething = () => {
const x = 150;
let activeSlide = document.querySelector('.slide');
activeSlide.classList.add(`-translate-x-[${x}]`);
}
It seemed that the -translate-x-[${x}] statement was causing the bug. However, after removing this line, the problem didn't go away. I tried to delete the "node_modules" and ".next" folders and reinstall the dependencies, but nothing seemed to work.
I don't know what caused it, but the only way I could get the application to run again was to go back to the previous commit (with a git reset --hard HEAD - WARNING: be careful with this command because you loose all uncommitted changes, but that was my intention) and delete that component (the file itself). Even a simple copy and paste of the contents of this file, with most of the "weird" lines commented out (this function, basically), would make the error come back. Literally nothing else seemed to work for me.
It probably doesn't answer your question, but I hope it can help someone who is facing the same problem, until no better solution comes up.
As Renato mentioned in his answer, it seems dynamically constructing tailwind class names returns this error.
This is explained in the tailwind docs here:
Dynamic class names
As outlined in Class detection in-depth, Tailwind doesn’t actually run your source code and won’t detect dynamically constructed class names.
❌ Don't construct class names dynamically
<div class="text-{{ error ? 'red' : 'green' }}-600"></div>
✔️ Always use complete class names
<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>
Also from this documentation about how tailwind detects CSS class names:
The most important implication of how Tailwind extracts class names is that it will only find classes that exist as complete unbroken strings in your source files.
If you use string interpolation or concatenate partial class names together, Tailwind will not find them and therefore will not generate the corresponding CSS
Therefore to dynamically set a CSS property of an element, using the inline style provided by React.js would be the best way to do it. For example:
const divStyle = {
color: 'blue',
backgroundImage: 'url(' + imgUrl + ')',
};
function HelloWorldComponent() {
return <div style={divStyle}>Hello World!</div>;
}
I had a similar issue that happened when I tried to add a preview of the filed I just choosed.
For that I used the URL object like that :
image.src = URL.createObjectURL(picture)
I just remove this part of my component the error was gone.

How to hide jitsi watermark in reactjs

i'm using react-jitsi library for rendering jitsi video
var interfaceConfig = {
SHOW_BRAND_WATERMARK: true,
SHOW_WATERMARK_FOR_GUESTS: false,
};
<Jitsi
// doamin="meet.jit.si"
roomName={'12345rfewhgresjttyi'}
displayName={'prakash'}
password={password}
interfaceConfig={interfaceConfig}
/>
i tried to hide jisti watermark in background using interfaceConfig. but interface config doesn't affect any UI.
Also i tried with css:
.leftwatermark {
display: none;
}
This is also not working.
i referred this link for hide watermark
Is there any way to hide the jitsi watermark using reactjs?
SHOW_BRAND_WATERMARK and SHOW_WATERMARK_FOR_GUESTS can not be overwrite by the client and must be in the server config
You must edit the file interface_config.js
sudo nano /usr/share/jitsi-meet/interface_config.js
And switch to
SHOW_BRAND_WATERMARK: false,
SHOW_WATERMARK_FOR_GUESTS: false,
then, save your file, and restart your browser page.
Be careful, this file can be reset to default when your upgrade Jitsi on your server. The fix is already asked in the roadmap.
there is no any way of removing the jitsi watermark.
but you can remove the link behind it.
If you need to hide the watermark of the Jitsi meet by using iFrame API, what you have to do is to override these attributes which include in the interface_config.js
SHOW_JITSI_WATERMARK: false,
HIDE_DEEP_LINKING_LOGO: true,
SHOW_BRAND_WATERMARK: false,
SHOW_WATERMARK_FOR_GUESTS: false
const options = {
...
configOverwrite: { startWithAudioMuted: true },
interfaceConfigOverwrite: { DISABLE_DOMINANT_SPEAKER_INDICATOR: true },
...
};
const api = new JitsiMeetExternalAPI(domain, options);
you can change the background-image link in css like below
.leftwatermark {
left: 32px;
top: 32px;
background-position: center left;
background-image: url(your-image-url); } // better view

FullCalendar React header custom buttons not showing

I'm trying to add some icons to the header as buttons, I've tried using both bootstrap and fontawesome as mentioned in the docs but I get an empty square instead of the icon. When using the bootstrap theme I get 'undefined', when using the standard I get the below.
Here's my code:
const customButtons = {
custom1: {
icon: "fa-times",
click: function() {
alert('test');
}
}
}
<CustomCalendar
customCalendarRef={customCalendarRef}
select={(e: any) => processClick(e)}
customButtons={customButtons}
themeSystem="standard"
header={{
right: '',
center: '',
left: 'prev,next today custom1'
}}
/>
Result:
How can I show an icon as a button in the header?
I'm also using fullcalendar in my react app so I've tried using your code. First there's one thing you forgot, wich is fontawesome icons also needs the "fa" class, so the correct would be fa fa-times, not only fa-times.
But then there's another issue which is the icon comes with custom fullcalendar classes when rendered:
So a solution you might use is to add this to your css somewhere:
.fc-icon.fa {
font: normal normal normal 14px/1 FontAwesome !important;
}
It worked for me:
Edited:
The string of the fontawesome classes should start with a blank space otherwise the 'fa' class will concatenate with the fullcalendar class. So: icon: ' fa fa-times'

CKEditorError: ckeditor-duplicated-modules: Some CKEditor 5 modules are duplicated

import CKEditor from '#ckeditor/ckeditor5-react';
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
import Base64UploadAdapter from '#ckeditor/ckeditor5-upload/src/adapters/base64uploadadapter';
Getting ckeditor 5 duplicate modules error. Anyone can help me.
Thanks in Advance.
It's because you are importing the plugin with the build !
In order to add plugins, you have to make a personnal build. Please read this page to know more about it : ckeditor offical documentation.
They even have an official online builder that does all the work for you ! : ckeditor online builder
Once you created it, you have to import the editor just as you have done before on line 2 but instead of writing from "#ckeditor/ckeditor5-build-classic" you have to write from "adress of the build folder of your personnal build".
I hope it helped you.
I had this problem when I tried to add CKEditor and a plugin separately.
the easiest way is go to CKEditor Online Builder and choose what plugins and toolbar items you need then after five steps the code that you need to work with is generated.
Then you can use the file named ckeditor.js in build folder and this is almost all that you need.
1- Add CKEditorModule
#NgModule({
imports: [CKEditorModule],
...
}
2- Add the CKEditor tag to your template
<ckeditor
[editor]="Editor"
[(ngModel)]="notification.body"
(ready)="onReady($event)"
[config]="config"
></ckeditor>
3- import the customized CKEditor js file(that you should copy from build folder in downloaded customized CKEditor)in your component
import * as customEditor from './ckeditor';
4- Create a property in your component
public Editor = customEditor;
5- Add your configs
ngOnInit() {
this.config = {
toolbar: {
items: [
'heading',
'|',
'fontSize',
'fontFamily',
'|',
'bold',
'italic',
'underline',
'strikethrough',
'highlight',
'|',
'alignment',
'|',
'numberedList',
'bulletedList',
'|',
'indent',
'outdent',
'|',
'todoList',
'link',
'blockQuote',
'imageUpload',
'insertTable',
'|',
'undo',
'redo'
]
},
language: 'en',
image: {
toolbar: [
'imageTextAlternative',
'imageStyle:full',
'imageStyle:side'
]
},
table: {
contentToolbar: [
'tableColumn',
'tableRow',
'mergeTableCells'
]
},
licenseKey: '',
wordCount: {
onUpdate: stats => {
this.charactersLength = stats.characters
}
}
}
}
That's it :)
NOTE: We don't use #ckeditor/ckeditor5-build-classic any more!
Wrong:
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
Correct:
import ClassicEditor from '#ckeditor/ckeditor5-editor-classic/src/classiceditor';
I had a similar problem. I solved it when I installed all modules of one version
I've face this issue when tried to use an editor on different pages few times.
Tried everything what is written above, nothing helped.
To solve the issue I used a React lazy loading for importing an editor.

Using Font Awesome in ui.bootstrap.rating

How can I use Font Awesome in ui.bootstrap.rating?
I found out, that when I add state-on="'fa-star'" state-off="'fa-star-o'" to and changed class="glyphicon" to class="fa" in ui-bootstrap-tpls it works.
But I guess there is a more custom way to change the class of the icons.
Yeah as you are doing with setting state-off and state-on is their recommended manner. If you are going to have lots of the ratings on a page, I would just create a custom template and over-ride the stock template. Here is a post custom templates
I had Font Awesome and so didnt want to include Glyphicons.
uib.bootstrap Version: 1.3.3 - 2016-05-22 uses limited Glyphicons, so this is what i added to my css
.glyphicon {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.glyphicon-star:before {
content: "\f005";
}
/**
copied from
.fa-star:before {
content: "\f005";
}
*/
.glyphicon-star-empty::before {
content: "\f006";
}
.glyphicon-chevron-right:before {
content: "\f054";
}
.glyphicon-chevron-left:before {
content: "\f053";
}
.glyphicon-chevron-up:before {
content: "\f077";
}
.glyphicon-chevron-down:before {
content: "\f078";
}
i.e. added css from Font Awesome 4.6.3 to appropriate glyphicon names
Now i dont know if this code will break on version of Font Awesome

Resources