├── tests ├── .gitignore ├── tsconfig.json ├── package.json └── src │ └── posts │ ├── directory │ └── listing.test.ts │ └── posts │ └── post.test.ts ├── ui ├── src │ ├── vite-env.d.ts │ ├── utils │ │ └── hash.ts │ ├── herd │ │ ├── directory │ │ │ ├── types.ts │ │ │ ├── ListingLink.vue │ │ │ └── AllListings.vue │ │ ├── posts │ │ │ ├── types.ts │ │ │ ├── CommentsForPost.vue │ │ │ ├── AllPosts.vue │ │ │ ├── CreateComment.vue │ │ │ ├── EditComment.vue │ │ │ ├── PostVotes.vue │ │ │ ├── CommentVotes.vue │ │ │ ├── CreatePost.vue │ │ │ ├── EditPost.vue │ │ │ ├── PostListItem.vue │ │ │ ├── PostDetail.vue │ │ │ └── CommentDetail.vue │ │ ├── profiles │ │ │ ├── MyAgentProfileDetail.vue │ │ │ ├── AgentProfileDetail.vue │ │ │ └── AgentProfile.vue │ │ └── herds │ │ │ ├── HerdPasswordModal.vue │ │ │ ├── WateringHole.vue │ │ │ ├── CreateHerd.vue │ │ │ └── HerdDetail.vue │ ├── components │ │ ├── BaseSpinner.vue │ │ ├── BaseContentHidden.vue │ │ ├── BaseEditDeleteButtons.vue │ │ ├── BaseThemeSelect.vue │ │ ├── BaseVoteInput.vue │ │ └── HomeNavbar.vue │ ├── style.css │ ├── stores │ │ └── theme.ts │ ├── routes.ts │ ├── main.ts │ └── App.vue ├── postcss.config.cjs ├── .gitignore ├── .eslintrc.js ├── index.html ├── tsconfig.json ├── vite.config.ts ├── tailwind.config.js └── package.json ├── dnas ├── directory │ ├── zomes │ │ ├── integrity │ │ │ ├── profiles │ │ │ │ ├── src │ │ │ │ │ └── lib.rs │ │ │ │ └── Cargo.toml │ │ │ └── directory │ │ │ │ ├── Cargo.toml │ │ │ │ └── src │ │ │ │ └── listing.rs │ │ └── coordinator │ │ │ ├── profiles │ │ │ ├── src │ │ │ │ └── lib.rs │ │ │ └── Cargo.toml │ │ │ └── directory │ │ │ ├── src │ │ │ ├── lib.rs │ │ │ ├── all_listings.rs │ │ │ └── listing.rs │ │ │ └── Cargo.toml │ └── workdir │ │ └── dna.yaml └── herd │ ├── zomes │ ├── integrity │ │ ├── herd │ │ │ ├── src │ │ │ │ ├── herd.rs │ │ │ │ └── lib.rs │ │ │ └── Cargo.toml │ │ └── posts │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ ├── lib.rs │ │ │ ├── votes.rs │ │ │ ├── post.rs │ │ │ ├── comment.rs │ │ │ └── validate.rs │ └── coordinator │ │ ├── posts │ │ ├── src │ │ │ ├── lib.rs │ │ │ ├── my_posts.rs │ │ │ ├── all_posts.rs │ │ │ ├── utils.rs │ │ │ ├── post.rs │ │ │ └── comment.rs │ │ └── Cargo.toml │ │ └── herd │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs │ └── workdir │ └── dna.yaml ├── assets └── wildebeests-stable-diffusion.jpg ├── .vscode └── settings.json ├── workdir ├── web-happ.yaml └── happ.yaml ├── .gitignore ├── flake.nix ├── Cargo.toml ├── package.json ├── README.md ├── TODO.md └── flake.lock /tests/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | .nyc_output/ -------------------------------------------------------------------------------- /ui/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /dnas/directory/zomes/integrity/profiles/src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate hc_zome_profiles_integrity; 2 | -------------------------------------------------------------------------------- /dnas/directory/zomes/coordinator/profiles/src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate hc_zome_profiles_coordinator; 2 | -------------------------------------------------------------------------------- /assets/wildebeests-stable-diffusion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattyg/herddit/HEAD/assets/wildebeests-stable-diffusion.jpg -------------------------------------------------------------------------------- /ui/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /ui/src/utils/hash.ts: -------------------------------------------------------------------------------- 1 | import {isEqual} from "lodash"; 2 | 3 | export const areHashesEqual = (hash1: Uint8Array, hash2: Uint8Array) => isEqual(hash1, hash2); -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "nixEnvSelector.suggestion": false, 3 | "nixEnvSelector.nixFile": "${workspaceRoot}/default.nix", 4 | "editor.tabSize": 2 5 | } -------------------------------------------------------------------------------- /workdir/web-happ.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | manifest_version: "1" 3 | name: herddit 4 | ui: 5 | bundled: "../ui/dist.zip" 6 | happ_manifest: 7 | bundled: "./herddit.happ" 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /node_modules/ 3 | /dist/ 4 | /target/ 5 | /.cargo/ 6 | *.happ 7 | *.webhapp 8 | *.zip 9 | *.dna 10 | .hc* 11 | .hc 12 | .running 13 | .templates 14 | -------------------------------------------------------------------------------- /ui/src/herd/directory/types.ts: -------------------------------------------------------------------------------- 1 | import { DnaHash } from '@holochain/client'; 2 | 3 | 4 | export interface Listing { 5 | title: string; 6 | description: string; 7 | network_seed: string; 8 | dna: DnaHash; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /dnas/directory/zomes/coordinator/directory/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod all_listings; 2 | pub mod listing; 3 | use hdk::prelude::*; 4 | 5 | #[hdk_extern] 6 | pub fn init(_: ()) -> ExternResult { 7 | Ok(InitCallbackResult::Pass) 8 | } 9 | -------------------------------------------------------------------------------- /dnas/herd/zomes/integrity/herd/src/herd.rs: -------------------------------------------------------------------------------- 1 | use hdi::prelude::*; 2 | 3 | pub fn validate_create_herd( 4 | action: EntryCreationAction, 5 | herd: Herd, 6 | ) -> ExternResult { 7 | 8 | Ok(ValidateCallbackResult::Valid) 9 | } -------------------------------------------------------------------------------- /ui/src/herd/posts/types.ts: -------------------------------------------------------------------------------- 1 | import { ActionHash } from '@holochain/client'; 2 | 3 | 4 | export interface Post { 5 | title: string; 6 | content: string; 7 | } 8 | 9 | 10 | export interface Comment { 11 | content: string; 12 | post_ah: ActionHash; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /dnas/herd/zomes/coordinator/posts/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod all_posts; 2 | pub mod comment; 3 | pub mod my_posts; 4 | pub mod post; 5 | pub mod utils; 6 | use hdk::prelude::*; 7 | 8 | #[hdk_extern] 9 | pub fn init(_: ()) -> ExternResult { 10 | Ok(InitCallbackResult::Pass) 11 | } 12 | -------------------------------------------------------------------------------- /dnas/herd/zomes/integrity/herd/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "herd_integrity" 3 | version = "0.0.1" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | name = "herd_integrity" 9 | 10 | [dependencies] 11 | hdi = { workspace = true } 12 | 13 | serde = { workspace = true } 14 | -------------------------------------------------------------------------------- /dnas/herd/zomes/integrity/posts/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "posts_integrity" 3 | version = "0.0.1" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | name = "posts_integrity" 9 | 10 | [dependencies] 11 | hdi = { workspace = true } 12 | 13 | serde = { workspace = true } 14 | -------------------------------------------------------------------------------- /dnas/directory/zomes/integrity/directory/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "directory_integrity" 3 | version = "0.0.1" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | name = "directory_integrity" 9 | 10 | [dependencies] 11 | hdi = { workspace = true } 12 | 13 | serde = { workspace = true } 14 | -------------------------------------------------------------------------------- /dnas/herd/zomes/coordinator/herd/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "herd" 3 | version = "0.0.1" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | name = "herd" 9 | 10 | [dependencies] 11 | hdk = { workspace = true } 12 | 13 | serde = { workspace = true } 14 | 15 | herd_integrity = { workspace = true } 16 | -------------------------------------------------------------------------------- /dnas/herd/zomes/coordinator/posts/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "posts" 3 | version = "0.2.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | name = "posts" 9 | 10 | [dependencies] 11 | hdk = { workspace = true } 12 | 13 | serde = { workspace = true } 14 | 15 | posts_integrity = { workspace = true } 16 | -------------------------------------------------------------------------------- /ui/.gitignore: -------------------------------------------------------------------------------- 1 | ## editors 2 | /.idea 3 | /.vscode 4 | 5 | ## system files 6 | .DS_Store 7 | 8 | ## npm 9 | /node_modules/ 10 | /npm-debug.log 11 | 12 | ## testing 13 | /coverage/ 14 | 15 | ## temp folders 16 | /.tmp/ 17 | 18 | # build 19 | /_site/ 20 | /dist/ 21 | /out-tsc/ 22 | 23 | storybook-static 24 | .rollup.cache 25 | *.tsbuildinfo -------------------------------------------------------------------------------- /dnas/directory/zomes/integrity/profiles/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "profiles_integrity" 3 | version = "0.0.1" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | name = "profiles_integrity" 9 | 10 | [dependencies] 11 | hc_zome_profiles_integrity = "0.2.0" 12 | hdi = { workspace = true } 13 | 14 | serde = { workspace = true } 15 | -------------------------------------------------------------------------------- /ui/src/components/BaseSpinner.vue: -------------------------------------------------------------------------------- 1 | . 12 | 13 | -------------------------------------------------------------------------------- /dnas/directory/zomes/coordinator/directory/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "directory" 3 | version = "0.2.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | name = "directory" 9 | 10 | [dependencies] 11 | hdk = { workspace = true } 12 | 13 | serde = { workspace = true } 14 | 15 | directory_integrity = { workspace = true } 16 | boba = "5.0.0" -------------------------------------------------------------------------------- /tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 7 | "allowSyntheticDefaultImports": true 8 | } 9 | } -------------------------------------------------------------------------------- /dnas/directory/zomes/coordinator/profiles/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "profiles" 3 | version = "0.1.2" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | name = "profiles" 9 | 10 | [dependencies] 11 | hdk = { workspace = true } 12 | 13 | serde = { workspace = true } 14 | 15 | profiles_integrity = { workspace = true } 16 | hc_zome_profiles_coordinator = "0.2.0" 17 | -------------------------------------------------------------------------------- /ui/src/style.css: -------------------------------------------------------------------------------- 1 | 2 | @tailwind base; 3 | @tailwind components; 4 | @tailwind utilities; 5 | 6 | 7 | html { 8 | font-size: 20px; 9 | } 10 | 11 | 12 | /* Not sure why I need to include this, 13 | since it should be included in tailwind already 14 | but it wasn't working in Tauri without it */ 15 | @keyframes spin { 16 | from { 17 | transform: rotate(0deg); 18 | } 19 | to { 20 | transform: rotate(360deg); 21 | } 22 | } -------------------------------------------------------------------------------- /ui/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true 5 | }, 6 | extends: [ 7 | 'eslint:recommended', 8 | 'plugin:vue/vue3-recommended', 9 | '@vue/eslint-config-typescript/recommended', 10 | ], 11 | overrides: [ 12 | ], 13 | parserOptions: { 14 | ecmaVersion: 'latest', 15 | sourceType: 'module' 16 | }, 17 | plugins: [ 18 | 'vue' 19 | ], 20 | rules: { 21 | 'vue/attribute-hyphenation': 'off' 22 | }, 23 | root: true 24 | } 25 | -------------------------------------------------------------------------------- /ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /dnas/herd/zomes/coordinator/herd/src/lib.rs: -------------------------------------------------------------------------------- 1 | use hdk::prelude::*; 2 | use herd_integrity::HerdInfo; 3 | 4 | #[hdk_extern] 5 | pub fn init(_: ()) -> ExternResult { 6 | Ok(InitCallbackResult::Pass) 7 | } 8 | 9 | #[hdk_extern] 10 | pub fn get_info(_: ()) -> ExternResult { 11 | let dna_properties = dna_info()?.modifiers.properties; 12 | 13 | let herd_info = HerdInfo::try_from(dna_properties) 14 | .map_err(|err| wasm_error!(WasmErrorInner::Guest(err.into())))?; 15 | 16 | Ok(herd_info) 17 | } 18 | -------------------------------------------------------------------------------- /ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "useDefineForClassFields": true, 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "strict": true, 8 | "jsx": "preserve", 9 | "sourceMap": true, 10 | "resolveJsonModule": true, 11 | "esModuleInterop": true, 12 | "lib": ["esnext", "dom"], 13 | "allowSyntheticDefaultImports": true, 14 | "skipLibCheck": true, 15 | "types": [ 16 | "vue3-toastify/global" 17 | ] 18 | }, 19 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] 20 | } 21 | -------------------------------------------------------------------------------- /ui/src/herd/profiles/MyAgentProfileDetail.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 19 | -------------------------------------------------------------------------------- /dnas/herd/zomes/coordinator/posts/src/my_posts.rs: -------------------------------------------------------------------------------- 1 | use hdk::prelude::*; 2 | use posts_integrity::*; 3 | #[hdk_extern] 4 | pub fn get_my_posts(author: AgentPubKey) -> ExternResult> { 5 | let links = get_links(author, LinkTypes::MyPosts, None)?; 6 | let get_input: Vec = links 7 | .into_iter() 8 | .filter_map(|link| ActionHash::try_from(link.target).ok()) 9 | .map(|target| GetInput::new(target.into(), GetOptions::default())) 10 | .collect(); 11 | let records = HDK.with(|hdk| hdk.borrow().get(get_input))?; 12 | let hashes: Vec = records 13 | .into_iter() 14 | .flatten() 15 | .map(|r| r.action_address().clone()) 16 | .collect(); 17 | Ok(hashes) 18 | } 19 | -------------------------------------------------------------------------------- /workdir/happ.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | manifest_version: "1" 3 | name: herddit 4 | description: ~ 5 | roles: 6 | - name: herd 7 | provisioning: 8 | strategy: create 9 | deferred: false 10 | dna: 11 | bundled: "../dnas/herd/workdir/herd.dna" 12 | modifiers: 13 | network_seed: ~ 14 | properties: ~ 15 | origin_time: ~ 16 | quantum_time: ~ 17 | version: ~ 18 | clone_limit: 1000000000 19 | - name: directory 20 | provisioning: 21 | strategy: create 22 | deferred: false 23 | dna: 24 | bundled: "../dnas/directory/workdir/directory.dna" 25 | modifiers: 26 | network_seed: ~ 27 | properties: ~ 28 | origin_time: ~ 29 | quantum_time: ~ 30 | version: ~ 31 | clone_limit: 0 32 | -------------------------------------------------------------------------------- /ui/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import vue from '@vitejs/plugin-vue'; 3 | import tailwindcss from 'tailwindcss'; 4 | import { viteStaticCopy } from 'vite-plugin-static-copy'; 5 | import path from 'node:path' 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig({ 9 | plugins: [ 10 | viteStaticCopy({ 11 | targets: [ 12 | { 13 | src: path.resolve(__dirname, '../node_modules/@shoelace-style/shoelace/dist/assets'), 14 | dest: path.resolve(__dirname, 'dist/shoelace') 15 | } 16 | ] 17 | }), 18 | vue({ 19 | template: { 20 | compilerOptions: { 21 | // treat all tags with a dash as custom elements 22 | isCustomElement: tag => tag.includes('-'), 23 | }, 24 | }, 25 | }), 26 | tailwindcss() 27 | ] 28 | }); 29 | -------------------------------------------------------------------------------- /dnas/herd/workdir/dna.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | manifest_version: "1" 3 | name: herd 4 | integrity: 5 | network_seed: ~ 6 | properties: 7 | title: herd 8 | origin_time: 1672608938336518 9 | zomes: 10 | - name: herd_integrity 11 | hash: ~ 12 | bundled: "../../../target/wasm32-unknown-unknown/release/herd_integrity.wasm" 13 | dependencies: ~ 14 | - name: posts_integrity 15 | hash: ~ 16 | bundled: "../../../target/wasm32-unknown-unknown/release/posts_integrity.wasm" 17 | dependencies: ~ 18 | coordinator: 19 | zomes: 20 | - name: herd 21 | hash: ~ 22 | bundled: "../../../target/wasm32-unknown-unknown/release/herd.wasm" 23 | dependencies: 24 | - name: herd_integrity 25 | - name: posts 26 | hash: ~ 27 | bundled: "../../../target/wasm32-unknown-unknown/release/posts.wasm" 28 | dependencies: 29 | - name: posts_integrity 30 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Flake for Holochain app development"; 3 | 4 | inputs = { 5 | nixpkgs.follows = "holochain-dev/nixpkgs"; 6 | 7 | holochain-dev = { 8 | url = "github:holochain/holochain"; 9 | inputs.versions.url = "github:holochain/holochain/?dir=versions/0_2"; 10 | }; 11 | }; 12 | 13 | outputs = inputs @ { ... }: 14 | inputs.holochain-dev.inputs.flake-parts.lib.mkFlake 15 | { 16 | inherit inputs; 17 | } 18 | { 19 | systems = builtins.attrNames inputs.holochain-dev.devShells; 20 | perSystem = 21 | { config 22 | , pkgs 23 | , system 24 | , ... 25 | }: { 26 | devShells.default = pkgs.mkShell { 27 | inputsFrom = [ inputs.holochain-dev.devShells.${system}.holonix ]; 28 | packages = [ pkgs.nodejs-18_x ]; 29 | }; 30 | }; 31 | }; 32 | } -------------------------------------------------------------------------------- /dnas/directory/workdir/dna.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | manifest_version: "1" 3 | name: directory 4 | integrity: 5 | network_seed: ~ 6 | properties: ~ 7 | origin_time: 1675920592357481 8 | zomes: 9 | - name: profiles_integrity 10 | hash: ~ 11 | bundled: "../../../target/wasm32-unknown-unknown/release/profiles_integrity.wasm" 12 | dependencies: ~ 13 | - name: directory_integrity 14 | hash: ~ 15 | bundled: "../../../target/wasm32-unknown-unknown/release/directory_integrity.wasm" 16 | dependencies: ~ 17 | coordinator: 18 | zomes: 19 | - name: profiles 20 | hash: ~ 21 | bundled: "../../../target/wasm32-unknown-unknown/release/profiles.wasm" 22 | dependencies: 23 | - name: profiles_integrity 24 | - name: directory 25 | hash: ~ 26 | bundled: "../../../target/wasm32-unknown-unknown/release/directory.wasm" 27 | dependencies: 28 | - name: directory_integrity -------------------------------------------------------------------------------- /tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tests", 3 | "version": "0.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "NODE_NO_WARNINGS=1 TRYORAMA_LOG_LEVEL=warn RUST_LOG=warn ava -s -c 1 --fail-fast --timeout=2m", 8 | "test-ts-node": "foreach -g \"**/*.test.ts\" -x \"NODE_NO_WARNINGS=1 ts-node-test #{path}\" --no-C" 9 | }, 10 | "author": "", 11 | "license": "CAL-1.0", 12 | "dependencies": { 13 | "@holochain/client": "^0.15.0", 14 | "@holochain/tryorama": "^0.15.0-rc.1", 15 | "@msgpack/msgpack": "^2.7.0", 16 | "foreach-cli": "^1.8.1", 17 | "ts-node-test": "^0.2.0" 18 | }, 19 | "type": "module", 20 | "devDependencies": { 21 | "@istanbuljs/esm-loader-hook": "^0.2.0", 22 | "ava": "^5.2.0", 23 | "bob-ts": "^4.1.1", 24 | "tap": "^16.3.4" 25 | }, 26 | "ava": { 27 | "extensions": { 28 | "ts": "module" 29 | }, 30 | "nodeArguments": [ 31 | "--loader=ts-node/esm" 32 | ] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ui/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{js,ts,jsx,tsx,vue}", 6 | ], 7 | theme: { 8 | extend: {}, 9 | }, 10 | plugins: [ 11 | require('@tailwindcss/forms'), 12 | require('@tailwindcss/typography'), 13 | require('@tailwindcss/aspect-ratio'), 14 | require('@tailwindcss/line-clamp'), 15 | require('daisyui') 16 | ], 17 | // daisyUI config (optional) 18 | daisyui: { 19 | styled: true, 20 | themes: ["light", "dark", "cupcake", "bumblebee", "emerald", "corporate", "synthwave", "retro", "cyberpunk", "valentine", "halloween", "garden", "forest", "aqua", "lofi", "pastel", "fantasy", "wireframe", "black", "luxury", "dracula", "cmyk", "autumn", "business", "acid", "lemonade", "night", "coffee", "winter"], 21 | base: true, 22 | utils: true, 23 | logs: true, 24 | rtl: false, 25 | prefix: "", 26 | darkTheme: "dark", 27 | }, 28 | } 29 | -------------------------------------------------------------------------------- /ui/src/herd/profiles/AgentProfileDetail.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 29 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [profile.dev] 2 | opt-level = "z" 3 | 4 | [profile.release] 5 | opt-level = "z" 6 | 7 | [workspace] 8 | members = ["dnas/*/zomes/coordinator/*", "dnas/*/zomes/integrity/*"] 9 | 10 | [workspace.dependencies] 11 | hdi = "=0.3.1" 12 | hdk = "=0.2.1" 13 | serde = "1" 14 | 15 | [workspace.dependencies.directory] 16 | path = "dnas/directory/zomes/coordinator/directory" 17 | 18 | [workspace.dependencies.directory_integrity] 19 | path = "dnas/directory/zomes/integrity/directory" 20 | 21 | [workspace.dependencies.profiles] 22 | path = "dnas/directory/zomes/coordinator/profiles" 23 | 24 | [workspace.dependencies.profiles_integrity] 25 | path = "dnas/directory/zomes/integrity/profiles" 26 | 27 | [workspace.dependencies.herd] 28 | path = "dnas/herd/zomes/coordinator/herd" 29 | 30 | [workspace.dependencies.herd_integrity] 31 | path = "dnas/herd/zomes/integrity/herd" 32 | 33 | [workspace.dependencies.posts] 34 | path = "dnas/herd/zomes/coordinator/posts" 35 | 36 | [workspace.dependencies.posts_integrity] 37 | path = "dnas/herd/zomes/integrity/posts" -------------------------------------------------------------------------------- /ui/src/stores/theme.ts: -------------------------------------------------------------------------------- 1 | // stores/counter.js 2 | import { defineStore } from 'pinia'; 3 | 4 | export interface Theme { 5 | name: string; 6 | active: boolean; 7 | } 8 | 9 | export const useThemeStore = defineStore('theme', { 10 | persist: true, 11 | state: () => ({ 12 | active: 'light', 13 | themes: ["light", "dark", "cyberpunk", "corporate", "retro", "wireframe", "black", "luxury", "cupcake", "valentine", "synthwave", "halloween", "garden", "forest", "aqua", "lofi", "pastel", "fantasy", "dracula", "cmyk", "autumn", "business", "acid", "lemonade", "night", "coffee", "winter"] 14 | }), 15 | getters: { 16 | themesDisplay(): Theme[] { 17 | return this.themes.map((name: string) => ({ 18 | name, 19 | active: this.active === name 20 | } as Theme)); 21 | }, 22 | }, 23 | actions: { 24 | set(theme: string) { 25 | this.active = theme; 26 | this.apply(); 27 | }, 28 | apply() { 29 | document.documentElement.setAttribute("data-theme", this.active); 30 | } 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /ui/src/components/BaseContentHidden.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | -------------------------------------------------------------------------------- /ui/src/routes.ts: -------------------------------------------------------------------------------- 1 | import AllPosts from './herd/posts/AllPosts.vue'; 2 | import CreatePost from './herd/posts/CreatePost.vue'; 3 | import PostDetail from './herd/posts/PostDetail.vue'; 4 | import CreateHerd from './herd/herds/CreateHerd.vue'; 5 | import WateringHole from './herd/herds/WateringHole.vue'; 6 | import HerdDetail from './herd/herds/HerdDetail.vue'; 7 | import AgentProfileDetail from './herd/profiles/AgentProfileDetail.vue'; 8 | import MyAgentProfileDetail from './herd/profiles/MyAgentProfileDetail.vue'; 9 | 10 | const herd_routes = [ 11 | { path: '', component: AllPosts }, 12 | { path: 'posts/create', component: CreatePost }, 13 | { path: 'posts/:postHashString', component: PostDetail }, 14 | ]; 15 | 16 | export default [ 17 | { path: '', component: WateringHole }, 18 | { path: '/agents/:agentPubKeyString', component: AgentProfileDetail }, 19 | { path: '/my-agent', component: MyAgentProfileDetail }, 20 | { path: '/herds/create', component: CreateHerd }, 21 | { path: '/herds/private/:password', component: HerdDetail, children: herd_routes }, 22 | { path: '/herds/:listingHashString', component: HerdDetail, children: herd_routes }, 23 | ]; 24 | -------------------------------------------------------------------------------- /ui/src/components/BaseEditDeleteButtons.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 40 | -------------------------------------------------------------------------------- /dnas/herd/zomes/integrity/posts/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod comment; 2 | pub use comment::*; 3 | pub mod post; 4 | pub use post::*; 5 | pub mod votes; 6 | pub use votes::*; 7 | pub mod validate; 8 | use hdi::prelude::*; 9 | pub use validate::*; 10 | 11 | #[hdk_entry_helper] 12 | #[derive(Clone)] 13 | pub struct Post { 14 | pub title: String, 15 | pub content: String, 16 | } 17 | 18 | #[hdk_entry_helper] 19 | #[derive(Clone)] 20 | pub struct Comment { 21 | pub content: String, 22 | pub post_ah: ActionHash, 23 | } 24 | 25 | #[derive(Serialize, Deserialize, SerializedBytes, Debug, Clone)] 26 | pub struct VoteTag { 27 | pub value: i8, 28 | } 29 | 30 | #[hdk_entry_defs] 31 | #[unit_enum(UnitEntryTypes)] 32 | pub enum EntryTypes { 33 | Post(Post), 34 | Comment(Comment), 35 | } 36 | 37 | #[hdk_link_types] 38 | pub enum LinkTypes { 39 | // Posts 40 | PostUpdates, 41 | AllPosts, 42 | MyPosts, 43 | 44 | // Post votes 45 | MyVotedPosts, 46 | PostVoteByAgent, 47 | 48 | // Comments 49 | PostToComments, 50 | CommentUpdates, 51 | MyComments, 52 | 53 | // Comment votes 54 | MyVotedComments, 55 | CommentVoteByAgent, 56 | } 57 | #[hdk_extern] 58 | pub fn genesis_self_check(_data: GenesisSelfCheckData) -> ExternResult { 59 | Ok(ValidateCallbackResult::Valid) 60 | } 61 | -------------------------------------------------------------------------------- /ui/src/components/BaseThemeSelect.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | -------------------------------------------------------------------------------- /ui/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import {createRouter, createWebHashHistory} from 'vue-router'; 3 | import './style.css' 4 | import App from './App.vue'; 5 | import Vue3Toastify, { type ToastContainerOptions } from 'vue3-toastify'; 6 | import 'vue3-toastify/dist/index.css'; 7 | import { createPinia } from 'pinia'; 8 | import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' 9 | import routes from './routes'; 10 | 11 | // Profiles custom elements 12 | import "@holochain-open-dev/profiles/dist/elements/profiles-context.js"; 13 | import "@holochain-open-dev/profiles/dist/elements/create-profile.js"; 14 | import "@holochain-open-dev/profiles/dist/elements/agent-avatar.js"; 15 | import "@holochain-open-dev/profiles/dist/elements/my-profile.js"; 16 | import "@holochain-open-dev/profiles/dist/elements/profile-prompt.js"; 17 | import "@holochain-open-dev/profiles/dist/elements/profile-detail.js"; 18 | 19 | // Shoelace 20 | import '@shoelace-style/shoelace/dist/themes/light.css'; 21 | import '@shoelace-style/shoelace/dist/themes/dark.css'; 22 | import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path'; 23 | setBasePath('shoelace'); 24 | 25 | // Initialize Vue App 26 | const router = createRouter({ 27 | history: createWebHashHistory(), 28 | routes, 29 | }); 30 | const pinia = createPinia(); 31 | pinia.use(piniaPluginPersistedstate); 32 | const app = createApp(App); 33 | 34 | app.use(pinia); 35 | app.use(router); 36 | app.use(Vue3Toastify, { 37 | autoClose: 2000, 38 | closeOnClick: false, 39 | position: 'bottom-left', 40 | containerId: 'toasts-container', 41 | style: { 42 | opacity: '1', 43 | userSelect: 'initial', 44 | width: 'auto' 45 | }, 46 | } as ToastContainerOptions); 47 | app.mount('#app'); -------------------------------------------------------------------------------- /ui/src/components/BaseVoteInput.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 58 | -------------------------------------------------------------------------------- /ui/src/herd/herds/HerdPasswordModal.vue: -------------------------------------------------------------------------------- 1 |