-import { myAuthRequired, newVote, showScores } from "@utils/app";
+import { myAuthRequired, newVote } from "@utils/app";
import { canShare, share } from "@utils/browser";
import { getExternalHost, getHttpBase } from "@utils/env";
import {
capitalizeFirstLetter,
futureDaysToUnixTime,
hostname,
- numToSI,
} from "@utils/helpers";
import { isImage, isVideo } from "@utils/media";
import {
import { Icon, PurgeWarning, Spinner } from "../common/icon";
import { MomentTime } from "../common/moment-time";
import { PictrsImage } from "../common/pictrs-image";
+import { VoteButtons, VoteButtonsCompact } from "../common/vote-buttons";
import { CommunityLink } from "../community/community-link";
import { PersonListing } from "../person/person-listing";
import { MetadataCard } from "./metadata-card";
);
}
- voteBar() {
- return (
- <div className={`vote-bar col-1 pe-0 small text-center`}>
- <button
- className={`btn-animate btn btn-link p-0 ${
- this.postView.my_vote == 1 ? "text-info" : "text-muted"
- }`}
- onClick={linkEvent(this, this.handleUpvote)}
- data-tippy-content={I18NextService.i18n.t("upvote")}
- aria-label={I18NextService.i18n.t("upvote")}
- aria-pressed={this.postView.my_vote === 1}
- >
- {this.state.upvoteLoading ? (
- <Spinner />
- ) : (
- <Icon icon="arrow-up1" classes="upvote" />
- )}
- </button>
- {showScores() ? (
- <div
- className={`unselectable pointer text-muted px-1 post-score`}
- data-tippy-content={this.pointsTippy}
- >
- {numToSI(this.postView.counts.score)}
- </div>
- ) : (
- <div className="p-1"></div>
- )}
- {this.props.enableDownvotes && (
- <button
- className={`btn-animate btn btn-link p-0 ${
- this.postView.my_vote == -1 ? "text-danger" : "text-muted"
- }`}
- onClick={linkEvent(this, this.handleDownvote)}
- data-tippy-content={I18NextService.i18n.t("downvote")}
- aria-label={I18NextService.i18n.t("downvote")}
- aria-pressed={this.postView.my_vote === -1}
- >
- {this.state.downvoteLoading ? (
- <Spinner />
- ) : (
- <Icon icon="arrow-down1" classes="downvote" />
- )}
- </button>
- )}
- </div>
- );
- }
-
get postLink() {
const post = this.postView.post;
return (
<Icon icon="fedilink" inline />
</a>
)}
- {mobile && !this.props.viewOnly && this.mobileVotes}
+ {mobile && !this.props.viewOnly && (
+ <VoteButtonsCompact
+ postListing={this}
+ enableDownvotes={this.props.enableDownvotes}
+ handleUpvote={this.handleUpvote}
+ handleDownvote={this.handleDownvote}
+ counts={this.postView.counts}
+ my_vote={this.postView.my_vote}
+ />
+ )}
{UserService.Instance.myUserInfo &&
!this.props.viewOnly &&
this.postActions()}
: pv.unread_comments;
}
- get mobileVotes() {
- // TODO: make nicer
- const tippy = showScores()
- ? { "data-tippy-content": this.pointsTippy }
- : {};
- return (
- <>
- <div>
- <button
- className={`btn-animate btn py-0 px-1 ${
- this.postView.my_vote === 1 ? "text-info" : "text-muted"
- }`}
- {...tippy}
- onClick={linkEvent(this, this.handleUpvote)}
- aria-label={I18NextService.i18n.t("upvote")}
- aria-pressed={this.postView.my_vote === 1}
- >
- {this.state.upvoteLoading ? (
- <Spinner />
- ) : (
- <>
- <Icon icon="arrow-up1" classes="icon-inline small" />
- {showScores() && (
- <span className="ms-2">
- {numToSI(this.postView.counts.upvotes)}
- </span>
- )}
- </>
- )}
- </button>
- {this.props.enableDownvotes && (
- <button
- className={`ms-2 btn-animate btn py-0 px-1 ${
- this.postView.my_vote === -1 ? "text-danger" : "text-muted"
- }`}
- onClick={linkEvent(this, this.handleDownvote)}
- {...tippy}
- aria-label={I18NextService.i18n.t("downvote")}
- aria-pressed={this.postView.my_vote === -1}
- >
- {this.state.downvoteLoading ? (
- <Spinner />
- ) : (
- <>
- <Icon icon="arrow-down1" classes="icon-inline small" />
- {showScores() && (
- <span
- className={classNames("ms-2", {
- invisible: this.postView.counts.downvotes === 0,
- })}
- >
- {numToSI(this.postView.counts.downvotes)}
- </span>
- )}
- </>
- )}
- </button>
- )}
- </div>
- </>
- );
- }
-
get saveButton() {
const saved = this.postView.saved;
const label = saved
<button
className="btn btn-link btn-sm d-flex align-items-center rounded-0 dropdown-item"
onClick={linkEvent(this, this.handleDeleteClick)}
- aria-label={label}
>
{this.state.deleteLoading ? (
<Spinner />
{this.postTitleLine()}
</div>
<div className="col-4">
- {/* Post body prev or thumbnail */}
+ {/* Post thumbnail */}
{!this.state.imageExpanded && this.thumbnail()}
</div>
</div>
{/* The larger view*/}
<div className="d-none d-sm-block">
<article className="row post-container">
- {!this.props.viewOnly && this.voteBar()}
+ {!this.props.viewOnly && (
+ <VoteButtons
+ postListing={this}
+ enableDownvotes={this.props.enableDownvotes}
+ handleUpvote={this.handleUpvote}
+ handleDownvote={this.handleDownvote}
+ counts={this.postView.counts}
+ my_vote={this.postView.my_vote}
+ />
+ )}
<div className="col-sm-2 pe-0 post-media">
<div className="">{this.thumbnail()}</div>
</div>