I wish I could loop this array of videos and images, how can I do? - arrays

In this demo http://jsfiddle.net/mdz82oLn/ I have inserted videos (IDs) and images (png, jpeg, etc) which are also displayed by means of customized buttons. The demo works perfectly in the vision but reached the end of the last video it returns in loop when instead it should restart from the first video in the list, how to integrate this function?
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
const playerElement = document.querySelector('#player');
const imageElement = document.querySelector('#slide');
const videos = {
'RGpr3Y6Q-1M': 'http://nothingbutgeek.com/wp-content/uploads/2018/06/automata_16x9.png',
'btxdcqLOGuc': 'https://live.staticflickr.com/2400/2078946248_d063d5a563_b.jpg',
'CIx0a1vcYPc': 'https://i.ytimg.com/vi/CIx0a1vcYPc/maxresdefault.jpg',
};
const videoIds = Object.keys(videos);
function onYouTubeIframeAPIReady() {
function onPlayerReady({ target }) {
var playButton = document.getElementById("play-button");
playButton.addEventListener("click", function() {
target.playVideo();
});
var pauseButton = document.getElementById("pause-button");
pauseButton.addEventListener("click", function() {
target.pauseVideo();
});
var next = document.getElementById("next");
next.addEventListener("click", function() {
target.nextVideo();
});
var pre = document.getElementById("previous");
pre.addEventListener("click", function() {
target.previousVideo();
});
target.loadPlaylist({
playlist: videoIds
});
}
function onPlayerStateChange({ data, target }) {
switch(data) {
case YT.PlayerState.ENDED:
target.nextVideo();
break;
case YT.PlayerState.BUFFERING:
const playlist = target.getPlaylist();
const playlistIndex = target.getPlaylistIndex();
const currentId = playlist[playlistIndex];
const image = videos[currentId];
if (imageElement.src !== image) {
imageElement.src = image;
}
break;
}
}
const player = new YT.Player(playerElement, {
height: '405',
width: '720',
playerVars: {
controls: 1,
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}

If I understand correctly you are stuck on last video and want to start the loop from 1 video:
In that case a change like this should work:
var next = document.getElementById("next");
next.addEventListener("click", function() {
target.nextVideo();
if(target.getPlaylistIndex() == videoIds.length -1){
target.loadPlaylist({
playlist: videoIds
});
}
});
Updated your Example
you can also update the switch case like this:
case YT.PlayerState.ENDED: {
if (target.getPlaylistIndex() == videoIds.length - 1) {
target.loadPlaylist({
playlist: videoIds
});
}
break;
}

Related

Drift chat opening in every page

I have drift's async script code in the index.html file of the react app.
<script>
"use strict";
!function () {
var t = window.driftt = window.drift = window.driftt || [];
if (!t.init) {
if (t.invoked) return void (window.console && console.error && console.error("Drift snippet included twice."));
t.invoked = !0, t.methods = ["identify", "config", "track", "reset", "debug", "show", "ping", "page", "hide", "off", "on"],
t.factory = function (e) {
return function () {
var n = Array.prototype.slice.call(arguments);
return n.unshift(e), t.push(n), t;
};
}, t.methods.forEach(function (e) {
t[e] = t.factory(e);
}), t.load = function (t) {
var e = 3e5, n = Math.ceil(new Date() / e) * e, o = document.createElement("script");
o.type = "text/javascript", o.async = !0, o.crossorigin = "anonymous", o.src = "https://js.driftt.com/include/" + n + "/" + t + ".js";
var i = document.getElementsByTagName("script")[0];
i.parentNode.insertBefore(o, i);
};
}
}();
drift.SNIPPET_VERSION = '0.3.1';
drift.load('----api----');
drift.on('ready', api => {
api.widget.hide();
})
</script>
The issue is, it is getting popped up in every page of the app whereas I want it only when I click a button(onClick)
The function to trigger onClick :
openDriftChat = () =>{
const { setDriftState } = this.props;
if (window.drift.api) {
//this needs to happen only once but currently happening on every page load
if (!this.props.driftInit) {
if (localStorage.token) {
var tokenBase64 = localStorage.token.split(".")[1];
var tokenBase64_1 = tokenBase64.replace("-", "+").replace("_", "/");
var token = JSON.parse(window.atob(tokenBase64_1));
window.drift.identify(token.email, {
email: token.email,
nickname: token.name
});
setDriftState(true);
}
}
window.drift.api.openChat();
}
}
I basically want it pop up only when I call the function.
Hello I had the same issue:
To hide the welcome message use the following css code
iframe#drift-widget.drift-widget-welcome-expanded-online {
display: none !important;
}
iframe#drift-widget.drift-widget-welcome-expanded-away {
display: none !important;
}
The welcome message will only be shown when your drift button. Some extra info:
To hide the drift button icon use the following js code
drift.on('ready', function (api) {
api.widget.hide()
drift.on('message', function (e) {
if (!e.data.sidebarOpen) {
api.widget.show()
}
})
drift.on('sidebarClose', function (e) {
if (e.data.widgetVisible) {
api.widget.hide()
}
})
})
To call for the sidebar from a specific button use the following
Javascript
(function () {
var DRIFT_CHAT_SELECTOR = '.drift-open-chat'
function ready(fn) {
if (document.readyState != 'loading') {
fn();
} else if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', fn);
} else {
document.attachEvent('onreadystatechange', function () {
if (document.readyState != 'loading')
fn();
});
}
}
function forEachElement(selector, fn) {
var elements = document.querySelectorAll(selector);
for (var i = 0; i < elements.length; i++)
fn(elements[i], i);
}
function openSidebar(driftApi, event) {
event.preventDefault();
driftApi.sidebar.open();
return false;
}
ready(function () {
drift.on('ready', function (api) {
var handleClick = openSidebar.bind(this, api)
forEachElement(DRIFT_CHAT_SELECTOR, function (el) {
el.addEventListener('click', handleClick);
});
});
});
})();
HTML
<a class="drift-open-chat">Open Chat</a>
I hope this helps someone out there.
PS: The above javascript code must be included after you have initialized your drift widget.
You need to disable that through the application: turn off the Playbooks.
Here is the link to do so: https://app.drift.com/playbooks
Hope it helps.

