Skip to content

Commit

Permalink
feat+fix: implement UI changes for profile view
Browse files Browse the repository at this point in the history
  • Loading branch information
rupansh committed Aug 23, 2024
1 parent 9165e2e commit c0cd2df
Show file tree
Hide file tree
Showing 10 changed files with 307 additions and 125 deletions.
2 changes: 1 addition & 1 deletion ssr/src/component/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ pub mod login_modal;
pub mod modal;
pub mod nav;
pub mod nav_icons;
pub mod no_more_posts;
pub mod option;
pub mod overlay;
pub mod profile_placeholders;
pub mod scrolling_post_view;
pub mod social;
pub mod spinner;
Expand Down
21 changes: 0 additions & 21 deletions ssr/src/component/no_more_posts.rs

This file was deleted.

70 changes: 70 additions & 0 deletions ssr/src/component/profile_placeholders.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use crate::utils::icon::icon_gen;

icon_gen!(
NoMorePostsGraphic,
view_box = "0 0 186 174",
r###"<circle r="4.2" fill="#27308C" opacity=".1" transform="matrix(1 0 0 -1 139 73.6)"/>
<circle r="2.5" fill="#27308C" opacity=".2" transform="matrix(1 0 0 -1 67 168.2)"/>
<mask id="a" width="78" height="78" x="23" y="18" maskUnits="userSpaceOnUse" style="mask-type:alpha">
<rect width="66.9" height="66.9" fill="#FFC467" rx="16" transform="matrix(.93383 -.357716 .357685 .933842 18.6 37.3)"/>
</mask>
<g mask="url(#a)">
<rect width="66.9" height="66.9" fill="#FFC467" rx="16" transform="matrix(.93383 -.357716 .357685 .933842 18.6 37.3)"/>
<path fill="#151A53" d="M39.6 59.5a18 18 0 0 1 16.6-19.2l44.2-3.3a18 18 0 0 1 19.3 16.6l5.6 76.7a6 6 0 0 1-8.6 5.8l-32.4-16-29.7 20.6a6 6 0 0 1-9.4-4.5l-5.6-76.7ZM27 31.7a4 4 0 0 1 4.3-5.4l5 .7a4 4 0 0 1 2.5 6.4l-3 4a4 4 0 0 1-7-1L27 31.6Z" opacity=".1"/>
</g>
<path fill="#5665FF" d="M74.8 69.7a18 18 0 0 1 20.4-15.2l43.9 6.4a18 18 0 0 1 15.2 20.5l-11.2 76a6 6 0 0 1-9.7 3.8l-28.1-22.7-33.5 13.7a6 6 0 0 1-8.2-6.4l11.2-76.1Z" opacity=".1"/>
<path fill="#3747E9" d="M43.7 58.7a18 18 0 0 1 16.7-19.3l44.2-3.2a18 18 0 0 1 19.3 16.6l5.6 76.7a6 6 0 0 1-8.6 5.8l-32.4-16-29.7 20.6a6 6 0 0 1-9.4-4.5l-5.7-76.7Z"/>
<path fill="#FF9E87" d="M27.8 29.2a4 4 0 0 1 4.3-5.5l5 .7a4 4 0 0 1 2.5 6.5l-3 3.9a4 4 0 0 1-7-1l-1.8-4.6ZM7.6 125a3.5 3.5 0 1 1 6.5-2.7 3.5 3.5 0 0 1-6.5 2.7ZM159.5 105.4a6.8 6.8 0 1 1 12.7-5 6.8 6.8 0 0 1-12.7 5Z"/>
<path fill="#FFE1DA" d="M120 162.7a4 4 0 0 1 1.9-6.7l4.8-1.3a4 4 0 0 1 4.9 5l-1.3 4.8a4 4 0 0 1-6.8 1.7l-3.5-3.5Z"/>
<path stroke="#fff" stroke-width="3" d="M69.7 58.4 99 56.3"/>
<path fill="#3F13E4" d="M149 32.3c-2.5 6-6.2-10.1-12.3-12.5-6-2.4-21-1.3-18.6-7.4 2.3-6 19.9-6.5 25.9-4.1 6 2.4 7.3 18 5 24Z" opacity=".3"/>"###
);

