Skip to content

Commit

Permalink
Merge pull request #78 from show-karma/feat/multi-dao
Browse files Browse the repository at this point in the history
Feat/multi dao
  • Loading branch information
andremury authored Dec 19, 2023
2 parents b00dad5 + fadd345 commit d979e8c
Show file tree
Hide file tree
Showing 30 changed files with 534 additions and 261 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ Karma discourse plugin can be used by DAOs on their forum to display forum user'

## Installation

This plugin can be installed on both self-hosted instances and managed hosting. We have experience working with managed hosting providers to install our plugin. If you need help with installation, contact us at info@showkarma.xyz
This plugin can be installed on both self-hosted instances and managed hosting. We have experience working with managed hosting providers to install our plugin. If you need help with installation, contact us at info@karmahq.xyz


__Step 1__: To install the plugin, you can follow the [Install Plugins in Discourse](https://meta.discourse.org/t/install-plugins-in-discourse/19157) official instructions.

__Step 2__: After the installation, the user should go to the plugins page (Admin -> Plugins) and hit Settings under `Karma` plugin. Then, set the Dao Name as registered at [Karma](https://showkarma.xyz).
__Step 2__: After the installation, the user should go to the plugins page (Admin -> Plugins) and hit Settings under `Karma` plugin. Then, set the Dao Name as registered at [Karma](https://karmahq.xyz).
![plugin-page](./docs/assets/plugins.png)

---
Expand Down
7 changes: 4 additions & 3 deletions app/controllers/karma_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ class KarmaScore::KarmaController < ::ApplicationController
before_action :ensure_logged_in

# api_url = "https://api.karmahq.xyz/api/discourse"
attr_accessor :api_url, :api_token, :delegate_thread_id, :dao_name, :headers
attr_accessor :api_url, :api_token, :delegate_thread_id, :dao_names, :headers

def initialize()
@dao_name = SiteSetting.DAO_name
@dao_names = SiteSetting.DAO_names
@api_token = SiteSetting.Karma_API_Key
@delegate_thread_id = SiteSetting.Delegate_pitch_thread_id
@api_url = "https://api.karmahq.xyz/api/forum-user"
Expand All @@ -31,7 +31,7 @@ def save_vote_reason
recommendation = params.require(:recommendation)
thread_id = params.require(:threadId)
post_id = params.require(:postId)

dao_name = params.require(:daoName)
begin
discourse_handle = current_user.username

Expand Down Expand Up @@ -72,6 +72,7 @@ def save_delegate_pitch
post_id = params.require(:postId)
public_address = params.require(:publicAddress)
forum = params.require(:forum)
dao_name = params.require(:daoName)
begin
discourse_handle = current_user.username

Expand Down
9 changes: 6 additions & 3 deletions assets/javascripts/discourse/components/delegate-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default Component.extend({
profile: {},
isOpen: false,
noneLabel: "delegate_actions.dropdown_none_label",
daoName: "",

delegateVisible: false,

Expand All @@ -23,17 +24,19 @@ export default Component.extend({

async fetchProfile() {
try {
const cli = new KarmaApiClient(this.siteSettings.DAO_name);
const cli = new KarmaApiClient(this.daoName);
const profile = await cli.fetchUser(this.currentUser?.username);
set(this, "profile", profile);
} catch (error) {}
} catch (error) { }
},

async init() {
this._super(...arguments);
this.fetchProfile();
this._super(...arguments);
const cli = new KarmaApiClient(this.siteSettings.DAO_name, "");
this.daoName = window.selectedDao;

const cli = new KarmaApiClient(this.daoName, "");
if (this.session) {
try {
await cli.checkHealth();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export default Component.extend({
let isDefaultFields = true;
if (this.profile.address) {
const karma = new KarmaApiClient(
this.siteSettings.DAO_name,
this.siteSettings.DAO_names,
this.profile.address
);
try {
Expand All @@ -149,7 +149,7 @@ export default Component.extend({
async post() {
let postId = this.postId;
const karma = new KarmaApiClient(
this.siteSettings.DAO_name,
this.siteSettings.DAO_names,
this.form.publicAddress
);

Expand Down
41 changes: 31 additions & 10 deletions assets/javascripts/discourse/components/karma-stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,55 @@ export default Component.extend({

shouldShowActionButtons: false,

daoName: "",

availableDaos: [],

karmaDelegatorsUrl: computed(function () {
return `https://karmahq.xyz/dao/${this.siteSettings.DAO_name}/delegators/${this.profile.username}`;
return `https://karmahq.xyz/dao/${this.daoName?.toLowerCase()}/delegators/${this.profile.username}`;
}),

setProfile(profile) {
set(this, "profile", profile);
},

init() {
this._super(...arguments);
set(this, 'daoName', window.selectedDao?.[0]?.toUpperCase() + window.selectedDao?.slice(1));
set(this, 'availableDaos', this.siteSettings.DAO_names?.split(",").map(
name => ({ name, select: () => this.selectDao(name) })));
},

async didReceiveAttrs() {
this._super(...arguments);
await this.fetchProfile();
},

@action
selectDao(daoName) {
if(!daoName) { return };

Check failure on line 43 in assets/javascripts/discourse/components/karma-stats.js

View workflow job for this annotation

GitHub Actions / build

Missing semicolon
if(!this.availableDaos.find(d => d.name === daoName)) { return };

Check failure on line 44 in assets/javascripts/discourse/components/karma-stats.js

View workflow job for this annotation

GitHub Actions / build

Missing semicolon
set(this, 'daoName', daoName);
window.selectedDao = daoName;
this.fetchProfile();
},

@action
async fetchProfile() {
const profile = await KarmaStats.start(
30,
{ SiteSettings: this.siteSettings },
"#" + this.wrapperId
"#" + this.wrapperId,
this.username
);
this.setProfile(profile);
set(
this,
"shouldShowActionButtons",
this.session &&
profile.username &&
this.currentUser &&
profile?.username === this.currentUser?.username
profile.username &&
this.currentUser &&
profile?.username === this.currentUser?.username
);
},

async didReceiveAttrs() {
this._super(...arguments);
await this.fetchProfile();
},
});
19 changes: 16 additions & 3 deletions assets/javascripts/discourse/components/profile-summary-votes.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Component from "@ember/component";
import { inject as service } from "@ember/service";
import { computed, set } from "@ember/object";
import { computed, set, observer } from "@ember/object";

Check failure on line 3 in assets/javascripts/discourse/components/profile-summary-votes.js

View workflow job for this annotation

GitHub Actions / build

Member 'observer' of the import declaration should be sorted alphabetically

Check failure on line 3 in assets/javascripts/discourse/components/profile-summary-votes.js

View workflow job for this annotation

GitHub Actions / build

'observer' is defined but never used
import VotingHistory from "../../lib/voting-history/index";
import KarmaApiClient from "../../lib/karma-api-client";

Expand All @@ -17,6 +17,10 @@ export default Component.extend({

count: 0,

daoName: "",

oldDaoName: "",

shouldShowActionButtons: computed(function () {
return (
this.session &&
Expand All @@ -28,6 +32,7 @@ export default Component.extend({

async fetchVotes() {
set(this, "fetched", false);
set(this, "votes", []);
const votes = await VotingHistory.start(this.profile, {
SiteSettings: this.siteSettings,
});
Expand All @@ -37,12 +42,13 @@ export default Component.extend({

async init() {
this._super(...arguments);
this.daoName = this.oldDaoName = window.selectedDao;
const cli = new KarmaApiClient(this.daoName, "");
if (this.session) {
const cli = new KarmaApiClient(this.siteSettings.DAO_name, "");
try {
const { allowance } = await cli.isApiAllowed(this.session.csrfToken);
set(this, "hasSetApiKey", !!allowance);
} catch {}
} catch { }
}
},

Expand All @@ -53,4 +59,11 @@ export default Component.extend({
this.fetchVotes();
}
},

didUpdate() {
if (this.profile.address && this.oldDaoName.toLowerCase() !== this.daoName.toLowerCase()) {
set(this, 'oldDaoName', this.daoName)

Check failure on line 65 in assets/javascripts/discourse/components/profile-summary-votes.js

View workflow job for this annotation

GitHub Actions / build

Missing semicolon
this.fetchVotes();
}
}
});
30 changes: 24 additions & 6 deletions assets/javascripts/discourse/components/proposal-banner.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,50 @@ export default Component.extend({

tokenContract: "",

daoName: "",

availableDaos: [],

logo: computed(function () {
return this.siteSettings.Custom_banner_icon_url || this.siteSettings.logo;
}),

init() {
this._super(...arguments);
this.daoName = window.selectedDao;
set(this, 'availableDaos', this.siteSettings.DAO_names?.split(",").map(
name => ({ name, select: () => this.selectDao(name) })));
},

@action
selectDao(daoName) {
if (!daoName) { return };

Check failure on line 42 in assets/javascripts/discourse/components/proposal-banner.js

View workflow job for this annotation

GitHub Actions / build

Missing semicolon
if (!this.availableDaos.find(d => d.name === daoName)) { return };

Check failure on line 43 in assets/javascripts/discourse/components/proposal-banner.js

View workflow job for this annotation

GitHub Actions / build

Missing semicolon
set(this, 'daoName', daoName);
window.selectedDao = daoName;
set(this, 'fetched', false);
this.fetchDataProposals();
},

@action
toggleBanner() {
set(this, "openClass", this.openClass === "opened" ? "" : "opened");
this.setBannerHeight();
},

async getGovContractAddr() {
const tokenAddress = await getGovAddrFromYml(this.siteSettings.DAO_name);
const tokenAddress = await getGovAddrFromYml(this.daoName);
set(this, "tokenContract", tokenAddress);
},

async fetchDataProposals() {
const {
Banner_past_proposal_days: daysAgo,
daoIds,

Check failure on line 64 in assets/javascripts/discourse/components/proposal-banner.js

View workflow job for this annotation

GitHub Actions / build

'daoIds' is assigned a value but never used
DAO_name,
} = this.siteSettings;
// Fix this workaround when voting history is refactored into components
const graphqlIds = (window.daoIds =
window.daoIds ??
daoIds ??
(await fetchDaoSnapshotAndOnChainIds(DAO_name)));
const graphqlIds =
(await fetchDaoSnapshotAndOnChainIds(this.daoName));

let onChain = [];
if (
Expand Down
9 changes: 8 additions & 1 deletion assets/javascripts/discourse/components/vote-breakdown.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Component from "@ember/component";
import { set } from "@ember/object";
import { set, action } from "@ember/object";

Check failure on line 2 in assets/javascripts/discourse/components/vote-breakdown.js

View workflow job for this annotation

GitHub Actions / build

Member 'action' of the import declaration should be sorted alphabetically
import { shortenNumber } from "../../lib/shorten-number";

export default Component.extend({
Expand All @@ -9,6 +9,8 @@ export default Component.extend({

loading: false,

proposalUrl: "",

sortVotes(votes) {
if (
Array.isArray(votes) &&
Expand Down Expand Up @@ -72,4 +74,9 @@ export default Component.extend({
const truncatedArray = this.truncateVotesArray(this.sortVotes(votesPct));
set(this, "values", truncatedArray);
},

@action
redirect() {
window.open(this.link, "_blank");
},
});
Loading

0 comments on commit d979e8c

Please sign in to comment.