UNPKG

globular-mvc

Version:

Generic template to create web-application that made use of globular as backend and materialize as css (wrap in web-component's)

493 lines (381 loc) 15.4 kB
import { createDir, deleteFile, readDir, uploadFiles } from "globular-web-client/api"; import { generatePeerToken, getUrl, Model } from '../Model' import { File } from '../File' import { ApplicationView } from "../ApplicationView"; import * as getUuidByString from "uuid-by-string"; import "@polymer/iron-icons/av-icons"; import { Application } from "../Application"; import { Account } from "../Account"; import { Contact, SetAccountContactRqst } from "globular-web-client/resource/resource_pb.js"; /** * Sample empty component */ export class Ringtones extends HTMLElement { // attributes. // Create the applicaiton view. constructor() { super() // Set the shadow dom. this.attachShadow({ mode: 'open' }); this.account = null; // Innitialisation of the layout. this.shadowRoot.innerHTML = ` <style> #container{ display: flex; flex-direction: column; } ::-webkit-scrollbar { width: 5px; height: 5px; } ::-webkit-scrollbar-track { background: var(--palette-background-default); } ::-webkit-scrollbar-thumb { background: var(--palette-divider); } #ringtones{ display: flex; flex-direction: column; max-height: 150px; overflow-y: auto; border-top: 1px solid var(--palette-action-disabled); } #ringtone-div{ display: flex; flex-direction: row; background-color: var(--palette-background-paper); color: var(--palette-text-primary); --iron-icon-fill-color: var(--palette-text-primary); align-items: center; font-size: .85rem; } </style> <div id="container"> <div id="ringtone-div"> <div id="ringtone"></div> <paper-icon-button id="ringtones-button" icon="arrow-drop-down"></paper-icon-button> <span style="flex-grow: 1;"></span> <paper-icon-button id="upload-button" icon="icons:file-upload"></paper-icon-button> </div> <div id="ringtones" style="display: none;"> <slot></slot> </div> </div> ` // give the focus to the input. this.container = this.shadowRoot.querySelector("#container") let ringtonesDiv = this.shadowRoot.querySelector("#ringtones") this.shadowRoot.querySelector("#ringtones-button").onclick = () => { if (ringtonesDiv.style.display == "none") { ringtonesDiv.style.display = "flex" this.shadowRoot.querySelector("#upload-button").style.display = "flex" } else { ringtonesDiv.style.display = "none" this.shadowRoot.querySelector("#upload-button").style.display = "none" } } // upload a new ringtone this.shadowRoot.querySelector("#upload-button").onclick = () => { var input = document.createElement('input'); input.type = 'file'; input.accept = ".mp3" input.click(); input.onchange = (evt) => { const files = evt.target.files if (files && files[0]) { let globule = Application.getGlobule(Application.account.domain) // set the path... let path = "/applications/" + Model.application + "/ringtones" uploadFiles(globule, localStorage.getItem("user_token"), path, files, () => { let f = files[0] f.path = path + "/" + f.name let ringtone = new Ringtone(f, this) this.insertBefore(ringtone, this.children[0]) }, err => { console.log(err) }) } } } } // The connection callback. connectedCallback() { if (this.children.length > 0) { return; } // Now I will save the contact ringtone... Account.getAccount(this.getAttribute("account"), contact => { this.account = contact; Account.getContacts(Application.account, `{"_id":"${contact.id + "@" + contact.domain}"}`, contacts => { if (contacts.length > 0) { if (contacts[0].ringtone) { this.account.ringtone = contacts[0].ringtone } // Now I will set the file... this.loadRingTone(Model.globular.config.WebRoot + "/webroot/" + Model.application + "/" + this.getAttribute("dir"), () => { // The dir where additional ringtone will be place. createDir(Model.globular, Model.globular.config.DataPath + "/files/applications/" + Model.application, "ringtones", () => { this.loadRingTone("/applications/" + Model.application + "/ringtones", () => this.setCurrentRingtone()) }, () => { this.loadRingTone("/applications/" + Model.application + "/ringtones", () => this.setCurrentRingtone()) }) }, false) } }, err => ApplicationView.displayMessage(err, 3000)) }, err => ApplicationView.displayMessage(err, 3000)) } setCurrentRingtone() { // set the firt ringtone by default... if (this.children.length > 0 && !this.account.ringtone) { this.setRingtone(this.children[0]) } else { let values = this.account.ringtone.split("/") let id = "_" + getUuidByString(values[values.length - 1]) let ringtone = this.querySelector("#" + id) this.setRingtone(ringtone) } } loadRingTone(path, callback, deletable) { readDir(Model.globular, path, false, dir => { dir.getFilesList().forEach(f => { if (f.getName().indexOf(".mp3") != -1) { let ringtone = new Ringtone(File.fromObject(f.toObject()), this) if (!this.querySelector("#" + ringtone.getAttribute("id"))) { this.appendChild(ringtone) if (deletable != undefined) { if (deletable == false) { ringtone.deleteButton.style.visibility = "hidden" } } } } }); if (callback) { callback() } }, err => ApplicationView.displayMessage(err, 3000)) } deleteRingtone(ringtone) { let toast = ApplicationView.displayMessage( ` <style> #yes-no-contact-delete-box{ display: flex; flex-direction: column; } #yes-no-contact-delete-box globular-contact-card{ padding-bottom: 10px; } #yes-no-contact-delete-box div{ display: flex; padding-bottom: 10px; } paper-button{ font-size: .85rem; height: 32px; } </style> <div id="yes-no-contact-delete-box"> <div>Your about to delete ringtone named ${ringtone.file.name}</div> <div>Is it what you want to do? </div> <div style="justify-content: flex-end;"> <paper-button id="yes-delete-btn">Yes</paper-button> <paper-button id="no-delete-btn">No</paper-button> </div> </div> `, 15000 // 15 sec... ); let yesBtn = document.querySelector("#yes-delete-btn") let noBtn = document.querySelector("#no-delete-btn") // On yes yesBtn.onclick = () => { let globule = Application.getGlobule(Application.account.domain) deleteFile(globule, ringtone.file.path, () => { this.removeChild(ringtone) toast.dismiss(); ApplicationView.displayMessage("the ringtone " + ringtone.file.name + " was deleted", 3000) }, err => { ApplicationView.displayMessage(err, 3000) }) } noBtn.onclick = () => { toast.dismiss(); } } setRingtone(ringtone) { if (!ringtone) { return } // set back the actual ringtone in the list ringtone.hideSetButton() ringtone.hideDeleteButton() if (this.shadowRoot.querySelector("#ringtone").children.length > 0) { let ringtone_ = this.shadowRoot.querySelector("#ringtone").children[0] ringtone_.showSetButton() ringtone_.showDeleteButton() this.appendChild(ringtone_) } // set the new ringtone. this.shadowRoot.querySelector("#ringtone").appendChild(ringtone) let ringtonesDiv = this.shadowRoot.querySelector("#ringtones") ringtonesDiv.style.display = "none" this.shadowRoot.querySelector("#upload-button").style.display = "none" // set the file path. this.account.ringtone = ringtone.file.path // Here I will return the value with it let rqst = new SetAccountContactRqst rqst.setAccountid(Application.account.id + "@" + Application.account.domain) let contact = new Contact contact.setId(this.account.id + "@" + this.account.domain) contact.setStatus("accepted") contact.setRingtone(this.account.ringtone) if (this.account.profilePicture) contact.setProfilepicture(this.account.profilePicture) contact.setInvitationtime(Math.round(Date.now() / 1000)) rqst.setContact(contact) let token = localStorage.getItem("user_token") // call persist data Model.getGlobule(Application.account.domain).resourceService .setAccountContact(rqst, { token: token, application: Model.application, domain: Model.domain }) .then((rsp) => { // Here I will return the value with it }) .catch(err => ApplicationView(err, 3000)); } play(loop) { this.shadowRoot.querySelector("#ringtone").children[0].play(loop) } stop() { this.shadowRoot.querySelector("#ringtone").children[0].stop() } } customElements.define('globular-ringtones', Ringtones) /** * Sample empty component */ export class Ringtone extends HTMLElement { // attributes. // Create the applicaiton view. constructor(file, parent) { super() // Set the shadow dom. this.attachShadow({ mode: 'open' }); this.id = "_" + getUuidByString(file.name) this.parent = parent; this.file = file; // Innitialisation of the layout. this.shadowRoot.innerHTML = ` <style> #container{ display: flex; align-items: center; font-size: 1rem; } .small { height: 32px; width: 32px; } </style> <div id="container"> <paper-icon-button class="small" id="play-button" icon="av:play-arrow"></paper-icon-button> <paper-icon-button class="small" id="stop-button" icon="av:stop" style="display: none;"></paper-icon-button> <span style="flex-grow: 1;">${file.name}</span> <paper-button id="delete-button" style="font-size: .75em;">delete</paper-button> <paper-button id="set-button" style="font-size: .75em;">set</paper-button> </div> ` // give the focus to the input. this.playBtn = this.shadowRoot.querySelector("#play-button") this.stopBtn = this.shadowRoot.querySelector("#stop-button") this.setButton = this.shadowRoot.querySelector("#set-button") this.deleteButton = this.shadowRoot.querySelector("#delete-button") let globule = Application.getGlobule(Application.account.domain) let url = getUrl(globule) let path = file.path path = path.replace(globule.config.WebRoot, "") path.split("/").forEach(item => { item = item.trim() if (item.length > 0) { url += "/" + encodeURIComponent(item) } }) url += "?application=" + Model.application generatePeerToken(globule, token => { if (localStorage.getItem("user_token") != undefined) { url += "&token=" + token } this.url = url; }) this.audio = null; this.playBtn.onclick = () => { this.play() } this.stopBtn.onclick = () => { this.stop() } this.setButton.onclick = () => { let ringtones = this.parent.getElementsByTagName("globular-ringtone") for (var i = 0; i < ringtones.length; i++) { ringtones[i].stop() } this.parent.setRingtone(this) } this.deleteButton.onclick = () => { let ringtones = this.parent.getElementsByTagName("globular-ringtone") for (var i = 0; i < ringtones.length; i++) { ringtones[i].stop() } this.parent.deleteRingtone(this) } } // The connection callback. connectedCallback() { } hideSetButton() { this.setButton.style.display = "none" } showSetButton() { this.setButton.style.display = "" } hideDeleteButton() { this.deleteButton.style.display = "none" } showDeleteButton() { this.deleteButton.style.display = "" } // Call search event. play(loop) { // stop currently selected ringtone... let ringtones = this.parent.getElementsByTagName("globular-ringtone") for (var i = 0; i < ringtones.length; i++) { ringtones[i].stop() } this.playBtn.style.display = "none" this.stopBtn.style.display = "" if (this.audio == null) { this.audio = new Audio(this.url) } if (loop) { this.audio.setAttribute("loop", "true") } this.audio.play() this.audio.onended = () => { this.stop() } } stop() { this.playBtn.style.display = "" this.stopBtn.style.display = "none" if (this.audio != null) { this.audio.pause() } } } customElements.define('globular-ringtone', Ringtone)