icon_gen!(
NoMoreBetsGraphic,
view_box = "0 0 210 205",
r###"<path d="M18.0256 39.3838C16.8783 36.5263 19.2545 33.4984 22.3028 33.9335L23.742 34.1389C26.7903 34.574 28.2244 38.1459 26.3234 40.5682L25.426 41.7119C23.525 44.1342 19.7146 43.5903 18.5673 40.7329L18.0256 39.3838Z" fill="#FFA8D7"/>
<path d="M5.37362 103.781C4.55381 101.739 6.25172 99.5753 8.42986 99.8862C10.608 100.197 11.6328 102.749 10.2744 104.48C8.91611 106.211 6.19343 105.822 5.37362 103.781Z" fill="#FFA8D7"/>
<path d="M188.957 146.678C187.363 142.708 190.665 138.5 194.9 139.105C199.136 139.71 201.128 144.673 198.487 148.038C195.846 151.404 190.551 150.648 188.957 146.678Z" fill="#FFA8D7"/>
<path opacity="0.2" d="M160.651 128.546C158.491 126.351 159.517 122.641 162.498 121.868L163.905 121.503C166.886 120.73 169.586 123.473 168.765 126.441L168.377 127.842C167.556 130.81 163.831 131.776 161.671 129.582L160.651 128.546Z" fill="#FF9E87"/>
<path opacity="0.3" d="M161.085 30.1576C158.146 34.5167 157.964 21.0824 153.605 18.1433C149.246 15.2042 137.135 13.3794 140.074 9.02032C143.013 4.66126 157.019 7.32421 161.378 10.2633C165.737 13.2024 164.024 25.7986 161.085 30.1576Z" fill="#FF0F91"/>
<circle opacity="0.2" cx="3" cy="3" r="3" transform="matrix(1 0 0 -1 80.0391 204.766)" fill="#27308C"/>
<path d="M34.699 192.18C34.4523 191.308 33.2194 189.722 30.262 190.356C27.3045 190.99 25.7759 189.283 25.3812 188.35" stroke="#FF83CC" stroke-width="3" stroke-linecap="round"/>
<path d="M193.056 34.9113C192.718 36.3102 193.188 39.4652 197.774 40.8943C202.36 42.3234 203.144 45.8773 202.963 47.4756" stroke="#FF83CC" stroke-width="3" stroke-linecap="round"/>
<path d="M86.5078 187C127.929 187 161.508 153.421 161.508 112C161.508 70.5786 127.929 37 86.5078 37C45.0865 37 11.5078 70.5786 11.5078 112C11.5078 153.421 45.0865 187 86.5078 187Z" fill="#E2017B"/>
<g filter="url(#filter0_d_516_779)">
<path d="M52.5078 71H187.508C188.834 71 190.106 71.5268 191.043 72.4645C191.981 73.4021 192.508 74.6739 192.508 76V101C192.508 102.326 191.981 103.598 191.043 104.536C190.106 105.473 188.834 106 187.508 106H52.5078C51.1817 106 49.91 105.473 48.9723 104.536C48.0346 103.598 47.5078 102.326 47.5078 101V76C47.5078 74.6739 48.0346 73.4021 48.9723 72.4645C49.91 71.5268 51.1817 71 52.5078 71V71Z" fill="white"/>
</g>
<path d="M116.508 79H90.5078C88.851 79 87.5078 80.3431 87.5078 82C87.5078 83.6569 88.851 85 90.5078 85H116.508C118.165 85 119.508 83.6569 119.508 82C119.508 80.3431 118.165 79 116.508 79Z" fill="#FE54B0"/>
<path d="M134.508 92H90.5078C88.851 92 87.5078 93.3431 87.5078 95C87.5078 96.6569 88.851 98 90.5078 98H134.508C136.165 98 137.508 96.6569 137.508 95C137.508 93.3431 136.165 92 134.508 92Z" fill="#FFBFE2"/>
<path d="M79.5078 88.5C79.5078 80.4919 73.0159 74 65.0078 74C56.9997 74 50.5078 80.4919 50.5078 88.5C50.5078 96.5081 56.9997 103 65.0078 103C73.0159 103 79.5078 96.5081 79.5078 88.5Z" fill="#18191A"/>
<g filter="url(#filter1_d_516_779)">
<path d="M172.508 116H37.5078C34.7464 116 32.5078 118.239 32.5078 121V146C32.5078 148.761 34.7464 151 37.5078 151H172.508C175.269 151 177.508 148.761 177.508 146V121C177.508 118.239 175.269 116 172.508 116Z" fill="white"/>
</g>
<path d="M101.508 124H75.5078C73.851 124 72.5078 125.343 72.5078 127C72.5078 128.657 73.851 130 75.5078 130H101.508C103.165 130 104.508 128.657 104.508 127C104.508 125.343 103.165 124 101.508 124Z" fill="#FE54B0"/>
<path d="M119.508 137H75.5078C73.851 137 72.5078 138.343 72.5078 140C72.5078 141.657 73.851 143 75.5078 143H119.508C121.165 143 122.508 141.657 122.508 140C122.508 138.343 121.165 137 119.508 137Z" fill="#FFBFE2"/>
<path d="M64.5078 133.5C64.5078 125.492 58.0159 119 50.0078 119C41.9997 119 35.5078 125.492 35.5078 133.5C35.5078 141.508 41.9997 148 50.0078 148C58.0159 148 64.5078 141.508 64.5078 133.5Z" fill="#18191A"/>
<path d="M64.8143 88.1444C63.0304 87.6856 62.4567 87.2111 62.4567 86.4722C62.4567 85.6244 63.2504 85.0333 64.5785 85.0333C65.9774 85.0333 66.496 85.6944 66.5432 86.6667H68.2799C68.2249 85.3289 67.3998 84.1 65.7573 83.7033V82H63.3998V83.68C61.8752 84.0067 60.6493 84.9867 60.6493 86.4878C60.6493 88.2844 62.1502 89.1789 64.3428 89.7C66.3074 90.1667 66.7003 90.8511 66.7003 91.5744C66.7003 92.1111 66.3153 92.9667 64.5785 92.9667C62.9597 92.9667 62.3231 92.2511 62.2367 91.3333H60.5078C60.6021 93.0367 61.8909 93.9933 63.3998 94.3122V96H65.7573V94.3278C67.2897 94.04 68.5078 93.1611 68.5078 91.5667C68.5078 89.3578 66.5982 88.6033 64.8143 88.1444Z" fill="white"/>
<path d="M50.8143 133.144C49.0304 132.686 48.4567 132.211 48.4567 131.472C48.4567 130.624 49.2504 130.033 50.5785 130.033C51.9774 130.033 52.496 130.694 52.5432 131.667H54.2799C54.2249 130.329 53.3998 129.1 51.7573 128.703V127H49.3998V128.68C47.8752 129.007 46.6493 129.987 46.6493 131.488C46.6493 133.284 48.1502 134.179 50.3428 134.7C52.3074 135.167 52.7003 135.851 52.7003 136.574C52.7003 137.111 52.3153 137.967 50.5785 137.967C48.9597 137.967 48.3231 137.251 48.2367 136.333H46.5078C46.6021 138.037 47.8909 138.993 49.3998 139.312V141H51.7573V139.328C53.2897 139.04 54.5078 138.161 54.5078 136.567C54.5078 134.358 52.5982 133.603 50.8143 133.144Z" fill="white"/>
<defs>
<filter id="filter0_d_516_779" x="41.5078" y="68" width="157" height="47" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="3"/>
<feGaussianBlur stdDeviation="3"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.161 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_516_779"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_516_779" result="shape"/>
</filter>
<filter id="filter1_d_516_779" x="26.5078" y="113" width="157" height="47" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="3"/>
<feGaussianBlur stdDeviation="3"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.161 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_516_779"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_516_779" result="shape"/>
</filter>
</defs>
"###
);
2 changes: 2 additions & 0 deletions ssr/src/error_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub fn ErrorTemplate(
}

