diff --git a/frontend/src/lib/components/neuron-detail/NeuronFollowingCard/NeuronFollowingCard.svelte b/frontend/src/lib/components/neuron-detail/NeuronFollowingCard/NeuronFollowingCard.svelte index d489effba29..8b8b75bc189 100644 --- a/frontend/src/lib/components/neuron-detail/NeuronFollowingCard/NeuronFollowingCard.svelte +++ b/frontend/src/lib/components/neuron-detail/NeuronFollowingCard/NeuronFollowingCard.svelte @@ -5,32 +5,36 @@ import { icpAccountsStore } from "$lib/derived/icp-accounts.derived"; import { listKnownNeurons } from "$lib/services/known-neurons.services"; import { authStore } from "$lib/stores/auth.store"; + import { ENABLE_NNS_TOPICS } from "$lib/stores/feature-flags.store"; import { i18n } from "$lib/stores/i18n"; import { followeesNeurons, isHotKeyControllable, isNeuronControllable, - type FolloweesNeuron, } from "$lib/utils/neuron.utils"; import { KeyValuePairInfo } from "@dfinity/gix-components"; import type { NeuronInfo } from "@dfinity/nns"; import { nonNullish } from "@dfinity/utils"; import { onMount } from "svelte"; - export let neuron: NeuronInfo; - let isControllable: boolean; - $: isControllable = + type Props = { + neuron: NeuronInfo; + }; + const { neuron }: Props = $props(); + + const isControllable = $derived( isNeuronControllable({ neuron, identity: $authStore.identity, accounts: $icpAccountsStore, }) || - isHotKeyControllable({ - neuron, - identity: $authStore.identity, - }); - let followees: FolloweesNeuron[]; - $: followees = followeesNeurons(neuron); + isHotKeyControllable({ + neuron, + identity: $authStore.identity, + }) + ); + const followees = $derived(followeesNeurons(neuron)); + const isFollowByTopic = $derived($ENABLE_NNS_TOPICS); onMount(listKnownNeurons); @@ -53,7 +57,7 @@
{#if isControllable} - + {/if}
diff --git a/frontend/src/lib/components/neuron-detail/actions/FollowNeuronsButton.svelte b/frontend/src/lib/components/neuron-detail/actions/FollowNeuronsButton.svelte index 27ce90af417..eea7682cf4d 100644 --- a/frontend/src/lib/components/neuron-detail/actions/FollowNeuronsButton.svelte +++ b/frontend/src/lib/components/neuron-detail/actions/FollowNeuronsButton.svelte @@ -7,7 +7,18 @@ import { openNnsNeuronModal } from "$lib/utils/modals.utils"; import { getContext } from "svelte"; - export let variant: "primary" | "secondary" = "primary"; + type Props = { + variant?: "primary" | "secondary"; + isFollowByTopic?: boolean; + }; + const { variant = "primary", isFollowByTopic = false }: Props = $props(); + + const onClick = () => { + openNnsNeuronModal({ + type: isFollowByTopic ? "follow-by-topic" : "follow", + data: { neuron: $store.neuron }, + }); + }; const { store }: NnsNeuronContext = getContext( NNS_NEURON_CONTEXT_KEY @@ -17,7 +28,5 @@ {$i18n.neuron_detail.follow_neurons} diff --git a/frontend/src/lib/modals/neurons/FollowNeuronsModal.svelte b/frontend/src/lib/modals/neurons/FollowNeuronsModal.svelte index 189a823fdb9..9f671d0b400 100644 --- a/frontend/src/lib/modals/neurons/FollowNeuronsModal.svelte +++ b/frontend/src/lib/modals/neurons/FollowNeuronsModal.svelte @@ -9,6 +9,7 @@ onClose: () => void; }; const { neuronId, onClose }: Props = $props(); + console.log("hi"); + import { i18n } from "$lib/stores/i18n"; + import type { NnsTopicFollowee } from "$lib/types/nns"; + import { getTopicSubtitle, getTopicTitle } from "$lib/utils/neuron.utils"; + import { + Checkbox, + Collapsible, + IconCheckCircleFill, + IconErrorOutline, + IconExpandMore, + } from "@dfinity/gix-components"; + import type { NeuronId, Topic } from "@dfinity/nns"; + + type Props = { + topic: Topic; + followees: NnsTopicFollowee[]; + checked: boolean; + onNnsChange: (args: { topic: Topic; checked: boolean }) => void; + removeFollowing: (args: { topic: Topic; neuronId: NeuronId }) => void; + }; + + let { + topic, + followees, + checked = false, + onNnsChange, + removeFollowing, + }: Props = $props(); + + const name = $derived(getTopicTitle({ topic, i18n: $i18n })); + let description = $derived(getTopicSubtitle({ topic, i18n: $i18n })); + + // const topicKey: SnsTopicKey = $derived(getSnsTopicInfoKey(topicInfo)); + // const name: string = $derived(fromDefinedNullable(topicInfo.name)); + // const description: string = $derived( + // fromDefinedNullable(topicInfo.description) + // ); + // const followees: FolloweeData[] = $derived.by(() => { + // const followesPerTopic = followeesByTopic({ neuron, topic }); + + // const mapToKnownNeuron = (neuronId: NeuronId): FolloweeData => { + // const knownNeuron = $knownNeuronsStore.find(({ id }) => id === neuronId); + // return nonNullish(knownNeuron) + // ? { + // neuronId: knownNeuron.id, + // name: knownNeuron.name, + // } + // : { neuronId }; + // }; + // // If we remove the last followee of that topic, followesPerTopic is undefined. + // // and we need to reset the followees array + // return followesPerTopic?.map(mapToKnownNeuron) ?? []; + // }); + + const onChange = () => { + // Checkbox doesn't support two-way binding + checked = !checked; + onNnsChange({ topic, checked }); + }; + + let toggleContent: () => void = $state(() => {}); + let expanded: boolean = $state(false); + const isFollowingByTopic = $derived(followees.length > 0); + + +
+ +
+ + {name} + + +
+ {#if isFollowingByTopic} + + {:else} + + {/if} +
+ + +
+
+

+ {description} +

+ +
+ {#if followees.length > 0} +
{$i18n.follow_sns_topics.topics_following}
+ {/if} + + {#if followees.length > 0} +
    + {#each followees as followee} +
  • {followee}
  • + {/each} +
+ {/if} +
+
+
+ + diff --git a/frontend/src/lib/modals/neurons/FollowNnsNeuronsByTopicModal.svelte b/frontend/src/lib/modals/neurons/FollowNnsNeuronsByTopicModal.svelte new file mode 100644 index 00000000000..198dab37bc5 --- /dev/null +++ b/frontend/src/lib/modals/neurons/FollowNnsNeuronsByTopicModal.svelte @@ -0,0 +1,177 @@ + + + + {currentStep?.title} + + {#if currentStep?.name === STEP_TOPICS} + + {/if} + + {#if currentStep?.name === STEP_NEURON} + + {/if} + + + diff --git a/frontend/src/lib/modals/neurons/FollowNnsNeuronsByTopicStepNeuron.svelte b/frontend/src/lib/modals/neurons/FollowNnsNeuronsByTopicStepNeuron.svelte new file mode 100644 index 00000000000..58404a4da7a --- /dev/null +++ b/frontend/src/lib/modals/neurons/FollowNnsNeuronsByTopicStepNeuron.svelte @@ -0,0 +1,161 @@ + + + + {$i18n.new_followee.title} + +
+ + {$i18n.new_followee.label} + + +
+ +
+ {$i18n.new_followee.options_title} + {#if $sortedknownNeuronsStore === undefined} + + {:else} +
    + {#each $sortedknownNeuronsStore as knownNeuron} +
  • + +
  • + {/each} +
+ {/if} +
+
+ + diff --git a/frontend/src/lib/modals/neurons/FollowNnsNeuronsByTopicStepTopics.svelte b/frontend/src/lib/modals/neurons/FollowNnsNeuronsByTopicStepTopics.svelte new file mode 100644 index 00000000000..481200cd613 --- /dev/null +++ b/frontend/src/lib/modals/neurons/FollowNnsNeuronsByTopicStepTopics.svelte @@ -0,0 +1,157 @@ + + + +

+ Delegate your voting by following other neurons to maximize your voting + rewards. Your voting is fully delegated only if following is set for every + topic. Alternatively, you can vote manually. +

+ + + +
+
Required Settings + {$i18n.follow_sns_topics.topics_critical_tooltip}
+ + {#each requiredTopics as topic} + + {/each} +
+ + + +
+ + +
Advance Settings
+ + {#each advanceTopics as topic} + + {/each} +
+
+ + +
+ + + +
+
+ + diff --git a/frontend/src/lib/modals/neurons/NnsNeuronModals.svelte b/frontend/src/lib/modals/neurons/NnsNeuronModals.svelte index 3c3e9a199f0..c4d953bdefe 100644 --- a/frontend/src/lib/modals/neurons/NnsNeuronModals.svelte +++ b/frontend/src/lib/modals/neurons/NnsNeuronModals.svelte @@ -31,6 +31,7 @@ } from "$lib/utils/neuron.utils"; import type { NeuronInfo } from "@dfinity/nns"; import { nonNullish } from "@dfinity/utils"; + import FollowNnsNeuronsByTopicModal from "./FollowNnsNeuronsByTopicModal.svelte"; let modal: NnsNeuronModal | undefined; const close = () => (modal = undefined); @@ -101,6 +102,13 @@ {/if} + {#if type === "follow-by-topic"} + + {/if} + {#if type === "add-hotkey"} {/if} diff --git a/frontend/src/lib/modals/neurons/NnsStakeNeuronModal.svelte b/frontend/src/lib/modals/neurons/NnsStakeNeuronModal.svelte index e69dc277061..e0b2b77bccf 100644 --- a/frontend/src/lib/modals/neurons/NnsStakeNeuronModal.svelte +++ b/frontend/src/lib/modals/neurons/NnsStakeNeuronModal.svelte @@ -1,7 +1,6 @@ {currentStep?.title ?? $i18n.accounts.select_source} {/if} {/if} - {#if currentStep?.name === "EditFollowNeurons"} + diff --git a/frontend/src/lib/pages/NnsNeurons.svelte b/frontend/src/lib/pages/NnsNeurons.svelte index 8b62ffe00b5..19ae45cccc7 100644 --- a/frontend/src/lib/pages/NnsNeurons.svelte +++ b/frontend/src/lib/pages/NnsNeurons.svelte @@ -11,6 +11,7 @@ startReducingVotingPowerAfterSecondsStore, } from "$lib/derived/network-economics.derived"; import { nonEmptyNeuronStore } from "$lib/derived/neurons.derived"; + import NnsNeuronModals from "$lib/modals/neurons/NnsNeuronModals.svelte"; import { listNeurons } from "$lib/services/neurons.services"; import { authStore } from "$lib/stores/auth.store"; import { i18n } from "$lib/stores/i18n"; @@ -59,6 +60,8 @@ {:else} {$i18n.neurons.text} {/if} + +