diff --git a/qortal-ui-plugins/plugins/core/group-management/group-management.src.js b/qortal-ui-plugins/plugins/core/group-management/group-management.src.js
index 9c817b85..8380590c 100644
--- a/qortal-ui-plugins/plugins/core/group-management/group-management.src.js
+++ b/qortal-ui-plugins/plugins/core/group-management/group-management.src.js
@@ -1,4 +1,3 @@
-
import { LitElement, html, css } from 'lit-element'
import { render } from 'lit-html'
import { Epml } from '../../../epml.js'
@@ -42,6 +41,7 @@ class GroupManagement extends LitElement {
--mdc-theme-primary: rgb(3, 169, 244);
--paper-input-container-focus-color: var(--mdc-theme-primary);
}
+
#group-management-page {
background: #fff;
padding: 12px 24px;
@@ -68,7 +68,6 @@ class GroupManagement extends LitElement {
.divCard {
border: 1px solid #eee;
padding: 1em;
- /** box-shadow: 0 1px 1px 0 rgba(0,0,0,0.14), 0 2px 1px -1px rgba(0,0,0,0.12), 0 1px 2px 0 rgba(0,0,0,0.20); **/
box-shadow: 0 .3px 1px 0 rgba(0,0,0,0.14), 0 1px 1px -1px rgba(0,0,0,0.12), 0 1px 2px 0 rgba(0,0,0,0.20);
margin-bottom: 2em;
}
@@ -86,14 +85,17 @@ class GroupManagement extends LitElement {
display: hidden !important;
visibility: none !important;
}
+
.details {
display: flex;
font-size: 18px;
}
+
span {
font-size: 18px;
word-break: break-all;
}
+
select {
padding: 13px 20px;
width: 100%;
@@ -101,19 +103,17 @@ class GroupManagement extends LitElement {
color: #555;
font-weight: 400;
}
+
.title {
font-weight:600;
font-size:12px;
line-height: 32px;
opacity: 0.66;
}
+
.itemList {
padding:0;
}
- /* .itemList > * {
- padding-left:24px;
- padding-right:24px;
- } */
`
}
@@ -128,6 +128,9 @@ class GroupManagement extends LitElement {
this.recipientPublicKey = ''
this.btnDisable = false
this.isLoading = false
+ this.createFee = 0.001
+ this.joinFee = 0.001
+ this.leaveFee = 0.001
}
render() {
@@ -138,6 +141,23 @@ class GroupManagement extends LitElement {
this.shadowRoot.querySelector('#createGroupDialog').show()}>addCreate Group
+
+
Your Joined Groups
+
+
+
+ {
+ render(html`${this.renderRole(data.item)}`, root)
+ }}>
+ {
+ render(html`${this.renderManageButton(data.item)}`, root)
+ }}>
+
+ ${this.isEmptyArray(this.joinedGroups) ? html`
+ Not a member of any groups!
+ `: ''}
+
+
Public Groups
@@ -145,32 +165,14 @@ class GroupManagement extends LitElement {
{
- render(html` this.joinGroup(data.item)}>queueJoin`, root)
- }}>
-
+ render(html` this.joinGroup(data.item)}>queueJoin`, root)
+ }}>
${this.isEmptyArray(this.publicGroups) ? html`
No Open Public Groups available!
`: ''}
-
-
Your Joined Groups
-
-
-
- {
- render(html`${this.renderRole(data.item)}`, root)
- }}>
- {
- render(html`${this.renderManageButton(data.item)}`, root)
- }}>
-
- ${this.isEmptyArray(this.joinedGroups) ? html`
- Not a member of any groups!
- `: ''}
-
-
@@ -415,6 +417,135 @@ class GroupManagement extends LitElement {
`
}
+ firstUpdated() {
+ this.unitCreateFee()
+ this.unitJoinFee()
+ this.unitLeaveFee()
+
+ const getOpenPublicGroups = async () => {
+ let openG = await parentEpml.request('apiCall', {
+ url: `/groups?limit=0&reverse=true`
+ })
+ let myGs = openG.filter(myG => myG.isOpen === true)
+ return myGs
+ }
+
+ const getJoinedGroups = async () => {
+ let joinedG = await parentEpml.request('apiCall', {
+ url: `/groups/member/${this.selectedAddress.address}`
+ })
+ return joinedG
+ }
+
+ const getOpen_JoinedGroups = async () => {
+ let _joinedGroups = await getJoinedGroups()
+ let _publicGroups = await getOpenPublicGroups()
+ let results = _publicGroups.filter(myOpenGroup => {
+ let value = _joinedGroups.some(myJoinedGroup => myOpenGroup.groupId === myJoinedGroup.groupId)
+ return !value
+ });
+ this.publicGroups = results
+ this.joinedGroups = _joinedGroups
+ setTimeout(getOpen_JoinedGroups, this.config.user.nodeSettings.pingInterval)
+ }
+
+ window.addEventListener("contextmenu", (event) => {
+ event.preventDefault();
+ this._textMenu(event)
+ });
+
+ window.addEventListener("click", () => {
+ parentEpml.request('closeCopyTextMenu', null)
+ });
+
+ window.onkeyup = (e) => {
+ if (e.keyCode === 27) {
+ parentEpml.request('closeCopyTextMenu', null)
+ }
+ }
+
+ let configLoaded = false
+
+ parentEpml.ready().then(() => {
+ parentEpml.subscribe('selected_address', async selectedAddress => {
+ this.selectedAddress = {}
+ selectedAddress = JSON.parse(selectedAddress)
+ if (!selectedAddress || Object.entries(selectedAddress).length === 0) return
+ this.selectedAddress = selectedAddress
+ })
+ parentEpml.subscribe('config', c => {
+ if (!configLoaded) {
+ setTimeout(getOpen_JoinedGroups, 1)
+ configLoaded = true
+ }
+ this.config = JSON.parse(c)
+ })
+ parentEpml.subscribe('copy_menu_switch', async value => {
+ if (value === 'false' && window.getSelection().toString().length !== 0) {
+ this.clearSelection()
+ }
+ })
+ })
+ parentEpml.imReady()
+ }
+
+ async unitCreateFee() {
+ 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 url = `${nodeUrl}/transactions/unitfee?txType=CREATE_GROUP`;
+ await fetch(url)
+ .then((response) => {
+ if (response.ok) {
+ return response.json();
+ }
+ return Promise.reject(response);
+ })
+ .then((json) => {
+ this.createFee = (Number(json) / 1e8).toFixed(8);
+ })
+ .catch((response) => {
+ console.log(response.status, response.statusText, 'Need Core Update');
+ })
+ }
+
+ async unitJoinFee() {
+ 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 url = `${nodeUrl}/transactions/unitfee?txType=JOIN_GROUP`;
+ await fetch(url)
+ .then((response) => {
+ if (response.ok) {
+ return response.json();
+ }
+ return Promise.reject(response);
+ })
+ .then((json) => {
+ this.joinFee = (Number(json) / 1e8).toFixed(8);
+ })
+ .catch((response) => {
+ console.log(response.status, response.statusText, 'Need Core Update');
+ })
+ }
+
+ async unitLeaveFee() {
+ 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 url = `${nodeUrl}/transactions/unitfee?txType=LEAVE_GROUP`;
+ await fetch(url)
+ .then((response) => {
+ if (response.ok) {
+ return response.json();
+ }
+ return Promise.reject(response);
+ })
+ .then((json) => {
+ this.leaveFee = (Number(json) / 1e8).toFixed(8);
+ })
+ .catch((response) => {
+ console.log(response.status, response.statusText, 'Need Core Update');
+ })
+ }
+
resetDefaultSettings() {
this.error = false
this.message = ''
@@ -424,28 +555,24 @@ class GroupManagement extends LitElement {
manageGroupOwner(groupObj) {
this.resetDefaultSettings()
this.manageGroupObj = groupObj
-
this.shadowRoot.querySelector('#manageGroupOwnerDialog').show()
}
manageGroupAdmin(groupObj) {
this.resetDefaultSettings()
this.manageGroupObj = groupObj
-
this.shadowRoot.querySelector('#manageGroupAdminDialog').show()
}
joinGroup(groupObj) {
this.resetDefaultSettings()
this.joinGroupObj = groupObj
-
this.shadowRoot.querySelector('#joinDialog').show()
}
leaveGroup(groupObj) {
this.resetDefaultSettings()
this.leaveGroupObj = groupObj
-
this.shadowRoot.querySelector('#leaveDialog').show()
}
@@ -479,7 +606,6 @@ class GroupManagement extends LitElement {
}
_textMenu(event) {
-
const getSelectedText = () => {
var text = "";
if (typeof window.getSelection != "undefined") {
@@ -493,108 +619,18 @@ class GroupManagement extends LitElement {
const checkSelectedTextAndShowMenu = () => {
let selectedText = getSelectedText();
if (selectedText && typeof selectedText === 'string') {
-
let _eve = { pageX: event.pageX, pageY: event.pageY, clientX: event.clientX, clientY: event.clientY }
-
let textMenuObject = { selectedText: selectedText, eventObject: _eve, isFrame: true }
-
parentEpml.request('openCopyTextMenu', textMenuObject)
}
}
-
checkSelectedTextAndShowMenu()
}
-
- firstUpdated() {
-
- // Call getNamesGrid
- // this.getNamesGrid()
-
- const getOpenPublicGroups = async () => {
- let openG = await parentEpml.request('apiCall', {
- url: `/groups?limit=0&reverse=true`
- })
-
- let myGs = openG.filter(myG => myG.isOpen === true)
- return myGs
- }
-
- const getJoinedGroups = async () => {
- let joinedG = await parentEpml.request('apiCall', {
- url: `/groups/member/${this.selectedAddress.address}`
- })
-
- return joinedG
- }
-
- const getOpen_JoinedGroups = async () => {
- // this.publicGroups = []
- // this.joinedGroups = []
-
- let _joinedGroups = await getJoinedGroups()
- let _publicGroups = await getOpenPublicGroups()
-
- let results = _publicGroups.filter(myOpenGroup => {
- let value = _joinedGroups.some(myJoinedGroup => myOpenGroup.groupId === myJoinedGroup.groupId)
- return !value
- });
- this.publicGroups = results
- this.joinedGroups = _joinedGroups
- setTimeout(getOpen_JoinedGroups, this.config.user.nodeSettings.pingInterval)
- }
-
- window.addEventListener("contextmenu", (event) => {
-
- event.preventDefault();
- this._textMenu(event)
- });
-
- window.addEventListener("click", () => {
-
- parentEpml.request('closeCopyTextMenu', null)
- });
-
- window.onkeyup = (e) => {
- if (e.keyCode === 27) {
-
- parentEpml.request('closeCopyTextMenu', null)
- }
- }
-
- let configLoaded = false
-
- parentEpml.ready().then(() => {
- parentEpml.subscribe('selected_address', async selectedAddress => {
- this.selectedAddress = {}
- selectedAddress = JSON.parse(selectedAddress)
- if (!selectedAddress || Object.entries(selectedAddress).length === 0) return
- this.selectedAddress = selectedAddress
- })
- parentEpml.subscribe('config', c => {
- if (!configLoaded) {
- setTimeout(getOpen_JoinedGroups, 1)
- configLoaded = true
- }
- this.config = JSON.parse(c)
- })
- parentEpml.subscribe('copy_menu_switch', async value => {
-
- if (value === 'false' && window.getSelection().toString().length !== 0) {
-
- this.clearSelection()
- }
- })
- })
-
-
- parentEpml.imReady()
- }
-
async createGroup(e) {
// Reset Default Settings...
this.resetDefaultSettings()
-
+ const createFeeInput = this.createFee
const groupNameInput = this.shadowRoot.getElementById("groupNameInput").value
const groupDescInput = this.shadowRoot.getElementById("groupDescInput").value
const groupTypeInput = this.shadowRoot.getElementById("groupTypeInput").value
@@ -628,11 +664,11 @@ class GroupManagement extends LitElement {
// Make Transaction Request
const makeTransactionRequest = async (_groupTypeInput, _groupApprovalInput, _groupMinDelayInput, _groupMaxDelayInput, lastRef) => {
-
let myTxnrequest = await parentEpml.request('transaction', {
type: 22,
nonce: this.selectedAddress.nonce,
params: {
+ fee: createFeeInput,
registrantAddress: this.selectedAddress.address,
rGroupName: groupNameInput,
rGroupDesc: groupDescInput,
@@ -643,15 +679,10 @@ class GroupManagement extends LitElement {
lastReference: lastRef,
}
})
-
return myTxnrequest
}
- // FAILED txnResponse = {success: false, message: "User declined transaction"}
- // SUCCESS txnResponse = { success: true, data: true }
-
const getTxnRequestResponse = (txnResponse) => {
-
if (txnResponse.success === false && txnResponse.message) {
this.error = true
this.message = txnResponse.message
@@ -695,12 +726,12 @@ class GroupManagement extends LitElement {
// Call validateReceiver
validateReceiver()
}
- // this.resetDefaultSettings()
}
async _joinGroup(groupId, groupName) {
// Reset Default Settings...
this.resetDefaultSettings()
+ const joinFeeInput = this.joinFee
this.isLoading = true
@@ -715,7 +746,6 @@ class GroupManagement extends LitElement {
const validateReceiver = async () => {
let lastRef = await getLastRef();
-
this.resetDefaultSettings()
let myTransaction = await makeTransactionRequest(lastRef)
getTxnRequestResponse(myTransaction)
@@ -724,26 +754,21 @@ class GroupManagement extends LitElement {
// Make Transaction Request
const makeTransactionRequest = async (lastRef) => {
-
let myTxnrequest = await parentEpml.request('transaction', {
type: 31,
nonce: this.selectedAddress.nonce,
params: {
+ fee: joinFeeInput,
registrantAddress: this.selectedAddress.address,
rGroupName: groupName,
rGroupId: groupId,
lastReference: lastRef,
}
})
-
return myTxnrequest
}
- // FAILED txnResponse = {success: false, message: "User declined transaction"}
- // SUCCESS txnResponse = { success: true, data: true }
-
const getTxnRequestResponse = (txnResponse) => {
-
if (txnResponse.success === false && txnResponse.message) {
this.error = true
this.message = txnResponse.message
@@ -757,15 +782,14 @@ class GroupManagement extends LitElement {
throw new Error(txnResponse)
}
}
-
validateReceiver()
-
this.resetDefaultSettings()
}
async _leaveGroup(groupId, groupName) {
// Reset Default Settings...
this.resetDefaultSettings()
+ const leaveFeeInput = this.leaveFee
this.isLoading = true
@@ -780,7 +804,6 @@ class GroupManagement extends LitElement {
const validateReceiver = async () => {
let lastRef = await getLastRef();
-
this.resetDefaultSettings()
let myTransaction = await makeTransactionRequest(lastRef)
getTxnRequestResponse(myTransaction)
@@ -789,24 +812,20 @@ class GroupManagement extends LitElement {
// Make Transaction Request
const makeTransactionRequest = async (lastRef) => {
-
let myTxnrequest = await parentEpml.request('transaction', {
type: 32,
nonce: this.selectedAddress.nonce,
params: {
+ fee: leaveFeeInput,
registrantAddress: this.selectedAddress.address,
rGroupName: groupName,
rGroupId: groupId,
lastReference: lastRef,
}
})
-
return myTxnrequest
}
- // FAILED txnResponse = {success: false, message: "User declined transaction"}
- // SUCCESS txnResponse = { success: true, data: true }
-
const getTxnRequestResponse = (txnResponse) => {
if (txnResponse.success === false && txnResponse.message) {
@@ -822,14 +841,11 @@ class GroupManagement extends LitElement {
throw new Error(txnResponse)
}
}
-
validateReceiver()
-
this.resetDefaultSettings()
}
clearSelection() {
-
window.getSelection().removeAllRanges()
window.parent.getSelection().removeAllRanges()
}