4
1
mirror of https://github.com/Qortal/qortal-ui.git synced 2025-02-14 19:25:50 +00:00

bug fixes and ability to repost

This commit is contained in:
PhilReact 2023-09-22 23:38:48 -05:00
parent a80f6800d8
commit e0c8093740
6 changed files with 178 additions and 87 deletions

View File

@ -212,7 +212,7 @@ getMyNode(){
} }
// check if progress is 100% and clear interval if true // check if progress is 100% and clear interval if true
if (res?.status === 'READY') { if (res.status === 'READY') {
clearInterval(intervalId) clearInterval(intervalId)
this.status = res this.status = res
this.isReady = true this.isReady = true

View File

@ -48,6 +48,7 @@ import '@polymer/paper-dialog/paper-dialog.js'
import '@polymer/paper-spinner/paper-spinner-lite.js' import '@polymer/paper-spinner/paper-spinner-lite.js'
import { RequestQueue } from '../../utils/queue.js' import { RequestQueue } from '../../utils/queue.js'
import { modalHelper } from '../../utils/publish-modal.js' import { modalHelper } from '../../utils/publish-modal.js'
import { generateIdFromAddresses } from '../../utils/id-generation.js'
const chatLastSeen = localForage.createInstance({ const chatLastSeen = localForage.createInstance({
name: "chat-last-seen", name: "chat-last-seen",
@ -1384,8 +1385,29 @@ class ChatPage extends LitElement {
this.addToQueue = this.addToQueue.bind(this) this.addToQueue = this.addToQueue.bind(this)
this.processQueue = this.processQueue.bind(this) this.processQueue = this.processQueue.bind(this)
this.isInProcessQueue = false this.isInProcessQueue = false
this.nodeUrl = this.getNodeUrl();
this.myNode = this.getMyNode();
} }
getNodeUrl() {
const myNode =
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
window.parent.reduxStore.getState().app.nodeConfig.node
];
const nodeUrl =
myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
return nodeUrl;
}
getMyNode() {
const myNode =
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
window.parent.reduxStore.getState().app.nodeConfig.node
];
return myNode;
}
setOpenGifModal(value) { setOpenGifModal(value) {
this.openGifModal = value this.openGifModal = value
} }
@ -1498,7 +1520,6 @@ class ChatPage extends LitElement {
render() { render() {
console.log('this.chatId', this.chatId, this._chatId)
return html` return html`
<div class="main-container"> <div class="main-container">
<div <div
@ -1506,7 +1527,10 @@ class ChatPage extends LitElement {
style="grid-template-rows: minmax(40px, auto) minmax(6%, 92vh) minmax(40px, auto); flex: 3;"> style="grid-template-rows: minmax(40px, auto) minmax(6%, 92vh) minmax(40px, auto); flex: 3;">
<div class="group-nav-container"> <div class="group-nav-container">
<div @click=${this._toggle} style="height: 100%; display: flex; align-items: center;flex-grow: 1; cursor: pointer; cursor: pointer; user-select: none"> <div @click=${()=> {
if(+this._chatId === 0 || this.isReceipient)return
this._toggle()
}} style=${`height: 100%; display: flex; align-items: center;flex-grow: 1; cursor: pointer; cursor: ${+this._chatId === 0 || this.isReceipient ? 'default': 'pointer'}; user-select: none`}>
${this.isReceipient ? '' : +this._chatId === 0 ? html` ${this.isReceipient ? '' : +this._chatId === 0 ? html`
<p class="group-name">Qortal General Chat</p> <p class="group-name">Qortal General Chat</p>
` : html` ` : html`
@ -1691,7 +1715,7 @@ class ChatPage extends LitElement {
<div> <div>
<div class="dialog-container"> <div class="dialog-container">
${this.imageFile && html` ${this.imageFile && html`
<img src=${URL.createObjectURL(this.imageFile)} alt="dialog-img" class="dialog-image" /> <img src=${this.imageFile.identifier ? `${this.nodeUrl}/arbitrary/${this.imageFile.service}/${this.imageFile.name}/${this.imageFile.identifier}?apiKey=${this.myNode.apiKey}` : URL.createObjectURL(this.imageFile)} alt="dialog-img" class="dialog-image" />
`} `}
<div class="caption-container"> <div class="caption-container">
<chat-text-editor <chat-text-editor
@ -1982,6 +2006,7 @@ class ChatPage extends LitElement {
_chatId=${ifDefined(this._chatId)} _chatId=${ifDefined(this._chatId)}
chatId=${this.chatId} chatId=${this.chatId}
?isreceipient=${this.isReceipient} ?isreceipient=${this.isReceipient}
.repost=${this.insertFile}
> >
</chat-right-panel-resources> </chat-right-panel-resources>
</div> </div>
@ -2380,6 +2405,11 @@ class ChatPage extends LitElement {
} }
insertFile(file) { insertFile(file) {
if(file.identifier){
this.imageFile = file
this.currentEditor = 'newChat'
return
}else
if (file.type.includes('image')) { if (file.type.includes('image')) {
this.imageFile = file this.imageFile = file
this.currentEditor = 'newChat' this.currentEditor = 'newChat'
@ -3900,7 +3930,9 @@ class ChatPage extends LitElement {
const stringifyMessageObject = JSON.stringify(messageObject) const stringifyMessageObject = JSON.stringify(messageObject)
return this.sendMessage({messageText: stringifyMessageObject, typeMessage, chatReference, isForward: false, isReceipient, _chatId, _publicKey, messageQueue}) return this.sendMessage({messageText: stringifyMessageObject, typeMessage, chatReference, isForward: false, isReceipient, _chatId, _publicKey, messageQueue})
} else if (outSideMsg && outSideMsg.type === 'image') { } else if (outSideMsg && outSideMsg.type === 'image') {
this.isUploadingImage = true if(!this.imageFile.identifier){
this.isUploadingImage = true
}
const userName = await getName(this.selectedAddress.address) const userName = await getName(this.selectedAddress.address)
if (!userName) { if (!userName) {
parentEpml.request('showSnackBar', get("chatpage.cchange27")) parentEpml.request('showSnackBar', get("chatpage.cchange27"))
@ -3909,78 +3941,94 @@ class ChatPage extends LitElement {
this.imageFile = null this.imageFile = null
return return
} }
const arbitraryFeeData = await modalHelper.getArbitraryFee()
const res = await modalHelper.showModalAndWaitPublish(
{ let service = "QCHAT_IMAGE"
feeAmount: arbitraryFeeData.feeToShow let name = userName
let identifier
if(this.imageFile.identifier){
identifier = this.imageFile.identifier
name = this.imageFile.name
service = this.imageFile.service
} else {
const arbitraryFeeData = await modalHelper.getArbitraryFee()
const res = await modalHelper.showModalAndWaitPublish(
{
feeAmount: arbitraryFeeData.feeToShow
}
);
if (res.action !== 'accept') throw new Error('User declined publish')
if (this.webWorkerFile) {
this.webWorkerFile.terminate()
this.webWorkerFile = null
} }
);
if (res.action !== 'accept') throw new Error('User declined publish')
if (this.webWorkerFile) { this.webWorkerFile = new WebWorkerFile()
this.webWorkerFile.terminate() const image = this.imageFile
this.webWorkerFile = null const id = this.uid.rnd()
} let groupPart
if(this.isReceipient){
this.webWorkerFile = new WebWorkerFile() groupPart = `direct_${generateIdFromAddresses(this._chatId, this.selectedAddress.address)}`
} else {
const image = this.imageFile groupPart = `group_${this._chatId}`
const id = this.uid.rnd() }
const groupPart = this.isReceipient ? `direct_${this._chatId.slice(-15)}` : `group_${this._chatId}` identifier = `qchat_${groupPart}_${id}`
const identifier = `qchat_${groupPart}_${id}` let compressedFile = ''
let compressedFile = '' await new Promise(resolve => {
await new Promise(resolve => { new Compressor(image, {
new Compressor(image, { quality: .6,
quality: .6, maxWidth: 1200,
maxWidth: 1200, mimeType: 'image/webp',
mimeType: 'image/webp', success(result) {
success(result) { const file = new File([result], "name", {
const file = new File([result], "name", { type: 'image/webp'
type: 'image/webp' })
}) compressedFile = file
compressedFile = file resolve()
resolve() },
}, error(err) {
error(err) { },
}, })
}) })
}) const fileSize = compressedFile.size
const fileSize = compressedFile.size if (fileSize > 500000) {
if (fileSize > 500000) { parentEpml.request('showSnackBar', get("chatpage.cchange26"))
parentEpml.request('showSnackBar', get("chatpage.cchange26")) this.isLoading = false
this.isLoading = false this.isUploadingImage = false
this.isUploadingImage = false return
return }
}
try { try {
await publishData({
registeredName: userName,
file: compressedFile,
service: 'QCHAT_IMAGE',
identifier: identifier,
parentEpml,
metaData: undefined,
uploadType: 'file',
selectedAddress: this.selectedAddress,
worker: this.webWorkerFile,
withFee: true,
feeAmount: arbitraryFeeData.fee
})
this.isUploadingImage = false
this.removeImage()
} catch (error) {
this.isLoading = false
this.isUploadingImage = false
return
}
await publishData({
registeredName: userName,
file: compressedFile,
service: 'QCHAT_IMAGE',
identifier: identifier,
parentEpml,
metaData: undefined,
uploadType: 'file',
selectedAddress: this.selectedAddress,
worker: this.webWorkerFile,
withFee: true,
feeAmount: arbitraryFeeData.fee
})
this.isUploadingImage = false
this.removeImage()
} catch (error) {
this.isLoading = false
this.isUploadingImage = false
return
} }
const messageObject = { const messageObject = {
messageText: trimmedMessage, messageText: trimmedMessage,
images: [{ images: [{
service: "QCHAT_IMAGE", service: service,
name: userName, name: name,
identifier: identifier, identifier: identifier,
}], }],
isImageDeleted: false, isImageDeleted: false,
@ -3988,6 +4036,7 @@ class ChatPage extends LitElement {
version: 3 version: 3
} }
const stringifyMessageObject = JSON.stringify(messageObject) const stringifyMessageObject = JSON.stringify(messageObject)
this.removeImage()
return this.sendMessage({messageText: stringifyMessageObject, typeMessage, chatReference: undefined, isForward: false, isReceipient, _chatId, _publicKey, messageQueue}) return this.sendMessage({messageText: stringifyMessageObject, typeMessage, chatReference: undefined, isForward: false, isReceipient, _chatId, _publicKey, messageQueue})
} else if (outSideMsg && outSideMsg.type === 'gif') { } else if (outSideMsg && outSideMsg.type === 'gif') {
const userName = await getName(this.selectedAddress.address) const userName = await getName(this.selectedAddress.address)

View File

@ -21,6 +21,7 @@ import {
translateUnsafeHTML, translateUnsafeHTML,
registerTranslateConfig, registerTranslateConfig,
} from 'lit-translate'; } from 'lit-translate';
import { generateIdFromAddresses } from '../../utils/id-generation';
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent }); const parentEpml = new Epml({ type: 'WINDOW', source: window.parent });
@ -51,7 +52,8 @@ class ChatRightPanelResources extends LitElement {
images: { type: Array }, images: { type: Array },
viewImage: { type: Boolean }, viewImage: { type: Boolean },
autoView: {type: Boolean}, autoView: {type: Boolean},
onlyMyImages: {type: Boolean} onlyMyImages: {type: Boolean},
repost: {attribute: false}
}; };
} }
@ -77,6 +79,8 @@ class ChatRightPanelResources extends LitElement {
this.viewImage = false; this.viewImage = false;
this.myName = this.myName =
window.parent.reduxStore.getState().app.accountInfo.names[0].name; window.parent.reduxStore.getState().app.accountInfo.names[0].name;
this.myAddress =
window.parent.reduxStore.getState().app.selectedAddress.address;
this.autoView =false this.autoView =false
this.onlyMyImages = true this.onlyMyImages = true
} }
@ -237,18 +241,18 @@ class ChatRightPanelResources extends LitElement {
font-family: Montserrat, sans-serif; font-family: Montserrat, sans-serif;
font-weight: 600; font-weight: 600;
color: var(--black); color: var(--black);
padding-left: 5px;
} }
`; `;
} }
async getMoreImages(reset) { async getMoreImages(reset) {
try { try {
console.log({reset})
if(reset){ if(reset){
this.images = [] this.images = []
} }
const groupPart = this.isReceipient const groupPart = this.isReceipient
? `direct_${this._chatId.slice(-15)}` ? `direct_${generateIdFromAddresses(this._chatId, this.myAddress)}`
: `group_${this._chatId}`; : `group_${this._chatId}`;
let offset = reset ? 0 : this.images.length; let offset = reset ? 0 : this.images.length;
@ -282,7 +286,6 @@ class ChatRightPanelResources extends LitElement {
} }
async updated(changedProperties) { async updated(changedProperties) {
console.log({ changedProperties });
if (changedProperties && changedProperties.has('_chatId')) { if (changedProperties && changedProperties.has('_chatId')) {
this.images = []; this.images = [];
this.getMoreImages(true); this.getMoreImages(true);
@ -315,7 +318,6 @@ class ChatRightPanelResources extends LitElement {
if (!entries[0].isIntersecting) { if (!entries[0].isIntersecting) {
return; return;
} else { } else {
console.log('hello', this.images)
if (this.images.length < 20) { if (this.images.length < 20) {
return; return;
} }
@ -340,7 +342,6 @@ class ChatRightPanelResources extends LitElement {
} }
render() { render() {
console.log('hello resources3', this.images);
return html` return html`
<div class="container"> <div class="container">
@ -368,7 +369,7 @@ class ChatRightPanelResources extends LitElement {
<div id="viewElement" class="container-body"> <div id="viewElement" class="container-body">
${this.images.map((image) => { ${this.images.map((image) => {
return html`<image-parent .image=${image} ?autoView=${this.autoView}></image-parent>`; return html`<image-parent .repost=${this.repost} .image=${image} ?autoView=${this.autoView}></image-parent>`;
})} })}
<div id='downObserver'></div> <div id='downObserver'></div>
</div> </div>
@ -407,7 +408,9 @@ class ImageParent extends LitElement {
images: { type: Array }, images: { type: Array },
viewImage: { type: Boolean }, viewImage: { type: Boolean },
image: { type: Object }, image: { type: Object },
autoView: {type: Boolean} autoView: {type: Boolean},
repost: {attribute: false},
isImgLoaded: {type: Boolean}
}; };
} }
@ -425,7 +428,7 @@ class ImageParent extends LitElement {
this.btnDisable = false; this.btnDisable = false;
this.errorMessage = ''; this.errorMessage = '';
this.successMessage = ''; this.successMessage = '';
this.isImgLoaded = false
this.images = []; this.images = [];
this.viewImage = false; this.viewImage = false;
this.myName = this.myName =
@ -584,6 +587,17 @@ class ImageParent extends LitElement {
.image-container { .image-container {
display: flex; display: flex;
} }
.repost-btn {
margin-top: 4px;
max-height: 28px;
padding: 5px 5px;
font-size: 14px;
background-color: #03a9f4;
color: white;
border: 1px solid transparent;
border-radius: 3px;
cursor: pointer;
}
`; `;
} }
@ -599,6 +613,11 @@ class ImageParent extends LitElement {
} }
} }
onLoad(){
this.isImgLoaded = true
this.requestUpdate()
}
render() { render() {
return html` return html`
${!this.autoView && !this.viewImage && this.myName !== this.image.name ${!this.autoView && !this.viewImage && this.myName !== this.image.name
@ -639,8 +658,14 @@ class ImageParent extends LitElement {
service: this.image.service, service: this.image.service,
identifier: this.image.identifier, identifier: this.image.identifier,
}} }}
.onLoad=${()=> this.onLoad()}
></reusable-image> ></reusable-image>
< ${this.isImgLoaded ? html`
<div class="actions-parent">
<button class="repost-btn" @click=${()=> this.repost(this.image)}>repost</button>
</div>
` : ''}
</div> </div>
` `
: ''} : ''}

View File

@ -732,7 +732,7 @@ class ChatScroller extends LitElement {
` `
)} )}
<div <div
style=${this.messageQueue.filter((item) => this.chatId.includes(item._chatId)).length > 0 ? 'height: 1px' : 'height: 1px; margin-top: -100px'} style=${this.messageQueue.filter((item) => this.chatId.includes(item._chatId)).length > 0 ? 'height: 1px' : 'height: 1px'}
id="bottomObserverForFetchingMessages" id="bottomObserverForFetchingMessages"
></div> ></div>
@ -745,7 +745,7 @@ class ChatScroller extends LitElement {
</div> </div>
` `
: ''} : ''}
${repeat( ${!this.disableAddingNewMessages ? repeat(
this.messageQueue.filter((item) => this.messageQueue.filter((item) =>
this.chatId.includes(item._chatId) this.chatId.includes(item._chatId)
), ),
@ -787,7 +787,7 @@ class ChatScroller extends LitElement {
?isInProgress=${true} ?isInProgress=${true}
></message-template> ></message-template>
` `
)} ): ''}
</ul> </ul>
`; `;
} }
@ -934,6 +934,7 @@ class ChatScroller extends LitElement {
if (this.messagesToRender.length === 0 || this.disableFetching) { if (this.messagesToRender.length === 0 || this.disableFetching) {
return; return;
} }
if(!this.disableAddingNewMessages) return
if ( if (
!entries[0].isIntersecting || !entries[0].isIntersecting ||
!entries[0].target || !entries[0].target ||

View File

@ -27,7 +27,7 @@ export class ResuableImage extends LitElement {
status: { type: Object }, status: { type: Object },
missingData: {type: Boolean}, missingData: {type: Boolean},
openDialogImage: { type: Boolean }, openDialogImage: { type: Boolean },
onLoad: {attribute: false}
}; };
} }
@ -182,6 +182,7 @@ export class ResuableImage extends LitElement {
); );
if (response && response.data && response.data.status === 'READY') { if (response && response.data && response.data.status === 'READY') {
this.status = response.data; this.status = response.data;
this.onLoad()
return; return;
} }
const intervalId = setInterval(async () => { const intervalId = setInterval(async () => {
@ -230,13 +231,14 @@ export class ResuableImage extends LitElement {
} }
// check if progress is 100% and clear interval if true // check if progress is 100% and clear interval if true
if (res?.status === 'READY') { if (res.status === 'READY') {
this.onLoad()
clearInterval(intervalId); clearInterval(intervalId);
this.status = res; this.status = res;
this.isReady = true; this.isReady = true;
} }
if(res?.status === 'MISSING_DATA'){ if(res.status === 'MISSING_DATA'){
this.status = res this.status = res
this.missingData = true this.missingData = true
clearInterval(intervalId) clearInterval(intervalId)

View File

@ -0,0 +1,14 @@
export function simpleHash(str) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = (hash << 5) - hash + str.charCodeAt(i);
hash = hash & hash; // Convert to 32bit integer
}
return hash.toString();
}
export function generateIdFromAddresses(address1, address2) {
// Sort addresses lexicographically and concatenate
const sortedAddresses = [address1, address2].sort().join('');
return simpleHash(sortedAddresses);
}