RecordRTC Extension problematically save a div

Using RecordRTC as an extension and also in my development work. Great work!
Is there a way my site can programatically record a div only, instead of the whole tab?
var myformat = {enableTabCaptureAPI: true, enableSpeakers: true}
if(typeof RecordRTC_Extension === 'undefined') {
alert('RecordRTC chrome extension is either disabled or not installed.');
} else {
var recorder = new RecordRTC_Extension();
//recorder.startRecording(recorder.getSupoortedFormats()[4], function() {
recorder.startRecording(myformat, function() {
setTimeout(function() {
recorder.stopRecording(function(blob) {
console.log(blob.size, blob);
var url = URL.createObjectURL(blob);
invokeSaveAsDialog(blob);
video.src = url;
});
}, 3000);
});
}
You do not need a chrome extension to record a DIV. I'm copying here complete demo that can record a DIV.
Start/Stop buttons:
<button id="btn-start-recording">Start Recording</button>
<button id="btn-stop-recording" disabled>Stop Recording</button>
DIV to be recorded:
<div id="element-to-record">
<input value="type something">
</div>
Optionally a hidden CANVAS:
<canvas id="background-canvas" style="position:absolute; top:-99999999px; left:-9999999999px;"></canvas>
Hidden canvas is used to draw DIV and get webp images. It is till an optional step. You can either append it to he DOM or keep in the memory.
Link RecordRTC and HTML-2-Canvas:
<script src="https://cdn.WebRTC-Experiment.com/RecordRTC.js"></script>
<script src="https://cdn.webrtc-experiment.com/html2canvas.min.js"></script>
Complete javascript code:
var elementToRecord = document.getElementById('element-to-record');
var canvas2d = document.getElementById('background-canvas');
var context = canvas2d.getContext('2d');
canvas2d.width = elementToRecord.clientWidth;
canvas2d.height = elementToRecord.clientHeight;
var isRecordingStarted = false;
var isStoppedRecording = false;
(function looper() {
if(!isRecordingStarted) {
return setTimeout(looper, 500);
}
html2canvas(elementToRecord).then(function(canvas) {
context.clearRect(0, 0, canvas2d.width, canvas2d.height);
context.drawImage(canvas, 0, 0, canvas2d.width, canvas2d.height);
if(isStoppedRecording) {
return;
}
requestAnimationFrame(looper);
});
})();
var recorder = new RecordRTC(canvas2d, {
type: 'canvas'
});
document.getElementById('btn-start-recording').onclick = function() {
this.disabled = true;
isStoppedRecording =false;
isRecordingStarted = true;
recorder.startRecording();
document.getElementById('btn-stop-recording').disabled = false;
};
document.getElementById('btn-stop-recording').onclick = function() {
this.disabled = true;
recorder.stopRecording(function() {
isRecordingStarted = false;
isStoppedRecording = true;
var blob = recorder.getBlob();
// document.getElementById('preview-video').srcObject = null;
document.getElementById('preview-video').src = URL.createObjectURL(blob);
document.getElementById('preview-video').parentNode.style.display = 'block';
elementToRecord.style.display = 'none';
// window.open(URL.createObjectURL(blob));
});
};
ONLINE demo:
https://www.webrtc-experiment.com/RecordRTC/simple-demos/recording-html-element.html