view! {
<div class="text-white">
<h1>{if errors.len() > 1 { "Errors" } else { "Error" }}</h1>
<For
// a function that returns the items we're iterating over; a signal is fine
Expand All @@ -70,5 +71,6 @@ pub fn ErrorTemplate(
}
}
/>
</div>
}
}
11 changes: 7 additions & 4 deletions ssr/src/page/post_view/bet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,13 +294,16 @@ fn HNWonLost(participation: BetDetails) -> impl IntoView {
fn BetTimer(participation: BetDetails, refetch_bet: Trigger) -> impl IntoView {
let bet_duration = participation.bet_duration().as_secs();
// Add some overhead to avoid fetching bet status multiple times
let time_remaining = create_rw_signal(participation.time_remaining() + Duration::from_secs(30));
// let time_remaining = create_rw_signal(participation.time_remaining() + Duration::from_secs(30));
let time_remaining = create_rw_signal(participation.time_remaining());
_ = use_interval_fn(
move || {
time_remaining.try_update(|t| *t = t.saturating_sub(Duration::from_secs(1)));
if time_remaining.try_get_untracked() == Some(Duration::ZERO) {
refetch_bet.notify();
}
_ = refetch_bet;
// TODO: notify once time_remaining is correct
// if time_remaining.try_get_untracked() == Some(Duration::ZERO) {
// refetch_bet.notify();
// }
},
1000,
);
Expand Down
6 changes: 3 additions & 3 deletions ssr/src/page/profile/ic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use crate::{
pub fn ProfileStream<Prov, EF, N>(
provider: Prov,
children: EF,
#[prop(optional)] empty_graphic: Option<icondata::Icon>,
#[prop(optional)] empty_text: String,
empty_graphic: icondata::Icon,
#[prop(into)] empty_text: String,
) -> impl IntoView
where
Prov: CursoredDataProvider + Clone + 'static,
Expand All @@ -30,7 +30,7 @@ where
empty_content=move || {
view! {
<div class="flex flex-col pt-9 gap-2 w-full justify-center items-center">
<Icon class="w-36 h-36" icon=empty_graphic.unwrap()/>
<Icon class="w-36 h-36" icon=empty_graphic/>
<span class="text-lg text-white">{empty_text.clone()}</span>
</div>
}
Expand Down
6 changes: 3 additions & 3 deletions ssr/src/page/profile/posts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use candid::Principal;

use crate::{
canister::utils::bg_url,
component::no_more_posts::NoMorePostsGraphic,
component::profile_placeholders::NoMorePostsGraphic,
state::canisters::{auth_canisters_store, unauth_canisters},
utils::{
event_streaming::events::ProfileViewVideo, posts::PostDetails, profile::PostsProvider,
Expand Down Expand Up @@ -35,7 +35,7 @@ fn Post(details: PostDetails, user_canister: Principal, _ref: NodeRef<html::Div>
};

let handle_image_error =
move |_| image_error.update(|image_error| *image_error = !*image_error);
move |_| _ = image_error.try_update(|image_error| *image_error = !*image_error);

let canisters = auth_canisters_store();
let post_details = details.clone();
Expand Down Expand Up @@ -100,7 +100,7 @@ pub fn ProfilePosts(user_canister: Principal) -> impl IntoView {
<ProfileStream
provider
empty_graphic=NoMorePostsGraphic
empty_text="No Videos Uploaded yet".into()
empty_text="No Videos Uploaded yet"
children=move |details, _ref| {
view! {
<Post
Expand Down
95 changes: 69 additions & 26 deletions ssr/src/page/profile/profile_iter.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,87 @@
use candid::Principal;
use futures::stream::{FuturesOrdered, StreamExt, TryStreamExt};

use crate::{
canister::individual_user_template::{GetPostsOfUserProfileError, Result5},
state::canisters::Canisters,
utils::posts::{FetchCursor, PostDetails, PostViewError},
utils::posts::{get_post_uid, PostDetails, PostViewError},
};

pub struct ProfileVideoStream<'a, const AUTH: bool> {
cursor: FetchCursor,
canisters: &'a Canisters<AUTH>,
user_canister: Principal,
#[derive(Clone, Copy, PartialEq)]
pub struct FixedFetchCursor<const LIMIT: u64> {
pub start: u64,
pub limit: u64,
}

impl<'a, const AUTH: bool> ProfileVideoStream<'a, AUTH> {
pub fn new(
cursor: FetchCursor,
canisters: &'a Canisters<AUTH>,
impl<const LIMIT: u64> FixedFetchCursor<LIMIT> {
pub fn advance(&mut self) {
self.start += self.limit;
self.limit = LIMIT;
}
}

pub struct PostsRes {
pub posts: Vec<PostDetails>,
pub end: bool,
}

pub(crate) trait ProfVideoStream<const LIMIT: u64>: Sized {
async fn fetch_next_posts<const AUTH: bool>(
cursor: FixedFetchCursor<LIMIT>,
canisters: &Canisters<AUTH>,
user_canister: Principal,
) -> Self {
Self {
cursor,
canisters,
user_canister,
}
) -> Result<PostsRes, PostViewError>;
}

pub struct ProfileVideoBetsStream;

impl ProfVideoStream<10> for ProfileVideoBetsStream {
async fn fetch_next_posts<const AUTH: bool>(
cursor: FixedFetchCursor<10>,
canisters: &Canisters<AUTH>,
user_canister: Principal,
) -> Result<PostsRes, PostViewError> {
let user = canisters.individual_user(user_canister).await?;
let bets = user
.get_hot_or_not_bets_placed_by_this_profile_with_pagination(cursor.start)
.await?;
let end = bets.len() < 10;
let posts = bets
.into_iter()
.map(|bet| get_post_uid(canisters, bet.canister_id, bet.post_id))
.collect::<FuturesOrdered<_>>()
.filter_map(|res| async { res.transpose() })
.try_collect::<Vec<_>>()
.await?;
Ok(PostsRes { posts, end })
}
}

pub struct ProfileVideoStream<const LIMIT: u64>;

pub async fn fetch_next_profile_posts(&self) -> Result<Vec<PostDetails>, PostViewError> {
let user = self.canisters.individual_user(self.user_canister).await?;
impl<const LIMIT: u64> ProfVideoStream<LIMIT> for ProfileVideoStream<LIMIT> {
async fn fetch_next_posts<const AUTH: bool>(
cursor: FixedFetchCursor<LIMIT>,
canisters: &Canisters<AUTH>,
user_canister: Principal,
) -> Result<PostsRes, PostViewError> {
let user = canisters.individual_user(user_canister).await?;
let posts = user
.get_posts_of_this_user_profile_with_pagination_cursor(
self.cursor.start,
self.cursor.limit,
)
.get_posts_of_this_user_profile_with_pagination_cursor(cursor.start, cursor.limit)
.await?;
match posts {
Result5::Ok(v) => Ok(v
.into_iter()
.map(|details| PostDetails::from_canister_post(AUTH, self.user_canister, details))
.collect::<Vec<PostDetails>>()),
Result5::Err(GetPostsOfUserProfileError::ReachedEndOfItemsList) => Ok(vec![]),
Result5::Ok(v) => {
let end = v.len() < LIMIT as usize;
let posts = v
.into_iter()
.map(|details| PostDetails::from_canister_post(AUTH, user_canister, details))
.collect::<Vec<_>>();
Ok(PostsRes { posts, end })
}
Result5::Err(GetPostsOfUserProfileError::ReachedEndOfItemsList) => Ok(PostsRes {
posts: vec![],
end: true,
}),
_ => Err(PostViewError::Canister(
"user canister refused to send posts".into(),
)),
Expand Down
Loading

0 comments on commit c0cd2df

Please sign in to comment.