diff --git a/qortal-ui-plugins/plugins/core/components/ChatGifs.js b/qortal-ui-plugins/plugins/core/components/ChatGifs.js new file mode 100644 index 00000000..3ddb8017 --- /dev/null +++ b/qortal-ui-plugins/plugins/core/components/ChatGifs.js @@ -0,0 +1,276 @@ +import { LitElement, html, css } from 'lit' +import { render } from 'lit/html.js' +import { Epml } from '../../../epml.js' +import * as zip from "@zip.js/zip.js"; +import { saveAs } from 'file-saver'; +import '@material/mwc-icon' +import ShortUniqueId from 'short-unique-id'; +import { publishData } from '../../utils/publish-image.js'; + +const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }) + +class ChatGifs extends LitElement { + static get properties() { + return { + selectedAddress: { type: Object }, + myGifCollections: { type: Array }, + gifsToBeAdded: { type: Array}, + webWorkerImage: {type: Object}, + mode: {type: String}, + currentCollection: {type: String} + } + } + + static get styles() { + return css` + + ` + } + + constructor() { + super() + this.uid = new ShortUniqueId() + this.selectedAddress = window.parent.reduxStore.getState().app.selectedAddress + this.myGifCollections = [] + this.myAccountName = '' + this.gifsToBeAdded = [] + // mode can be 'myCollection', 'newCollection', 'explore', 'subscribedCollection' + this.mode = "myCollection" + this.currentCollection = null + } + + async firstUpdated() { + + + try { + const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; + const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port; + const userName = await this.getName(this.selectedAddress.address); + this.myAccountName = userName + if(this.myAccountName){ + const getMyGifColloctions = await parentEpml.request('apiCall', { + url: `/arbitrary/resources?service=GIF_REPOSITORY&limit=0&name=${this.myAccountName}` + }) + + + const getMetaDataGifs = (getMyGifColloctions || []).map(async (collection) => { + let collectionObj = collection + try { + const metaData = await parentEpml.request('apiCall', { + url: `/arbitrary/metadata/GIF_REPOSITORY/${this.myAccountName}/${collection.identifier}` + }) + + collectionObj = { + ...collection, + gifUrls: [] + } + if(metaData.description){ + const metaDataArray = metaData.description.split(';').map((data)=> { + return `${nodeUrl}/arbitrary/GIF_REPOSITORY/${this.myAccountName}/${collection.identifier}?filepath=${data}` + }) + const listOfGifs = [`${nodeUrl}/arbitrary/GIF_REPOSITORY/Phil/gif_pmBEwm?filepath=giphy (1).gif`, `${nodeUrl}/arbitrary/GIF_REPOSITORY/Phil/gif_pmBEwm?filepath=giphy (3).gif`] + + collectionObj = { + ...collection, + gifUrls: metaDataArray + } + + } + + + + } catch (error) { + console.log(error) + } + + return collectionObj + }) + const gifCollectionWithMetaData = await Promise.all(getMetaDataGifs) + console.log({gifCollectionWithMetaData}) + this.myGifCollections = gifCollectionWithMetaData + } + + } catch (error) { + + } + } + + async getName (recipient) { + try { + const getNames = await parentEpml.request("apiCall", { + type: "api", + url: `/names/address/${recipient}`, + }); + + if (Array.isArray(getNames) && getNames.length > 0 ) { + return getNames[0].name + } else { + return '' + } + + } catch (error) { + return "" + } + } + + addGifs(gifs){ + console.log('gifs', gifs) + const mapGifs = gifs.map((file)=> { + return { + file, + name: file.name + } + }) + console.log({mapGifs}) + this.gifsToBeAdded = [...this.gifsToBeAdded, ...mapGifs] + console.log('this.gifsToBeAdded', this.gifsToBeAdded) + } + + async uploadGifCollection(){ + try { + function blobToBase64(blob) { + return new Promise((resolve, _) => { + const reader = new FileReader(); + reader.onloadend = () => resolve(reader.result); + reader.readAsDataURL(blob); + }); + } + const zipFileWriter = new zip.BlobWriter("application/zip"); +// Creates a TextReader object storing the text of the entry to add in the zip +// (i.e. "Hello world!"). +const helloWorldReader = new zip.TextReader("Hello world!"); + +// Creates a ZipWriter object writing data via `zipFileWriter`, adds the entry +// "hello.txt" containing the text "Hello world!" via `helloWorldReader`, and +// closes the writer. + +const zipWriter = new zip.ZipWriter(zipFileWriter, { bufferedWrite: true }); + + +for (let i = 0; i < this.gifsToBeAdded.length; i++) { + await zipWriter.add(this.gifsToBeAdded[i].name, new zip.BlobReader(this.gifsToBeAdded[i].file)); + } + + +await zipWriter.close(); +const zipFileBlob = await zipFileWriter.getData() +const blobTobase = await blobToBase64(zipFileBlob) +console.log({blobTobase}) +const userName = await this.getName(this.selectedAddress.address); + if (!userName) { + parentEpml.request('showSnackBar', get("chatpage.cchange27")); + this.isLoading = false; + return; + } + const id = this.uid(); + const identifier = `gif_${id}`; +await publishData({ + registeredName: userName, + file : blobTobase.split(',')[1], + service: 'GIF_REPOSITORY', + identifier: identifier, + parentEpml, + metaData: undefined, + uploadType: 'zip', + selectedAddress: this.selectedAddress, + worker: this.webWorkerImage, + isBase64: true, + metaData: `description=${this.gifsToBeAdded.map((gif)=> gif.name).join(';')}` + }) +saveAs(zipFileBlob, 'zipfile'); +console.log({zipFileBlob}) + } catch (error) { + console.log(error) + } + } + + render() { + + return html` +
+
+ + + + + + +${this.mode === "myCollection" && !this.currentCollection ? html` + ${this.myGifCollections.map((collection)=> { + return html` +
+

{ + this.currentCollection = collection + }}>${collection.identifier}

+ +
+ ` + })} + ` : ''} + ${this.currentCollection ? html` + + ${this.currentCollection.gifUrls.map((gif)=> { + console.log({gif}) + + return html` + { + e.target.src = gif + }} src=${gif} style="width: 50px; height: 50px" /> + ` + })} + ` : ''} + ${this.mode === "newCollection" ? html` + + + +
+ ${this.gifsToBeAdded.map((gif, i)=> { + console.log({gif}) + return html` +
+ + { + this.gifsToBeAdded[i] = { + ...gif, + name: e.target.value + } + })} /> +
+ + ` + })} +
+ ` : ''} + +
+
+ ` + } + + +} + +window.customElements.define('chat-gifs', ChatGifs) diff --git a/qortal-ui-plugins/plugins/core/components/ChatPage.js b/qortal-ui-plugins/plugins/core/components/ChatPage.js index 0ade923f..5ebc0247 100644 --- a/qortal-ui-plugins/plugins/core/components/ChatPage.js +++ b/qortal-ui-plugins/plugins/core/components/ChatPage.js @@ -11,7 +11,7 @@ import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import { Editor, Extension } from '@tiptap/core' import * as zip from "@zip.js/zip.js"; import { saveAs } from 'file-saver'; - +import './ChatGifs' // import localForage from "localforage"; registerTranslateConfig({ loader: lang => fetch(`/language/${lang}.json`).then(res => res.json()) @@ -106,7 +106,7 @@ class ChatPage extends LitElement { selectedHead: { type: Object }, userName: { type: String }, goToRepliedMessage: {attribute: false}, - gifsToBeAdded: { type: Array} + openGifModal: {type: Boolean} } } @@ -894,7 +894,12 @@ class ChatPage extends LitElement { this.currentEditor = '_chatEditorDOM' this.initialChat = this.initialChat.bind(this) this.isEnabledChatEnter = true - this.gifsToBeAdded = [] + this.openGifModal = false + } + + setOpenGifModal(value){ + console.log({value}) + this.openGifModal = value } _toggle(value) { @@ -1104,6 +1109,7 @@ console.log({zipFileBlob}) .repliedToMessageObj=${this.repliedToMessageObj} .toggleEnableChatEnter=${this.toggleEnableChatEnter} ?isEnabledChatEnter=${this.isEnabledChatEnter} + .setOpenGifModal=${(val)=> this.setOpenGifModal(val)} > @@ -1124,6 +1130,15 @@ console.log({zipFileBlob}) `: ''} + + { + this.setOpenGifModal(false) + // this.removeImage(); + }} + style=${this.openGifModal ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100"}> + + { this.removeImage(); @@ -1174,34 +1189,7 @@ console.log({zipFileBlob}) - - { - // this.removeImage(); - }} - style=${true ? "visibility:visible;z-index:50" : "visibility: hidden;z-index:-100"}> -
-
- - - - -
-
-
+

${translate("chatpage.cchange41")}


@@ -1511,7 +1499,7 @@ console.log({zipFileBlob}) } initialChat(e) { - if (this.editor && !this.editor.isFocused && this.currentEditor === '_chatEditorDOM' && !this.openForwardOpen && !this.openTipUser) { + if (this.editor && !this.editor.isFocused && this.currentEditor === '_chatEditorDOM' && !this.openForwardOpen && !this.openTipUser &&!this.openGifModal) { // WARNING: Deprecated methods from KeyBoard Event if (e.code === "Space" || e.keyCode === 32 || e.which === 32) { } else if (inputKeyCodes.includes(e.keyCode)) { diff --git a/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js b/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js index cc371fa4..70a7d068 100644 --- a/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js +++ b/qortal-ui-plugins/plugins/core/components/ChatTextEditor.js @@ -29,7 +29,8 @@ class ChatTextEditor extends LitElement { reflect: true }, toggleEnableChatEnter: {attribute: false}, - isEnabledChatEnter: {type: Boolean} + isEnabledChatEnter: {type: Boolean}, + setOpenGifModal: {attribute: false} } } @@ -461,6 +462,13 @@ class ChatTextEditor extends LitElement { + ${this.setOpenGifModal ? + html` + + ` + : ''} ${this.editedMessageObj ? ( html`
diff --git a/qortal-ui-plugins/plugins/utils/publish-image.js b/qortal-ui-plugins/plugins/utils/publish-image.js index 5835aa33..ed8e2a64 100644 --- a/qortal-ui-plugins/plugins/utils/publish-image.js +++ b/qortal-ui-plugins/plugins/utils/publish-image.js @@ -17,7 +17,8 @@ export const publishData = async ({ uploadType, selectedAddress, worker, - isBase64 + isBase64, + metaData }) => { const validateName = async (receiverName) => { let nameRes = await parentEpml.request("apiCall", { @@ -131,7 +132,13 @@ export const publishData = async ({ let uploadDataUrl = `/arbitrary/${service}/${registeredName}${urlSuffix}?apiKey=${getApiKey()}` if (identifier != null && identifier.trim().length > 0) { uploadDataUrl = `/arbitrary/${service}/${registeredName}/${identifier}${urlSuffix}?apiKey=${getApiKey()}` + + if(metaData){ + uploadDataUrl = `/arbitrary/${service}/${registeredName}/${identifier}${urlSuffix}?${metaData}&apiKey=${getApiKey()}` + + } } + let uploadDataRes = await parentEpml.request("apiCall", { type: "api", method: "POST",