Skip to content

Commit

Permalink
refactor(projects): add support for hiding projects
Browse files Browse the repository at this point in the history
Implements: #1242
  • Loading branch information
jtourkos committed Nov 6, 2024
1 parent 5681f7f commit 2aa178c
Show file tree
Hide file tree
Showing 18 changed files with 147 additions and 38 deletions.
22 changes: 5 additions & 17 deletions src/lib/components/drip-lists-section/drip-lists-section.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import DripListCard from '../drip-list-card/drip-list-card.svelte';
import type { DripListsSectionDripListFragment } from './__generated__/gql.generated';
import type { SplitsComponentSplitsReceiver } from '../splits/types';
import Toggle from '$lib/components/toggle/toggle.svelte';
import VisibilityToggle from '../visibility-toggle/visibility-toggle.svelte';
export let dripLists: DripListsSectionDripListFragment[];
export let votingRounds: (VotingRound & { splits: SplitsComponentSplitsReceiver[] })[];
Expand All @@ -35,7 +35,7 @@
let error = false;
let showHidden: boolean = false;
$: hiddenProjectsCount = dripLists?.filter((dl) => !dl.isVisible).length ?? 0;
$: hiddenListsCount = dripLists.filter((dl) => !dl.isVisible).length ?? 0;
$: dripListsAndVotingRounds = [
...(showHidden
Expand All @@ -44,6 +44,7 @@
.filter((dl) => dl.isVisible)
.map((dl) => ({ ...dl, type: 'drip-list' as const }))),
...votingRounds.map((vr) => ({ ...vr, type: 'voting-round' as const })),
// Show hidden lists last.
].sort((a, b) => {
if (showHidden && 'isVisible' in a && 'isVisible' in b) {
return a.isVisible === b.isVisible ? 0 : a.isVisible ? -1 : 1;
Expand Down Expand Up @@ -85,13 +86,8 @@
horizontalScroll: false,
}}
>
<svelte:fragment slot="custom-actions">
{#if hiddenProjectsCount}
<div class="toggle-visibility">
<Toggle bind:checked={showHidden} />
<p>Show hidden projects {hiddenProjectsCount}</p>
</div>
{/if}
<svelte:fragment slot="left-actions">
<VisibilityToggle bind:showHidden hiddenItemsCount={hiddenListsCount} />
</svelte:fragment>

{#if dripListsAndVotingRounds}
Expand Down Expand Up @@ -143,11 +139,3 @@
</div>
{/if}
</Section>

<style>
.toggle-visibility {
display: flex;
justify-content: space-between;
gap: 8px;
}
</style>
16 changes: 15 additions & 1 deletion src/lib/components/project-card/project-card.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
${PROJECT_NAME_FRAGMENT}
fragment ProjectCard on Project {
...ProjectName
isVisible
source {
forge
ownerName
Expand Down Expand Up @@ -36,14 +37,15 @@
import filterCurrentChainData from '$lib/utils/filter-current-chain-data';
export let project: ProjectCardFragment;
export let isHidden = false;
let projectChainData = filterCurrentChainData(project.chainData);
</script>

<a
class="wrapper"
href={buildProjectUrl(project.source.forge, project.source.ownerName, project.source.repoName)}
>
<div class="project-card">
<div class="project-card" class:hidden-project={isHidden}>
<div
class="background"
style:background-color={isClaimed(projectChainData)
Expand Down Expand Up @@ -120,4 +122,16 @@
gap: 0.125rem;
color: var(--color-foreground-level-6);
}
.hidden-project {
color: var(--color-foreground);
opacity: 0;
animation: fadeIn 1s ease forwards;
}
@keyframes fadeIn {
to {
opacity: 0.3;
}
}
</style>
43 changes: 42 additions & 1 deletion src/lib/components/project-customizer/project-customizer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
color
}
}
isVisible
}
`;
</script>
Expand All @@ -34,12 +35,13 @@
import TabbedBox from '../tabbed-box/tabbed-box.svelte';
import twemoji from '$lib/utils/twemoji';
import filterCurrentChainData from '$lib/utils/filter-current-chain-data';
import Toggle from '$lib/components/toggle/toggle.svelte';
export let originalProject: ProjectCustomizerFragment;
export let newProjectData: Writable<
ReturnType<
typeof filterCurrentChainData<ProjectCustomizerFragment['chainData'][number], 'claimed'>
>
> & { isProjectHidden: boolean }
>;
let activeTab: 'tab-1' | 'tab-2' =
Expand Down Expand Up @@ -70,6 +72,12 @@
}
$: handleColorChange(selectedColor);
let isHidden = $newProjectData.isProjectHidden;
function handleIsHiddenChange(isHidden: boolean) {
$newProjectData.isProjectHidden = isHidden;
}
$: handleIsHiddenChange(isHidden);
let lastUploadedCid =
$newProjectData.avatar.__typename === 'ImageAvatar' ? $newProjectData.avatar.cid : undefined;
function handleFileUpload(e: CustomEvent<{ ipfsCid: string }>) {
Expand Down Expand Up @@ -163,6 +171,19 @@
{/each}
</div>
</FormField>

<div class="visibility-toggle">
<h4>Hide this project from my profile</h4>
<Toggle bind:checked={isHidden} />
</div>
<div class="hide-info">
<p>This will only hide the project from your public profile</p>
<ul>
<li><p>· It will remain claimed by you on the blockchain</p></li>
<li><p>· Any existing funding will continue to flow to and from it</p></li>
<li><p>· It will be visible from a direct link</p></li>
</ul>
</div>
</div>

<style>
Expand Down Expand Up @@ -260,4 +281,24 @@
transform: scale(1);
box-shadow: var(--elevation-low);
}
.visibility-toggle {
display: flex;
justify-content: space-between;
}
.hide-info {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.hide-info > p {
margin-bottom: 1rem;
}
.hide-info li {
display: flex;
margin-left: 0.5rem;
}
</style>
25 changes: 22 additions & 3 deletions src/lib/components/projects-section/projects-section.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import Plus from '../icons/Plus.svelte';
import modal from '$lib/stores/modal';
import filterCurrentChainData from '$lib/utils/filter-current-chain-data';
import VisibilityToggle from '../visibility-toggle/visibility-toggle.svelte';
export let projects: ProjectsSectionProjectFragment[];
export let withClaimProjectButton = false;
Expand All @@ -27,6 +28,20 @@
export let collapsed = false;
export let collapsable = false;
let showHidden: boolean = false;
$: hiddenProjectsCount = projects.filter((p) => !p.isVisible).length ?? 0;
$: projectsToShow = [
...(showHidden ? projects : projects.filter((p) => p.isVisible))
// Show hidden projects last.
.sort((a, b) => {
if (showHidden && 'isVisible' in a && 'isVisible' in b) {
return a.isVisible === b.isVisible ? 0 : a.isVisible ? -1 : 1;
}
return 0;
}),
];
</script>

<Section
Expand Down Expand Up @@ -57,20 +72,24 @@
: 'This user hasnʼt claimed any software projects yet.',
}}
>
{#if projects}
{#if projectsToShow}
<div class="projects">
{#each projects as project}
{#each projectsToShow as project}
{@const projectChainData = filterCurrentChainData(project.chainData)}
{#if isClaimed(projectChainData)}
<div>
<PrimaryColorThemer colorHex={projectChainData.color}>
<ProjectCard {project} />
<ProjectCard {project} isHidden={!project.isVisible} />
</PrimaryColorThemer>
</div>
{/if}
{/each}
</div>
{/if}

<svelte:fragment slot="left-actions">
<VisibilityToggle bind:showHidden hiddenItemsCount={hiddenProjectsCount}></VisibilityToggle>
</svelte:fragment>
</Section>

<style>
Expand Down
9 changes: 1 addition & 8 deletions src/lib/components/section-header/section-header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
export let collapsed = true;
export let collapsable = false;
export let customActionsPosition: 'before' | 'after' = 'before';
</script>

<!--svelte-ignore a11y-click-events-have-key-events -->
Expand Down Expand Up @@ -54,9 +53,7 @@
{/if}
</div>
<div class="actions">
{#if customActionsPosition === 'before'}
<slot name="custom-actions"></slot>
{/if}
<slot name="left-actions"></slot>

{#each actions as action}
<Button
Expand All @@ -68,10 +65,6 @@
on:click={action.handler}>{action.label}</Button
>
{/each}

{#if customActionsPosition === 'after'}
<slot name="custom-actions"></slot>
{/if}
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/section/section.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
{...header}
actionsDisabled={collapsed || header.actionsDisabled}
>
<slot name="custom-actions" slot="custom-actions"></slot>
<slot name="left-actions" slot="left-actions"></slot>
</SectionHeader>
<div>
<SectionSkeleton bind:this={skeletonInstance} bind:collapsed {...skeleton}>
Expand Down
33 changes: 33 additions & 0 deletions src/lib/components/visibility-toggle/visibility-toggle.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<script lang="ts">
import Toggle from '$lib/components/toggle/toggle.svelte';
export let hiddenItemsCount: number;
export let showHidden: boolean = false;
export let message = 'Show hidden';
</script>

{#if hiddenItemsCount}
<div class="visibility-toggle">
<Toggle bind:checked={showHidden} />
<p>{message}</p>
<div class="count"><span>{hiddenItemsCount}</span></div>
</div>
{/if}

<style>
.visibility-toggle {
display: flex;
justify-content: space-between;
gap: 8px;
}
.count {
font-weight: bold;
border-radius: 0.5rem 0 0.5rem 0.5rem;
background-color: var(--color-foreground-level-2);
}
.count span {
padding: 0.5rem 0.5rem;
}
</style>
1 change: 1 addition & 0 deletions src/lib/flows/claim-project-flow/claim-project-flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const CLAIM_PROJECT_FLOW_PROJECT_FRAGMENT = gql`
...EnterGitUrlStepProject
...AddEthereumAddressStepProject
...ReviewStepUnclaimedProject
isVisible
}
`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
export let newProjectData: Writable<
ReturnType<
typeof filterCurrentChainData<ProjectCustomizerFragment['chainData'][number], 'claimed'>
>
> & { isProjectHidden: boolean }
>;
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
export let newProjectData: Writable<
ReturnType<
typeof filterCurrentChainData<ProjectCustomizerFragment['chainData'][number], 'claimed'>
>
> & { isProjectHidden: boolean }
>;
const dispatch = createEventDispatcher<StepComponentEvents>();
Expand Down
7 changes: 4 additions & 3 deletions src/lib/flows/claim-project-flow/steps/review/review.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,10 @@
}
function customize() {
const newProjectDataWritable = writable(
filterCurrentChainData(fakeClaimedProject.chainData, 'claimed'),
);
const newProjectDataWritable = writable({
...filterCurrentChainData(fakeClaimedProject.chainData, 'claimed'),
isProjectHidden: false,
});
if (isModal) {
dispatch('sidestep', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
account {
accountId
}
isVisible
chainData {
... on ClaimedProjectData {
avatar {
Expand All @@ -19,6 +20,7 @@
color
}
}
isVisible
}
`;
</script>
Expand Down Expand Up @@ -53,7 +55,9 @@
export let project: SetNewMetadataStepFragment;
$: projectChainData = filterCurrentChainData(project.chainData, 'claimed');
$: projectDataWritable = writable(structuredClone(projectChainData));
$: projectDataWritable = writable(
structuredClone({ ...projectChainData, isProjectHidden: !project.isVisible }),
);
let valid = false;
Expand Down Expand Up @@ -85,6 +89,7 @@
cid: $projectDataWritable.avatar.cid,
},
color: $projectDataWritable.color,
isVisible: !$projectDataWritable.isProjectHidden,
};
const ipfsHash = await metadataManager.pinAccountMetadata(newMetadata);
Expand Down
3 changes: 2 additions & 1 deletion src/lib/utils/metadata/RepoDriverMetadataManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export default class RepoDriverMetadataManager extends MetadataManagerBase<
}

public buildAccountMetadata(context: {
forProject: PickGQLF<Project, 'account' | 'source'> & {
forProject: PickGQLF<Project, 'account' | 'source' | 'isVisible'> & {
chainData: Pick<ClaimedProjectData, 'avatar' | 'color' | 'description'>;
};
forSplits: LatestVersion<typeof repoDriverAccountMetadataParser>['splits'];
Expand All @@ -119,6 +119,7 @@ export default class RepoDriverMetadataManager extends MetadataManagerBase<
ownerName: forProject.source.ownerName,
url: forProject.source.url,
},
isVisible: forProject.isVisible,
avatar:
forProject.chainData.avatar.__typename === 'EmojiAvatar'
? {
Expand Down
Loading

0 comments on commit 2aa178c

Please sign in to comment.