Fixing saved / starred. Fixes #42

This commit is contained in:
Dessalines 2020-09-26 11:18:49 -05:00
parent 5c740cdff0
commit be939c90a9
2 changed files with 325 additions and 297 deletions

View file

@ -54,6 +54,7 @@ interface PostListingState {
imageExpanded: boolean; imageExpanded: boolean;
viewSource: boolean; viewSource: boolean;
showAdvanced: boolean; showAdvanced: boolean;
showMoreMobile: boolean;
my_vote: number; my_vote: number;
score: number; score: number;
upvotes: number; upvotes: number;
@ -85,6 +86,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
imageExpanded: false, imageExpanded: false,
viewSource: false, viewSource: false,
showAdvanced: false, showAdvanced: false,
showMoreMobile: false,
my_vote: this.props.post.my_vote, my_vote: this.props.post.my_vote,
score: this.props.post.score, score: this.props.post.score,
upvotes: this.props.post.upvotes, upvotes: this.props.post.upvotes,
@ -493,7 +495,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
commentsLine(mobile: boolean = false) { commentsLine(mobile: boolean = false) {
let post = this.props.post; let post = this.props.post;
return ( return (
<div class="d-flex justify-content-between justify-content-lg-start flex-wrap text-muted font-weight-bold"> <div class="d-flex justify-content-between justify-content-lg-start flex-wrap text-muted font-weight-bold mb-1">
<button class="btn btn-link text-muted p-0"> <button class="btn btn-link text-muted p-0">
<Link <Link
className="text-muted small" className="text-muted small"
@ -510,9 +512,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
})} })}
</Link> </Link>
</button> </button>
{!mobile && this.state.downvotes !== 0 && ( {!mobile && (
<>
{this.state.downvotes !== 0 && (
<button <button
class="btn text-muted py-0" class="btn text-muted py-0 pr-0"
data-tippy-content={this.pointsTippy} data-tippy-content={this.pointsTippy}
> >
<small> <small>
@ -523,6 +527,25 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
</small> </small>
</button> </button>
)} )}
{!this.props.showBody && (
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleSavePostClick)}
data-tippy-content={
post.saved ? i18n.t('unsave') : i18n.t('save')
}
>
<small>
<svg
class={`icon icon-inline ${post.saved && 'text-warning'}`}
>
<use xlinkHref="#icon-star"></use>
</svg>
</small>
</button>
)}
</>
)}
{/* This is an expanding spacer for mobile */} {/* This is an expanding spacer for mobile */}
<div className="flex-grow-1"></div> <div className="flex-grow-1"></div>
{mobile && ( {mobile && (
@ -541,7 +564,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
{this.state.upvotes} {this.state.upvotes}
</button> </button>
<button <button
className={`ml-2 btn-animate btn py-0 px-1 ${ className={`ml-2 btn-animate btn py-0 pl-1 ${
this.state.my_vote == -1 ? 'text-danger' : 'text-muted' this.state.my_vote == -1 ? 'text-danger' : 'text-muted'
}`} }`}
onClick={linkEvent(this, this.handlePostDisLike)} onClick={linkEvent(this, this.handlePostDisLike)}
@ -556,7 +579,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
</button> </button>
</div> </div>
<button <button
class="btn btn-link btn-animate text-muted py-0 pl-1 pr-0" class="btn btn-link btn-animate text-muted py-0 pl-1"
onClick={linkEvent(this, this.handleSavePostClick)} onClick={linkEvent(this, this.handleSavePostClick)}
data-tippy-content={ data-tippy-content={
post.saved ? i18n.t('unsave') : i18n.t('save') post.saved ? i18n.t('unsave') : i18n.t('save')
@ -566,6 +589,19 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
<use xlinkHref="#icon-star"></use> <use xlinkHref="#icon-star"></use>
</svg> </svg>
</button> </button>
{!this.state.showMoreMobile && this.props.showBody && (
<button
class="btn btn-link btn-animate text-muted py-0 p-0"
onClick={linkEvent(this, this.handleShowMoreMobile)}
data-tippy-content={i18n.t('more')}
>
<svg class="icon icon-inline">
<use xlinkHref="#icon-more-vertical"></use>
</svg>
</button>
)}
{this.state.showMoreMobile && this.postActions(mobile)}
</> </>
)} )}
</div> </div>
@ -591,17 +627,30 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
); );
} }
postActions() { postActions(mobile: boolean = false) {
let post = this.props.post; let post = this.props.post;
return ( return (
<ul class="list-inline mb-1 text-muted font-weight-bold"> UserService.Instance.user && (
{UserService.Instance.user && (
<> <>
{this.props.showBody && ( {this.props.showBody && (
<> <>
<li className="list-inline-item"> {!mobile && (
<button
class="btn btn-link btn-animate text-muted py-0 pl-0"
onClick={linkEvent(this, this.handleSavePostClick)}
data-tippy-content={
post.saved ? i18n.t('unsave') : i18n.t('save')
}
>
<svg
class={`icon icon-inline ${post.saved && 'text-warning'}`}
>
<use xlinkHref="#icon-star"></use>
</svg>
</button>
)}
<Link <Link
className="btn btn-link btn-animate text-muted" className="btn btn-link btn-animate text-muted py-0"
to={`/create_post${this.crossPostParams}`} to={`/create_post${this.crossPostParams}`}
title={i18n.t('cross_post')} title={i18n.t('cross_post')}
> >
@ -609,14 +658,12 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
<use xlinkHref="#icon-copy"></use> <use xlinkHref="#icon-copy"></use>
</svg> </svg>
</Link> </Link>
</li>
</> </>
)} )}
{this.myPost && this.props.showBody && ( {this.myPost && this.props.showBody && (
<> <>
<li className="list-inline-item">
<button <button
class="btn btn-link btn-animate text-muted" class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleEditClick)} onClick={linkEvent(this, this.handleEditClick)}
data-tippy-content={i18n.t('edit')} data-tippy-content={i18n.t('edit')}
> >
@ -624,31 +671,25 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
<use xlinkHref="#icon-edit"></use> <use xlinkHref="#icon-edit"></use>
</svg> </svg>
</button> </button>
</li>
<li className="list-inline-item">
<button <button
class="btn btn-link btn-animate text-muted" class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleDeleteClick)} onClick={linkEvent(this, this.handleDeleteClick)}
data-tippy-content={ data-tippy-content={
!post.deleted ? i18n.t('delete') : i18n.t('restore') !post.deleted ? i18n.t('delete') : i18n.t('restore')
} }
> >
<svg <svg
class={`icon icon-inline ${ class={`icon icon-inline ${post.deleted && 'text-danger'}`}
post.deleted && 'text-danger'
}`}
> >
<use xlinkHref="#icon-trash"></use> <use xlinkHref="#icon-trash"></use>
</svg> </svg>
</button> </button>
</li>
</> </>
)} )}
{!this.state.showAdvanced && this.props.showBody ? ( {!this.state.showAdvanced && this.props.showBody ? (
<li className="list-inline-item">
<button <button
class="btn btn-link btn-animate text-muted" class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleShowAdvanced)} onClick={linkEvent(this, this.handleShowAdvanced)}
data-tippy-content={i18n.t('more')} data-tippy-content={i18n.t('more')}
> >
@ -656,13 +697,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
<use xlinkHref="#icon-more-vertical"></use> <use xlinkHref="#icon-more-vertical"></use>
</svg> </svg>
</button> </button>
</li>
) : ( ) : (
<> <>
{this.props.showBody && post.body && ( {this.props.showBody && post.body && (
<li className="list-inline-item">
<button <button
class="btn btn-link btn-animate text-muted" class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleViewSource)} onClick={linkEvent(this, this.handleViewSource)}
data-tippy-content={i18n.t('view_source')} data-tippy-content={i18n.t('view_source')}
> >
@ -674,30 +713,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
<use xlinkHref="#icon-file-text"></use> <use xlinkHref="#icon-file-text"></use>
</svg> </svg>
</button> </button>
</li>
)} )}
{this.canModOnSelf && ( {this.canModOnSelf && (
<> <>
<li className="list-inline-item">
<button <button
class="btn btn-link btn-animate text-muted" class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleModLock)} onClick={linkEvent(this, this.handleModLock)}
data-tippy-content={ data-tippy-content={
post.locked ? i18n.t('unlock') : i18n.t('lock') post.locked ? i18n.t('unlock') : i18n.t('lock')
} }
> >
<svg <svg
class={`icon icon-inline ${ class={`icon icon-inline ${post.locked && 'text-danger'}`}
post.locked && 'text-danger'
}`}
> >
<use xlinkHref="#icon-lock"></use> <use xlinkHref="#icon-lock"></use>
</svg> </svg>
</button> </button>
</li>
<li className="list-inline-item">
<button <button
class="btn btn-link btn-animate text-muted" class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleModSticky)} onClick={linkEvent(this, this.handleModSticky)}
data-tippy-content={ data-tippy-content={
post.stickied ? i18n.t('unsticky') : i18n.t('sticky') post.stickied ? i18n.t('unsticky') : i18n.t('sticky')
@ -711,13 +744,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
<use xlinkHref="#icon-pin"></use> <use xlinkHref="#icon-pin"></use>
</svg> </svg>
</button> </button>
</li>
</> </>
)} )}
{/* Mods can ban from community, and appoint as mods to community */} {/* Mods can ban from community, and appoint as mods to community */}
{(this.canMod || this.canAdmin) && ( {(this.canMod || this.canAdmin) &&
<li className="list-inline-item"> (!post.removed ? (
{!post.removed ? (
<span <span
class="pointer" class="pointer"
onClick={linkEvent(this, this.handleModRemoveShow)} onClick={linkEvent(this, this.handleModRemoveShow)}
@ -731,14 +762,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
> >
{i18n.t('restore')} {i18n.t('restore')}
</span> </span>
)} ))}
</li>
)}
{this.canMod && ( {this.canMod && (
<> <>
{!this.isMod && ( {!this.isMod &&
<li className="list-inline-item"> (!post.banned_from_community ? (
{!post.banned_from_community ? (
<span <span
class="pointer" class="pointer"
onClick={linkEvent( onClick={linkEvent(
@ -758,32 +786,24 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
> >
{i18n.t('unban')} {i18n.t('unban')}
</span> </span>
)} ))}
</li>
)}
{!post.banned_from_community && post.creator_local && ( {!post.banned_from_community && post.creator_local && (
<li className="list-inline-item">
<span <span
class="pointer" class="pointer"
onClick={linkEvent( onClick={linkEvent(this, this.handleAddModToCommunity)}
this,
this.handleAddModToCommunity
)}
> >
{this.isMod {this.isMod
? i18n.t('remove_as_mod') ? i18n.t('remove_as_mod')
: i18n.t('appoint_as_mod')} : i18n.t('appoint_as_mod')}
</span> </span>
</li>
)} )}
</> </>
)} )}
{/* Community creators and admins can transfer community to another mod */} {/* Community creators and admins can transfer community to another mod */}
{(this.amCommunityCreator || this.canAdmin) && {(this.amCommunityCreator || this.canAdmin) &&
this.isMod && this.isMod &&
post.creator_local && ( post.creator_local &&
<li className="list-inline-item"> (!this.state.showConfirmTransferCommunity ? (
{!this.state.showConfirmTransferCommunity ? (
<span <span
class="pointer" class="pointer"
onClick={linkEvent( onClick={linkEvent(
@ -800,10 +820,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
</span> </span>
<span <span
class="pointer d-inline-block mr-1" class="pointer d-inline-block mr-1"
onClick={linkEvent( onClick={linkEvent(this, this.handleTransferCommunity)}
this,
this.handleTransferCommunity
)}
> >
{i18n.t('yes')} {i18n.t('yes')}
</span> </span>
@ -817,15 +834,12 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
{i18n.t('no')} {i18n.t('no')}
</span> </span>
</> </>
)} ))}
</li>
)}
{/* Admins can ban from all, and appoint other admins */} {/* Admins can ban from all, and appoint other admins */}
{this.canAdmin && ( {this.canAdmin && (
<> <>
{!this.isAdmin && ( {!this.isAdmin &&
<li className="list-inline-item"> (!post.banned ? (
{!post.banned ? (
<span <span
class="pointer" class="pointer"
onClick={linkEvent(this, this.handleModBanShow)} onClick={linkEvent(this, this.handleModBanShow)}
@ -839,11 +853,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
> >
{i18n.t('unban_from_site')} {i18n.t('unban_from_site')}
</span> </span>
)} ))}
</li>
)}
{!post.banned && post.creator_local && ( {!post.banned && post.creator_local && (
<li className="list-inline-item">
<span <span
class="pointer" class="pointer"
onClick={linkEvent(this, this.handleAddAdmin)} onClick={linkEvent(this, this.handleAddAdmin)}
@ -852,14 +863,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
? i18n.t('remove_as_admin') ? i18n.t('remove_as_admin')
: i18n.t('appoint_as_admin')} : i18n.t('appoint_as_admin')}
</span> </span>
</li>
)} )}
</> </>
)} )}
{/* Site Creator can transfer to another admin */} {/* Site Creator can transfer to another admin */}
{this.amSiteCreator && this.isAdmin && ( {this.amSiteCreator &&
<li className="list-inline-item"> this.isAdmin &&
{!this.state.showConfirmTransferSite ? ( (!this.state.showConfirmTransferSite ? (
<span <span
class="pointer" class="pointer"
onClick={linkEvent( onClick={linkEvent(
@ -890,14 +900,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
{i18n.t('no')} {i18n.t('no')}
</span> </span>
</> </>
)} ))}
</li>
)}
</> </>
)} )}
</> </>
)} )
</ul>
); );
} }
@ -1014,7 +1021,6 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
{this.commentsLine(true)} {this.commentsLine(true)}
{this.duplicatesLine()} {this.duplicatesLine()}
{this.postActions()}
{this.removeAndBanDialogs()} {this.removeAndBanDialogs()}
</div> </div>
</div> </div>
@ -1443,6 +1449,13 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
setupTippy(); setupTippy();
} }
handleShowMoreMobile(i: PostListing) {
i.state.showMoreMobile = !i.state.showMoreMobile;
i.state.showAdvanced = !i.state.showAdvanced;
i.setState(i.state);
setupTippy();
}
get pointsTippy(): string { get pointsTippy(): string {
let points = i18n.t('number_of_points', { let points = i18n.t('number_of_points', {
count: this.state.score, count: this.state.score,

View file

@ -43,6 +43,7 @@ import {
setAuth, setAuth,
lemmyHttp, lemmyHttp,
previewLines, previewLines,
editPostFindRes,
} from '../utils'; } from '../utils';
import { UserListing } from './user-listing'; import { UserListing } from './user-listing';
import { HtmlTags } from './html-tags'; import { HtmlTags } from './html-tags';
@ -884,6 +885,9 @@ export class User extends Component<any, UserState> {
this.props.history.push( this.props.history.push(
`/u/${this.state.userName}/view/${viewStr}/sort/${sortStr}/page/${page}` `/u/${this.state.userName}/view/${viewStr}/sort/${sortStr}/page/${page}`
); );
this.state.loading = true;
this.setState(this.state);
this.fetchUserData();
} }
handlePageChange(page: number) { handlePageChange(page: number) {
@ -1141,6 +1145,17 @@ export class User extends Component<any, UserState> {
const data = res.data as CommentResponse; const data = res.data as CommentResponse;
saveCommentRes(data, this.state.userRes.comments); saveCommentRes(data, this.state.userRes.comments);
this.setState(this.state); this.setState(this.state);
} else if (
res.op == UserOperation.EditPost ||
res.op == UserOperation.DeletePost ||
res.op == UserOperation.RemovePost ||
res.op == UserOperation.LockPost ||
res.op == UserOperation.StickyPost ||
res.op == UserOperation.SavePost
) {
let data = res.data as PostResponse;
editPostFindRes(data, this.state.userRes.posts);
this.setState(this.state);
} else if (res.op == UserOperation.CreatePostLike) { } else if (res.op == UserOperation.CreatePostLike) {
const data = res.data as PostResponse; const data = res.data as PostResponse;
createPostLikeFindRes(data, this.state.userRes.posts); createPostLikeFindRes(data, this.state.userRes.posts);