Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mvp #168

Merged
merged 19 commits into from
Jan 9, 2025
Merged

Mvp #168

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@
import SignUp from "./lib/components/views/signup/SignUp.svelte";
import { addressStore } from "$lib/stores/address.store";
import { currentUser } from "$lib/stores/current-user.store";
import { isConnected } from "$lib/stores/is-connectec.store";
import Feed from "$lib/components/views/feed/Feed.svelte";
import Profile from "$lib/components/views/profile/Profile.svelte";
import IndividualPost from "$lib/components/posts/IndividualPost.svelte";
import MessagesPage from "$lib/components/Messages/MessagesPage.svelte";
import { myPostStore } from "$lib/stores/my-post.store";
import { usersProfile } from "$lib/stores/users-profile.store";
import { followListStore } from "$lib/stores/follow-list.store";
import MobileTopView from "$lib/components/views/main/MobileTopView.svelte";
import MobileBottomNavBar from "$lib/components/views/main/MobileBottomNavBar.svelte";

let isLoading = true;
let isFollowListAlreadyFetched = false;
Expand All @@ -30,6 +29,7 @@
"/profile/:address": Profile,
"/post/:id/:user": IndividualPost,
"/signup": SignUp,
"/test": MobileTopView,
};

function handleRouteReload() {
Expand Down Expand Up @@ -99,10 +99,14 @@
<Router {routes} />
{:else if $currentUser}
<div class="bg-background">
<MobileTopView />
<div class="flex w-full bg-background justify-center">
<Left />
<Middle><Router {routes} /></Middle>
<Middle>
<Router {routes} />
</Middle>
<Right />
</div>
<MobileBottomNavBar />
</div>
{/if}
54 changes: 54 additions & 0 deletions src/lib/components/DisconnectWallet/DisconnectWallet.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<script lang="ts">
import { addressStore } from "$lib/stores/address.store";
import { currentUser } from "$lib/stores/current-user.store";
import { push } from "svelte-spa-router";
import { writable } from "svelte/store";
import ButtonWithLoader from "../ButtonWithLoader/ButtonWithLoader.svelte";


async function handleDisconnect() {
try {
// Disconnect the wallet
await addressStore.disconnectWallet();

// Clear all relevant stores
const { subscribe, set } = writable();
set(undefined);

// Reset location and force a clean state
window.location.href = '/';
} catch (error) {
console.error("Error disconnecting wallet:", error);
}
}
</script>

<div class="px-2 py-1 w-full">
<ButtonWithLoader
class="mt-4 group text-sm font-medium w-full px-4 h-10 rounded-lg text-red-500
hover:text-white hover:bg-red-500 transition-all duration-200
border border-red-200 hover:border-red-500
flex items-center justify-start gap-2
bg-white/5 backdrop-blur-sm"
loaderClass="size-5"
on:click={handleDisconnect}
>
<div class="flex items-center gap-2 w-full">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-4 w-4 group-hover:rotate-180 transition-transform duration-200"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
/>
</svg>
<span>Disconnect Wallet</span>
</div>
</ButtonWithLoader>
</div>
7 changes: 3 additions & 4 deletions src/lib/components/UserList/UserList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,21 @@
usersProfile.subscribe((value) => {
profiles = value.values();
});
// usersProfile.fetchProfiles()
</script>

{#if $usersProfile.size > 0}
<div class="w-full h-full">
<Card.Root
data-x-chunk-name="UserList"
data-x-chunk-description="A card showing a list of users."
class="border-border rounded p-0 min-w-[280px]"
class="border-border rounded p-0 min-w-[280px] max-w-[400px]"
>
<Card.Header>
<Card.Title>You might like</Card.Title>
</Card.Header>
<Card.Content class="w-full">
<div
class="grid gap-8 max-h-[80vh] overflow-y-auto scrollable-element pr-3"
class="grid gap-6 lg:gap-8 max-h-[60vh] lg:max-h-[80vh] overflow-y-auto scrollable-element pr-2 lg:pr-3"
>
{#each $usersProfile.values() as profile}
{#if profile.address !== $currentUser.address}
Expand All @@ -43,4 +42,4 @@
scrollbar-color: hsl(0, 0%, 45%) hsl(0 0% 14.9%);
scrollbar-width: thin;
}
</style>
</style>
15 changes: 11 additions & 4 deletions src/lib/components/posts/CreatePost.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import { currentUser } from "$lib/stores/current-user.store";
import type { Tag } from "$lib/models/Tag";
import * as Dialog from "$lib/components/ui/dialog/index.js";
import { Plus, Image, X } from "lucide-svelte";
import { Plus, Image, X, Signpost } from "lucide-svelte";
import ButtonWithLoader from "$lib/components/ButtonWithLoader/ButtonWithLoader.svelte";
import ProfilePicture from "$lib/components/UserProfile/ProfilePicture.svelte";
import { notifyNewPostStore } from "$lib/stores/notify-new-post.store";
import { isMobile } from "$lib/stores/is-mobile.store";

let content = "";
let fileInput: HTMLInputElement | null = null;
Expand Down Expand Up @@ -105,10 +106,16 @@

<Dialog.Root bind:open={dialogOpen}>
<Dialog.Trigger
class="w-full h-13 bg-primary text-secondary rounded-full py-3 font-bold text-lg hover:bg-ring transition-colors duration-200 flex items-center justify-center"
class="h-13 bg-primary text-secondary rounded-full py-3 font-bold text-lg hover:bg-ring flex justify-center {$isMobile
? 'w-fit px-3'
: 'items-center w-full'}"
>
<Plus class="w-5 h-5 mr-2" />
Post
{#if $isMobile}
<Signpost class="size-8" />
{:else}
<Plus class="w-5 h-5 mr-2" />
Post
{/if}
</Dialog.Trigger>
<Dialog.Content class="w-full text-primary border-border">
<Dialog.Header>
Expand Down
4 changes: 2 additions & 2 deletions src/lib/components/posts/IndividualPost.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
import { Textarea } from "$lib/components/ui/textarea";
import Post from "$lib/components/posts/Post.svelte";
import { Image } from "lucide-svelte";
import { afterUpdate } from "svelte";
import type { Tag } from "$lib/models/Tag";
import { upload } from "$lib/ao/uploader";
import { link, push, location } from "svelte-spa-router";
import ButtonWithLoader from "../ButtonWithLoader/ButtonWithLoader.svelte";
import type { Profile } from "$lib/models/Profile";
import { isMobile } from "$lib/stores/is-mobile.store";

// Reactive declaration for URL parsing
$: {
Expand Down Expand Up @@ -196,7 +196,7 @@
}
</script>

<div class="max-w-prose mx-auto mt-10 mb-10">
<div class="max-w-prose mx-auto mb-10 {$isMobile ? "mt-0" : "mt-10"}">
{#if post}
<div class="border border-border hover:bg-gray-900/5">
<Post event={post} />
Expand Down
26 changes: 12 additions & 14 deletions src/lib/components/posts/Post.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@
(async () => {
const repostFilter = JSON.stringify([
{
kinds: ["6"],
tags: { e: event.Id.toString() },
kinds: "6",
tags: { e: [event.Id.toString()] },
},
]);
repostArray = await fetchEvents(repostFilter);
Expand Down Expand Up @@ -216,17 +216,15 @@
<a use:link href={`/post/${event.From}/${event.Id}`}>
<div>
<div class="flex justify-start space-x-3">
<div class="hidden sm:flex">
{#if isRepost && originalUser}
<div>
<ProfilePictureHoverCard profile={originalUser} />
</div>
{:else if profile}
<div>
<ProfilePictureHoverCard {profile} />
</div>
{/if}
</div>
{#if isRepost && originalUser}
<div>
<ProfilePictureHoverCard profile={originalUser} />
</div>
{:else if profile}
<div>
<ProfilePictureHoverCard {profile} />
</div>
{/if}

<div class="flex-1">
<div class="flex space-x-1 mb-1">
Expand Down Expand Up @@ -273,7 +271,7 @@

<div class="flex justify-between mt-3 engagement-buttons">
<div class="flex items-center">
<Reply {event} on:newReply={handleNewReply} />
<Reply {event} {isRepost} on:newReply={handleNewReply} />
{#if replyCount > 0}
<span class="ml-1 text-sm text-muted-foreground">
{replyCount}
Expand Down
58 changes: 49 additions & 9 deletions src/lib/components/views/engagement/PostPreview.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,25 @@
import type { Profile } from "$lib/models/Profile";
import ProfilePictureHoverCard from "$lib/components/UserProfile/ProfilePictureHoverCard.svelte";
import ProfileHoverCard from "$lib/components/UserProfile/ProfileHoverCard.svelte";
import { Repeat2Icon } from "lucide-svelte";
import { usersProfile } from "$lib/stores/users-profile.store";
import { currentUser } from "$lib/stores/current-user.store";

export let event: any;
export let user: Profile | undefined;
export let isRepost: boolean;

let originalPostEvent = isRepost ? JSON.parse(event.Content) : event;

let profile = $usersProfile.get(event.From);

let originalPostProfile = $usersProfile.get(originalPostEvent.From);

function formatContent(content: string): string {
// console.log("hhhh", JSON.parse(content));
// content = isRepost ? JSON.parse(content).Content : content;
// console.log("hhhh", content);

let urlReplaceContent = content.replace(/(?:https?|ftp):\/\/[\n\S]+/g, "");

if (urlReplaceContent.length < 400) {
Expand All @@ -19,10 +33,24 @@
}
</script>

{#if isRepost}
<div class="flex items-center text-muted-foreground mb-2">
<Repeat2Icon size={16} class="mr-2" />
<span class="text-sm"
>Reposted by
{#if profile?.address == $currentUser?.address}
You
{:else}
@{profile?.display_name}
{/if}
</span>
</div>
{/if}

<div class="flex mt-4">
<div class="h-full flex flex-col items-center">
{#if user}
<ProfilePictureHoverCard size="lg" profile={user} />
{#if originalPostProfile}
<ProfilePictureHoverCard size="lg" profile={originalPostProfile} />
{/if}
<div
id="vertical-line"
Expand All @@ -33,31 +61,43 @@
<div
class="h-12 w-full flex items-center min-w-0 overflow-hidden whitespace-nowrap"
>
{#if user}
<ProfileHoverCard profile={user}>
{#if isRepost && originalPostProfile}
<ProfileHoverCard profile={originalPostProfile}>
<div class="flex space-x-1">
<div class="text-primary text-base font-medium mr-1 ml-2">
{originalPostProfile?.name}
</div>

<div class="text-muted-foreground text-base font-light truncate">
{"@" + originalPostProfile?.display_name}
</div>
</div>
</ProfileHoverCard>
{:else if profile}
<ProfileHoverCard {profile}>
<div class="flex space-x-1">
<div class="text-primary text-base font-medium mr-1 ml-2">
{user?.name}
{profile?.name}
</div>

<div class="text-muted-foreground text-base font-light truncate">
{"@" + user?.display_name}
{"@" + profile?.display_name}
</div>
</div>
</ProfileHoverCard>
{/if}

<span class="text-muted-foreground pl-1">
· {formatTimestamp(event.Timestamp)}</span
· {formatTimestamp(originalPostEvent.Timestamp)}</span
>
</div>
<div class="text-primary text-start mt-4">
{formatContent(event.Content)}
{formatContent(originalPostEvent.Content)}
</div>

<div class="text-start text-muted-foreground mt-5">
{"Replying to "}
<span class="text-sky-500">{"@" + user?.display_name}</span>
<span class="text-sky-500">{"@" + profile?.display_name}</span>
</div>
</div>
</div>
4 changes: 3 additions & 1 deletion src/lib/components/views/engagement/Reply.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import { usersProfile } from "$lib/stores/users-profile.store";

export let event: any;
export let isRepost: boolean;

let newReply: any;
let profile = $usersProfile.get(event.From);

Expand Down Expand Up @@ -158,7 +160,7 @@
</Dialog.Trigger>
<Dialog.Content class="w-full text-primary border-border">
<Dialog.Header>
<PostPreview {event} user={profile} />
<PostPreview {event} {isRepost} user={profile} />
</Dialog.Header>
<form on:submit|preventDefault={() => {}}>
<div class="flex">
Expand Down
Loading
Loading