How to add JSON objects to a string of array in my images service dynamically

I have image and file service to take picture i used this for camera functionality https://devdactic.com/how-to-capture-and-store-images-with-ionic/
angular.module('ob3App')
.factory('FileService', function() {
var images;
var IMAGE_STORAGE_KEY = 'images';
function getImages() {
var img = window.localStorage.getItem(IMAGE_STORAGE_KEY);
if (img) {
images = JSON.parse(img);
} else {
images = [];
}
return images;
};
function addImage(img) {
images.push(img);
window.localStorage.setItem(IMAGE_STORAGE_KEY, JSON.stringify(images));
};
return {
storeImage: addImage,
images: getImages
}
})
.factory('ImageService', function($cordovaCamera, FileService, $q, $cordovaFile) {
function makeid() {
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < 5; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
function optionsForType(type) {
var source;
/* switch (type) {
case 0:
source = Camera.PictureSourceType.CAMERA;
break;
case 1:
source = Camera.PictureSourceType.PHOTOLIBRARY;
break;
}*/
return {
destinationType: Camera.DestinationType.FILE_URI,
sourceType: source,
allowEdit: false,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: false
};
}
function saveMedia(type) {
return $q(function(resolve, reject) {
var options = optionsForType(type);
$cordovaCamera.getPicture(options).then(function(imageUrl) {
var name = imageUrl.substr(imageUrl.lastIndexOf('/') + 1);
var namePath = imageUrl.substr(0, imageUrl.lastIndexOf('/') + 1);
var newName = makeid() + name;
$cordovaFile.copyFile(namePath, name, cordova.file.dataDirectory, newName)
.then(function(info) {
FileService.storeImage(newName);
resolve();
}, function(e) {
reject();
});
});
})
}
return {
handleMediaDialog: saveMedia
}
});
And i have a list of 3 items on swiping any of this item this buttons will be displayed, Which will invoke my camera function and take picture
<ion-option-button ng-click="addImage()"class="icon ion-android-camera"></ion-option-button>
<ion-option-button >
<img ng-src="{{urlForImage(separateImage)}}" width="90px" height="90px"/></ion-option-button>
<ion-option-button ng-click="gridPage()" class="icon ion-ios-grid-view"></ion-option-button>
i will get an array of image names
["image1.jpg",
"image2.jpg",
"image3.jpg"]
i need a json in this formate, With the detail that in which item i took this image.
[{"ItemNo":"1",
"FileName":"image1.jpg"},
{"ItemNo":"1",
"FileName":"image2.jpg",},
{"ItemNo":"3",
"FileName":"image3.jpg"}];
Could some one help me to solve this issue
This would be
var myArray = ['image1.jpg','image2.jpg','image3.jpg'];
var result = myArray.map(function(name, i) {
return {
ItemNo: i,
FileName: name
};
});
console.log( JSON.stringify(result) );
You would map the array.
If the ItemNo should start with 1, use
return {
ItemNo: (i + 1),
FileName: name
};

How testing file upload directive?

How can I test?
element.bind('change', function(evt) {
var files = evt.target.files;
if (!attrs.previewContainer) {
attrs.previewContainer = "preview";
var div = document.createElement("div");
var li = document.createElement("li");
li.appendChild(div);
li.id = attrs.previewContainer;
element.append(div);
}
if (typeof files !== "undefined") {
if (attrs.multiple) {
for (var i = 0, l = files.length; i < l; i++) {
loadMetadata(files[i], attrs).then(function(result) {
result.url = URL.createObjectURL(files[i]);
scope.metadata.push(result);
});
}
} else {
loadMetadata(files[0], attrs).then(function(result) {
result.url = URL.createObjectURL(files[0]);
scope.metadata = result;
});
}
}
});
The file HTML:
<input name='uploadVideo' type="file" metadata="uploadVideo"
preview-container="videoPreview" data-ng-model="uploadVideo.file">
I want to create a test file on a custom directive that deals in uploading a video and see a preview. So I would like to know how you create an event listening in angular:
Or similar
it('Test input file', inject(function() {
fakeFile = {
name: '/home/developer/mcd2/public/modules/uploads/store/videos/542e73cf054fbc3a1630d216/bear_movie.mp4'
};
var fileInput, evt;
fileInput = element.find('input').trigger('input');
evt = $.Event('change');
evt.target = {
files: [fakeFile]
};
angular.element(fileInput).triggerHandler(evt);
fileInput.trigger(evt);
expect(form.$modelValue.name).toBe(fakeFile.name);
expect(form.$valid).toBeTruthy();
}));

accessing items in firebase

I'm trying to learn firebase/angularjs by extending an app to use firebase as the backend.
My forge looks like this
.
In my program I have binded firebaseio.com/projects to $scope.projects.
How do I access the children?
Why doesn't $scope.projects.getIndex() return the keys to the children?
I know the items are in $scope.projects because I can see them if I do console.log($scope.projects)
app.js
angular.module('todo', ['ionic', 'firebase'])
/**
* The Projects factory handles saving and loading projects
* from localStorage, and also lets us save and load the
* last active project index.
*/
.factory('Projects', function() {
return {
all: function () {
var projectString = window.localStorage['projects'];
if(projectString) {
return angular.fromJson(projectString);
}
return [];
},
// just saves all the projects everytime
save: function(projects) {
window.localStorage['projects'] = angular.toJson(projects);
},
newProject: function(projectTitle) {
// Add a new project
return {
title: projectTitle,
tasks: []
};
},
getLastActiveIndex: function () {
return parseInt(window.localStorage['lastActiveProject']) || 0;
},
setLastActiveIndex: function (index) {
window.localStorage['lastActiveProject'] = index;
}
}
})
.controller('TodoCtrl', function($scope, $timeout, $ionicModal, Projects, $firebase) {
// Load or initialize projects
//$scope.projects = Projects.all();
var projectsUrl = "https://ionic-guide-harry.firebaseio.com/projects";
var projectRef = new Firebase(projectsUrl);
$scope.projects = $firebase(projectRef);
$scope.projects.$on("loaded", function() {
var keys = $scope.projects.$getIndex();
console.log($scope.projects.$child('-JGTmBu4aeToOSGmgCo1'));
// Grab the last active, or the first project
$scope.activeProject = $scope.projects.$child("" + keys[0]);
});
// A utility function for creating a new project
// with the given projectTitle
var createProject = function(projectTitle) {
var newProject = Projects.newProject(projectTitle);
$scope.projects.$add(newProject);
Projects.save($scope.projects);
$scope.selectProject(newProject, $scope.projects.length-1);
};
// Called to create a new project
$scope.newProject = function() {
var projectTitle = prompt('Project name');
if(projectTitle) {
createProject(projectTitle);
}
};
// Called to select the given project
$scope.selectProject = function(project, index) {
$scope.activeProject = project;
Projects.setLastActiveIndex(index);
$scope.sideMenuController.close();
};
// Create our modal
$ionicModal.fromTemplateUrl('new-task.html', function(modal) {
$scope.taskModal = modal;
}, {
scope: $scope
});
$scope.createTask = function(task) {
if(!$scope.activeProject || !task) {
return;
}
console.log($scope.activeProject.task);
$scope.activeProject.task.$add({
title: task.title
});
$scope.taskModal.hide();
// Inefficient, but save all the projects
Projects.save($scope.projects);
task.title = "";
};
$scope.newTask = function() {
$scope.taskModal.show();
};
$scope.closeNewTask = function() {
$scope.taskModal.hide();
};
$scope.toggleProjects = function() {
$scope.sideMenuController.toggleLeft();
};
// Try to create the first project, make sure to defer
// this by using $timeout so everything is initialized
// properly
$timeout(function() {
if($scope.projects.length == 0) {
while(true) {
var projectTitle = prompt('Your first project title:');
if(projectTitle) {
createProject(projectTitle);
break;
}
}
}
});
});
I'm interested in the objects at the bottom
console.log($scope.projects)
Update
After digging around it seems I may be accessing the data incorrectly. https://www.firebase.com/docs/reading-data.html
Here's my new approach
// Load or initialize projects
//$scope.projects = Projects.all();
var projectsUrl = "https://ionic-guide-harry.firebaseio.com/projects";
var projectRef = new Firebase(projectsUrl);
projectRef.on('value', function(snapshot) {
if(snapshot.val() === null) {
console.log('location does not exist');
} else {
console.log(snapshot.val()['-JGTdgGAfq7dqBpSk2ls']);
}
});
$scope.projects = $firebase(projectRef);
$scope.projects.$on("loaded", function() {
// Grab the last active, or the first project
$scope.activeProject = $scope.projects.$child("a");
});
I'm still not sure how to traverse the keys programmatically but I feel I'm getting close
It's an object containing more objects, loop it with for in:
for (var key in $scope.projects) {
if ($scope.projects.hasOwnProperty(key)) {
console.log("The key is: " + key);
console.log("The value is: " + $scope.projects[key]);
}
}
ok so val() returns an object. In order to traverse all the children of projects I do
// Load or initialize projects
//$scope.projects = Projects.all();
var projectsUrl = "https://ionic-guide-harry.firebaseio.com/projects";
var projectRef = new Firebase(projectsUrl);
projectRef.on('value', function(snapshot) {
if(snapshot.val() === null) {
console.log('location does not exist');
} else {
var keys = Object.keys(snapshot.val());
console.log(snapshot.val()[keys[0]]);
}
});
$scope.projects = $firebase(projectRef);
$scope.projects.$on("loaded", function() {
// Grab the last active, or the first project
$scope.activeProject = $scope.projects.$child("a");
});
Note the var keys = Object.keys() gets all the keys at firebaseio.com/projects then you can get the first child by doing snapshot.val()[keys[0])

Resources