Browse Source

bug fixes and ability to repost

resolve-20231003
PhilReact 1 year ago
parent
commit
e0c8093740
  1. 2
      plugins/plugins/core/components/ChatImage.js
  2. 189
      plugins/plugins/core/components/ChatPage.js
  3. 45
      plugins/plugins/core/components/ChatRightPanelResources.js
  4. 7
      plugins/plugins/core/components/ChatScroller.js
  5. 8
      plugins/plugins/core/components/ReusableImage.js
  6. 14
      plugins/plugins/utils/id-generation.js

2
plugins/plugins/core/components/ChatImage.js

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

189
plugins/plugins/core/components/ChatPage.js

@ -48,6 +48,7 @@ import '@polymer/paper-dialog/paper-dialog.js'
import '@polymer/paper-spinner/paper-spinner-lite.js'
import { RequestQueue } from '../../utils/queue.js'
import { modalHelper } from '../../utils/publish-modal.js'
import { generateIdFromAddresses } from '../../utils/id-generation.js'
const chatLastSeen = localForage.createInstance({
name: "chat-last-seen",
@ -1384,8 +1385,29 @@ class ChatPage extends LitElement {
this.addToQueue = this.addToQueue.bind(this)
this.processQueue = this.processQueue.bind(this)
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) {
this.openGifModal = value
}
@ -1498,7 +1520,6 @@ class ChatPage extends LitElement {
render() {
console.log('this.chatId', this.chatId, this._chatId)
return html`
<div class="main-container">
<div
@ -1506,7 +1527,10 @@ class ChatPage extends LitElement {
style="grid-template-rows: minmax(40px, auto) minmax(6%, 92vh) minmax(40px, auto); flex: 3;">
<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`
<p class="group-name">Qortal General Chat</p>
` : html`
@ -1691,7 +1715,7 @@ class ChatPage extends LitElement {
<div>
<div class="dialog-container">
${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">
<chat-text-editor
@ -1982,6 +2006,7 @@ class ChatPage extends LitElement {
_chatId=${ifDefined(this._chatId)}
chatId=${this.chatId}
?isreceipient=${this.isReceipient}
.repost=${this.insertFile}
>
</chat-right-panel-resources>
</div>
@ -2380,6 +2405,11 @@ class ChatPage extends LitElement {
}
insertFile(file) {
if(file.identifier){
this.imageFile = file
this.currentEditor = 'newChat'
return
}else
if (file.type.includes('image')) {
this.imageFile = file
this.currentEditor = 'newChat'
@ -3900,7 +3930,9 @@ class ChatPage extends LitElement {
const stringifyMessageObject = JSON.stringify(messageObject)
return this.sendMessage({messageText: stringifyMessageObject, typeMessage, chatReference, isForward: false, isReceipient, _chatId, _publicKey, messageQueue})
} else if (outSideMsg && outSideMsg.type === 'image') {
this.isUploadingImage = true
if(!this.imageFile.identifier){
this.isUploadingImage = true
}
const userName = await getName(this.selectedAddress.address)
if (!userName) {
parentEpml.request('showSnackBar', get("chatpage.cchange27"))
@ -3909,78 +3941,94 @@ class ChatPage extends LitElement {
this.imageFile = null
return
}
const arbitraryFeeData = await modalHelper.getArbitraryFee()
const res = await modalHelper.showModalAndWaitPublish(
{
feeAmount: arbitraryFeeData.feeToShow
let service = "QCHAT_IMAGE"
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.terminate()
this.webWorkerFile = null
}
this.webWorkerFile = new WebWorkerFile()
const image = this.imageFile
const id = this.uid.rnd()
const groupPart = this.isReceipient ? `direct_${this._chatId.slice(-15)}` : `group_${this._chatId}`
const identifier = `qchat_${groupPart}_${id}`
let compressedFile = ''
await new Promise(resolve => {
new Compressor(image, {
quality: .6,
maxWidth: 1200,
mimeType: 'image/webp',
success(result) {
const file = new File([result], "name", {
type: 'image/webp'
})
compressedFile = file
resolve()
},
error(err) {
},
})
})
const fileSize = compressedFile.size
if (fileSize > 500000) {
parentEpml.request('showSnackBar', get("chatpage.cchange26"))
this.isLoading = false
this.isUploadingImage = false
return
}
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.webWorkerFile = new WebWorkerFile()
const image = this.imageFile
const id = this.uid.rnd()
let groupPart
if(this.isReceipient){
groupPart = `direct_${generateIdFromAddresses(this._chatId, this.selectedAddress.address)}`
} else {
groupPart = `group_${this._chatId}`
}
identifier = `qchat_${groupPart}_${id}`
let compressedFile = ''
await new Promise(resolve => {
new Compressor(image, {
quality: .6,
maxWidth: 1200,
mimeType: 'image/webp',
success(result) {
const file = new File([result], "name", {
type: 'image/webp'
})
compressedFile = file
resolve()
},
error(err) {
},
})
})
this.isUploadingImage = false
this.removeImage()
} catch (error) {
this.isLoading = false
this.isUploadingImage = false
return
const fileSize = compressedFile.size
if (fileSize > 500000) {
parentEpml.request('showSnackBar', get("chatpage.cchange26"))
this.isLoading = false
this.isUploadingImage = false
return
}
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
}
}
const messageObject = {
messageText: trimmedMessage,
images: [{
service: "QCHAT_IMAGE",
name: userName,
service: service,
name: name,
identifier: identifier,
}],
isImageDeleted: false,
@ -3988,6 +4036,7 @@ class ChatPage extends LitElement {
version: 3
}
const stringifyMessageObject = JSON.stringify(messageObject)
this.removeImage()
return this.sendMessage({messageText: stringifyMessageObject, typeMessage, chatReference: undefined, isForward: false, isReceipient, _chatId, _publicKey, messageQueue})
} else if (outSideMsg && outSideMsg.type === 'gif') {
const userName = await getName(this.selectedAddress.address)

45
plugins/plugins/core/components/ChatRightPanelResources.js

@ -21,6 +21,7 @@ import {
translateUnsafeHTML,
registerTranslateConfig,
} from 'lit-translate';
import { generateIdFromAddresses } from '../../utils/id-generation';
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent });
@ -51,7 +52,8 @@ class ChatRightPanelResources extends LitElement {
images: { type: Array },
viewImage: { 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.myName =
window.parent.reduxStore.getState().app.accountInfo.names[0].name;
this.myAddress =
window.parent.reduxStore.getState().app.selectedAddress.address;
this.autoView =false
this.onlyMyImages = true
}
@ -237,18 +241,18 @@ class ChatRightPanelResources extends LitElement {
font-family: Montserrat, sans-serif;
font-weight: 600;
color: var(--black);
padding-left: 5px;
}
`;
}
async getMoreImages(reset) {
try {
console.log({reset})
if(reset){
this.images = []
}
const groupPart = this.isReceipient
? `direct_${this._chatId.slice(-15)}`
? `direct_${generateIdFromAddresses(this._chatId, this.myAddress)}`
: `group_${this._chatId}`;
let offset = reset ? 0 : this.images.length;
@ -282,7 +286,6 @@ class ChatRightPanelResources extends LitElement {
}
async updated(changedProperties) {
console.log({ changedProperties });
if (changedProperties && changedProperties.has('_chatId')) {
this.images = [];
this.getMoreImages(true);
@ -315,7 +318,6 @@ class ChatRightPanelResources extends LitElement {
if (!entries[0].isIntersecting) {
return;
} else {
console.log('hello', this.images)
if (this.images.length < 20) {
return;
}
@ -340,7 +342,6 @@ class ChatRightPanelResources extends LitElement {
}
render() {
console.log('hello resources3', this.images);
return html`
<div class="container">
@ -368,7 +369,7 @@ class ChatRightPanelResources extends LitElement {
<div id="viewElement" class="container-body">
${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>
@ -407,7 +408,9 @@ class ImageParent extends LitElement {
images: { type: Array },
viewImage: { type: Boolean },
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.errorMessage = '';
this.successMessage = '';
this.isImgLoaded = false
this.images = [];
this.viewImage = false;
this.myName =
@ -584,6 +587,17 @@ class ImageParent extends LitElement {
.image-container {
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() {
return html`
${!this.autoView && !this.viewImage && this.myName !== this.image.name
@ -639,8 +658,14 @@ class ImageParent extends LitElement {
service: this.image.service,
identifier: this.image.identifier,
}}
.onLoad=${()=> this.onLoad()}
></reusable-image>
<
${this.isImgLoaded ? html`
<div class="actions-parent">
<button class="repost-btn" @click=${()=> this.repost(this.image)}>repost</button>
</div>
` : ''}
</div>
`
: ''}

7
plugins/plugins/core/components/ChatScroller.js

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

8
plugins/plugins/core/components/ReusableImage.js

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

14
plugins/plugins/utils/id-generation.js

@ -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);
}
Loading…
Cancel
Save