"eslint": "^7.15.0",
"eslint-plugin-jane": "^9.0.4",
"husky": "^4.3.5",
- "lemmy-js-client": "^1.0.16",
+ "lemmy-js-client": "1.0.17-beta5",
"lint-staged": "^10.5.3",
"mini-css-extract-plugin": "^1.3.2",
"node-fetch": "^2.6.1",
import { initializeSite } from '../shared/initialize';
import { App } from '../shared/components/app';
-const site = window.isoData.site;
+const site = window.isoData.site_res;
initializeSite(site);
const wrapper = (
<BrowserRouter>
- <App site={window.isoData.site} />
+ <App siteRes={window.isoData.site_res} />
</BrowserRouter>
);
import { InitialFetchRequest, IsoData } from '../shared/interfaces';
import { routes } from '../shared/routes';
import IsomorphicCookie from 'isomorphic-cookie';
-import { setAuth } from '../shared/utils';
-import { GetSiteForm, LemmyHttp } from 'lemmy-js-client';
+import { GetSite, LemmyHttp } from 'lemmy-js-client';
import process from 'process';
import { Helmet } from 'inferno-helmet';
import { initializeSite } from '../shared/initialize';
const context = {} as any;
let auth: string = IsomorphicCookie.load('jwt', req);
- let getSiteForm: GetSiteForm = {};
- setAuth(getSiteForm, auth);
+ let getSiteForm: GetSite = { auth };
let promises: Promise<any>[] = [];
let isoData: IsoData = {
path: req.path,
- site,
+ site_res: site,
routeData,
lang,
};
const wrapper = (
<StaticRouter location={req.url} context={isoData}>
- <App site={isoData.site} />
+ <App siteRes={isoData.site_res} />
</StaticRouter>
);
if (context.url) {
UserOperation,
SiteResponse,
GetSiteResponse,
- SiteConfigForm,
+ SaveSiteConfig,
GetSiteConfigResponse,
- WebSocketJsonResponse,
GetSiteConfig,
} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+import { UserService, WebSocketService } from '../services';
import {
wsJsonToRes,
capitalizeFirstLetter,
setIsoData,
wsSubscribe,
isBrowser,
- setAuth,
+ wsUserOp,
} from '../utils';
import autosize from 'autosize';
import { SiteForm } from './site-form';
interface AdminSettingsState {
siteRes: GetSiteResponse;
siteConfigRes: GetSiteConfigResponse;
- siteConfigForm: SiteConfigForm;
+ siteConfigForm: SaveSiteConfig;
loading: boolean;
siteConfigLoading: boolean;
}
private isoData = setIsoData(this.context);
private subscription: Subscription;
private emptyState: AdminSettingsState = {
- siteRes: this.isoData.site,
+ siteRes: this.isoData.site_res,
siteConfigForm: {
config_hjson: null,
- auth: null,
+ auth: UserService.Instance.authField(),
},
siteConfigRes: {
config_hjson: null,
this.state.siteConfigLoading = false;
this.state.loading = false;
} else {
- WebSocketService.Instance.getSiteConfig();
+ WebSocketService.Instance.client.getSiteConfig({
+ auth: UserService.Instance.authField(),
+ });
}
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let form: GetSiteConfig = {};
- setAuth(form, req.auth);
+ let form: GetSiteConfig = { auth: req.auth };
return [req.client.getSiteConfig(form)];
}
}
get documentTitle(): string {
- return `${i18n.t('admin_settings')} - ${this.state.siteRes.site.name}`;
+ return `${i18n.t('admin_settings')} - ${
+ this.state.siteRes.site_view.site.name
+ }`;
}
render() {
) : (
<div class="row">
<div class="col-12 col-md-6">
- {this.state.siteRes.site.id && (
- <SiteForm site={this.state.siteRes.site} />
+ {this.state.siteRes.site_view.site.id && (
+ <SiteForm site={this.state.siteRes.site_view.site} />
)}
{this.admins()}
{this.bannedUsers()}
<ul class="list-unstyled">
{this.state.siteRes.admins.map(admin => (
<li class="list-inline-item">
- <UserListing
- user={{
- name: admin.name,
- preferred_username: admin.preferred_username,
- avatar: admin.avatar,
- id: admin.id,
- local: admin.local,
- actor_id: admin.actor_id,
- }}
- />
+ <UserListing user={admin.user} />
</li>
))}
</ul>
<ul class="list-unstyled">
{this.state.siteRes.banned.map(banned => (
<li class="list-inline-item">
- <UserListing
- user={{
- name: banned.name,
- preferred_username: banned.preferred_username,
- avatar: banned.avatar,
- id: banned.id,
- local: banned.local,
- actor_id: banned.actor_id,
- }}
- />
+ <UserListing user={banned.user} />
</li>
))}
</ul>
handleSiteConfigSubmit(i: AdminSettings, event: any) {
event.preventDefault();
i.state.siteConfigLoading = true;
- WebSocketService.Instance.saveSiteConfig(i.state.siteConfigForm);
+ WebSocketService.Instance.client.saveSiteConfig(i.state.siteConfigForm);
i.setState(i.state);
}
i.setState(i.state);
}
- parseMessage(msg: WebSocketJsonResponse) {
- console.log(msg);
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
this.context.router.history.push('/');
this.setState(this.state);
return;
} else if (msg.reconnect) {
- } else if (res.op == UserOperation.EditSite) {
- let data = res.data as SiteResponse;
- this.state.siteRes.site = data.site;
+ } else if (op == UserOperation.EditSite) {
+ let data = wsJsonToRes<SiteResponse>(msg).data;
+ this.state.siteRes.site_view = data.site_view;
this.setState(this.state);
toast(i18n.t('site_saved'));
- } else if (res.op == UserOperation.GetSiteConfig) {
- let data = res.data as GetSiteConfigResponse;
+ } else if (op == UserOperation.GetSiteConfig) {
+ let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
this.state.siteConfigRes = data;
this.state.loading = false;
this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
this.setState(this.state);
var textarea: any = document.getElementById(this.siteConfigTextAreaId);
autosize(textarea);
- } else if (res.op == UserOperation.SaveSiteConfig) {
- let data = res.data as GetSiteConfigResponse;
+ } else if (op == UserOperation.SaveSiteConfig) {
+ let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
this.state.siteConfigRes = data;
this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
this.state.siteConfigLoading = false;
import './styles.scss';
export interface AppProps {
- site: GetSiteResponse;
+ siteRes: GetSiteResponse;
}
export class App extends Component<AppProps, any> {
super(props, context);
}
render() {
+ let siteRes = this.props.siteRes;
return (
<>
<Provider i18next={i18n}>
<div>
- <Theme user={this.props.site.my_user} />
- {this.props.site &&
- this.props.site.site &&
- this.props.site.site.icon && (
+ <Theme user={siteRes.my_user} />
+ {siteRes &&
+ siteRes.site_view.site &&
+ this.props.siteRes.site_view.site.icon && (
<Helmet>
<link
id="favicon"
rel="icon"
type="image/x-icon"
- href={this.props.site.site.icon}
+ href={this.props.siteRes.site_view.site.icon}
/>
</Helmet>
)}
- <Navbar site={this.props.site} />
+ <Navbar site_res={this.props.siteRes} />
<div class="mt-4 p-0 fl-1">
<Switch>
{routes.map(({ path, exact, component: C, ...rest }) => (
</Switch>
<Symbols />
</div>
- <Footer site={this.props.site} />
+ <Footer site={this.props.siteRes} />
</div>
</Provider>
</>
import { Link } from 'inferno-router';
import { Subscription } from 'rxjs';
import {
- CommentNode as CommentNodeI,
- CommentForm as CommentFormI,
- WebSocketJsonResponse,
+ CreateComment,
+ EditComment,
UserOperation,
CommentResponse,
} from 'lemmy-js-client';
-import { capitalizeFirstLetter, wsJsonToRes, wsSubscribe } from '../utils';
+import { CommentNode as CommentNodeI } from '../interfaces';
+import {
+ capitalizeFirstLetter,
+ wsJsonToRes,
+ wsSubscribe,
+ wsUserOp,
+} from '../utils';
import { WebSocketService, UserService } from '../services';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
}
interface CommentFormState {
- commentForm: CommentFormI;
buttonTitle: string;
finished: boolean;
+ formId: string;
}
export class CommentForm extends Component<CommentFormProps, CommentFormState> {
private subscription: Subscription;
private emptyState: CommentFormState = {
- commentForm: {
- auth: null,
- content: null,
- post_id: this.props.node
- ? this.props.node.comment.post_id
- : this.props.postId,
- creator_id: UserService.Instance.user
- ? UserService.Instance.user.id
- : null,
- },
buttonTitle: !this.props.node
? capitalizeFirstLetter(i18n.t('post'))
: this.props.edit
? capitalizeFirstLetter(i18n.t('save'))
: capitalizeFirstLetter(i18n.t('reply')),
finished: false,
+ formId: null,
};
constructor(props: any, context: any) {
this.state = this.emptyState;
- if (this.props.node) {
- if (this.props.edit) {
- this.state.commentForm.edit_id = this.props.node.comment.id;
- this.state.commentForm.parent_id = this.props.node.comment.parent_id;
- this.state.commentForm.content = this.props.node.comment.content;
- this.state.commentForm.creator_id = this.props.node.comment.creator_id;
- } else {
- // A reply gets a new parent id
- this.state.commentForm.parent_id = this.props.node.comment.id;
- }
- }
-
this.parseMessage = this.parseMessage.bind(this);
this.subscription = wsSubscribe(this.parseMessage);
}
<div class="mb-3">
{UserService.Instance.user ? (
<MarkdownTextArea
- initialContent={this.state.commentForm.content}
+ initialContent={
+ this.props.node
+ ? this.props.node.comment_view.comment.content
+ : null
+ }
buttonTitle={this.state.buttonTitle}
finished={this.state.finished}
replyType={!!this.props.node}
}
handleCommentSubmit(msg: { val: string; formId: string }) {
- this.state.commentForm.content = msg.val;
- this.state.commentForm.form_id = msg.formId;
+ let content = msg.val;
+ this.state.formId = msg.formId;
+
+ let node = this.props.node;
+
if (this.props.edit) {
- WebSocketService.Instance.editComment(this.state.commentForm);
+ let form: EditComment = {
+ content,
+ form_id: this.state.formId,
+ edit_id: node.comment_view.comment.id,
+ auth: UserService.Instance.authField(),
+ };
+ WebSocketService.Instance.client.editComment(form);
} else {
- WebSocketService.Instance.createComment(this.state.commentForm);
+ let form: CreateComment = {
+ content,
+ form_id: this.state.formId,
+ post_id: node ? node.comment_view.post.id : this.props.postId,
+ parent_id: node ? node.comment_view.comment.parent_id : null,
+ auth: UserService.Instance.authField(),
+ };
+ WebSocketService.Instance.client.createComment(form);
}
this.setState(this.state);
}
this.props.onReplyCancel();
}
- parseMessage(msg: WebSocketJsonResponse) {
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
// Only do the showing and hiding if logged in
if (UserService.Instance.user) {
if (
- res.op == UserOperation.CreateComment ||
- res.op == UserOperation.EditComment
+ op == UserOperation.CreateComment ||
+ op == UserOperation.EditComment
) {
- let data = res.data as CommentResponse;
+ let data = wsJsonToRes<CommentResponse>(msg).data;
// This only finishes this form, if the randomly generated form_id matches the one received
- if (this.state.commentForm.form_id == data.form_id) {
+ if (this.state.formId == data.form_id) {
this.setState({ finished: true });
- // Necessary because it broke tribute for some reaso
+ // Necessary because it broke tribute for some reason
this.setState({ finished: false });
}
}
import { Component, linkEvent } from 'inferno';
import { Link } from 'inferno-router';
import {
- CommentNode as CommentNodeI,
- CommentLikeForm,
- DeleteCommentForm,
- RemoveCommentForm,
- MarkCommentAsReadForm,
- MarkUserMentionAsReadForm,
- SaveCommentForm,
- BanFromCommunityForm,
- BanUserForm,
- CommunityUser,
- UserView,
- AddModToCommunityForm,
- AddAdminForm,
- TransferCommunityForm,
- TransferSiteForm,
+ CreateCommentLike,
+ DeleteComment,
+ RemoveComment,
+ MarkCommentAsRead,
+ MarkUserMentionAsRead,
+ SaveComment,
+ BanFromCommunity,
+ BanUser,
+ CommunityModeratorView,
+ UserViewSafe,
+ AddModToCommunity,
+ AddAdmin,
+ TransferCommunity,
+ TransferSite,
SortType,
+ CommentView,
+ UserMentionView,
} from 'lemmy-js-client';
-import { CommentSortType, BanType } from '../interfaces';
+import {
+ CommentSortType,
+ CommentNode as CommentNodeI,
+ BanType,
+} from '../interfaces';
import { WebSocketService, UserService } from '../services';
import {
mdToHtml,
locked?: boolean;
markable?: boolean;
showContext?: boolean;
- moderators: CommunityUser[];
- admins: UserView[];
+ moderators: CommunityModeratorView[];
+ admins: UserViewSafe[];
// TODO is this necessary, can't I get it from the node itself?
postCreatorId?: number;
showCommunity?: boolean;
showConfirmTransferCommunity: false,
showConfirmAppointAsMod: false,
showConfirmAppointAsAdmin: false,
- my_vote: this.props.node.comment.my_vote,
- score: this.props.node.comment.score,
- upvotes: this.props.node.comment.upvotes,
- downvotes: this.props.node.comment.downvotes,
- borderColor: this.props.node.comment.depth
- ? colorList[this.props.node.comment.depth % colorList.length]
+ my_vote: this.props.node.comment_view.my_vote,
+ score: this.props.node.comment_view.counts.score,
+ upvotes: this.props.node.comment_view.counts.upvotes,
+ downvotes: this.props.node.comment_view.counts.downvotes,
+ borderColor: this.props.node.depth
+ ? colorList[this.props.node.depth % colorList.length]
: colorList[0],
readLoading: false,
saveLoading: false,
this.handleCommentDownvote = this.handleCommentDownvote.bind(this);
}
+ // TODO see if there's a better way to do this, and all willReceiveProps
componentWillReceiveProps(nextProps: CommentNodeProps) {
- this.state.my_vote = nextProps.node.comment.my_vote;
- this.state.upvotes = nextProps.node.comment.upvotes;
- this.state.downvotes = nextProps.node.comment.downvotes;
- this.state.score = nextProps.node.comment.score;
+ let cv = nextProps.node.comment_view;
+ this.state.my_vote = cv.my_vote;
+ this.state.upvotes = cv.counts.upvotes;
+ this.state.downvotes = cv.counts.downvotes;
+ this.state.score = cv.counts.score;
this.state.readLoading = false;
this.state.saveLoading = false;
this.setState(this.state);
render() {
let node = this.props.node;
+ let cv = this.props.node.comment_view;
return (
<div
className={`comment ${
- node.comment.parent_id && !this.props.noIndent ? 'ml-1' : ''
+ cv.comment.parent_id && !this.props.noIndent ? 'ml-1' : ''
}`}
>
<div
- id={`comment-${node.comment.id}`}
+ id={`comment-${cv.comment.id}`}
className={`details comment-node py-2 ${
!this.props.noBorder ? 'border-top border-light' : ''
} ${this.isCommentNew ? 'mark' : ''}`}
style={
!this.props.noIndent &&
- this.props.node.comment.parent_id &&
+ cv.comment.parent_id &&
`border-left: 2px ${this.state.borderColor} solid !important`
}
>
<div
- class={`${
- !this.props.noIndent &&
- this.props.node.comment.parent_id &&
- 'ml-2'
- }`}
+ class={`${!this.props.noIndent && cv.comment.parent_id && 'ml-2'}`}
>
<div class="d-flex flex-wrap align-items-center text-muted small">
<span class="mr-2">
- <UserListing
- user={{
- name: node.comment.creator_name,
- preferred_username: node.comment.creator_preferred_username,
- avatar: node.comment.creator_avatar,
- id: node.comment.creator_id,
- local: node.comment.creator_local,
- actor_id: node.comment.creator_actor_id,
- published: node.comment.creator_published,
- }}
- />
+ <UserListing user={cv.creator} />
</span>
{this.isMod && (
{i18n.t('creator')}
</div>
)}
- {(node.comment.banned_from_community || node.comment.banned) && (
+ {(cv.creator_banned_from_community || cv.creator.banned) && (
<div className="badge badge-danger mr-2">
{i18n.t('banned')}
</div>
{this.props.showCommunity && (
<>
<span class="mx-1">{i18n.t('to')}</span>
- <CommunityLink
- community={{
- name: node.comment.community_name,
- id: node.comment.community_id,
- local: node.comment.community_local,
- actor_id: node.comment.community_actor_id,
- icon: node.comment.community_icon,
- }}
- />
+ <CommunityLink community={cv.community} />
<span class="mx-2">•</span>
- <Link className="mr-2" to={`/post/${node.comment.post_id}`}>
- {node.comment.post_name}
+ <Link className="mr-2" to={`/post/${cv.post.id}`}>
+ {cv.post.name}
</Link>
</>
)}
</a>
<span className="mr-1">•</span>
<span>
- <MomentTime data={node.comment} />
+ <MomentTime data={cv.comment} />
</span>
</div>
{/* end of user row */}
class="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleMarkRead)}
data-tippy-content={
- node.comment.read
+ cv.comment.read
? i18n.t('mark_as_unread')
: i18n.t('mark_as_read')
}
) : (
<svg
class={`icon icon-inline ${
- node.comment.read && 'text-success'
+ cv.comment.read && 'text-success'
}`}
>
<use xlinkHref="#icon-check"></use>
<button class="btn btn-link btn-animate">
<Link
className="text-muted"
- to={`/create_private_message/recipient/${node.comment.creator_id}`}
+ to={`/create_private_message/recipient/${cv.creator.id}`}
title={i18n.t('message').toLowerCase()}
>
<svg class="icon">
this.handleSaveCommentClick
)}
data-tippy-content={
- node.comment.saved
- ? i18n.t('unsave')
- : i18n.t('save')
+ cv.saved ? i18n.t('unsave') : i18n.t('save')
}
>
{this.state.saveLoading ? (
) : (
<svg
class={`icon icon-inline ${
- node.comment.saved && 'text-warning'
+ cv.saved && 'text-warning'
}`}
>
<use xlinkHref="#icon-star"></use>
this.handleDeleteClick
)}
data-tippy-content={
- !node.comment.deleted
+ !cv.comment.deleted
? i18n.t('delete')
: i18n.t('restore')
}
>
<svg
class={`icon icon-inline ${
- node.comment.deleted && 'text-danger'
+ cv.comment.deleted && 'text-danger'
}`}
>
<use xlinkHref="#icon-trash"></use>
{/* Admins and mods can remove comments */}
{(this.canMod || this.canAdmin) && (
<>
- {!node.comment.removed ? (
+ {!cv.comment.removed ? (
<button
class="btn btn-link btn-animate text-muted"
onClick={linkEvent(
{this.canMod && (
<>
{!this.isMod &&
- (!node.comment.banned_from_community ? (
+ (!cv.creator_banned_from_community ? (
<button
class="btn btn-link btn-animate text-muted"
onClick={linkEvent(
{i18n.t('unban')}
</button>
))}
- {!node.comment.banned_from_community &&
- node.comment.creator_local &&
+ {!cv.creator_banned_from_community &&
+ cv.creator.local &&
(!this.state.showConfirmAppointAsMod ? (
<button
class="btn btn-link btn-animate text-muted"
{/* Community creators and admins can transfer community to another mod */}
{(this.amCommunityCreator || this.canAdmin) &&
this.isMod &&
- node.comment.creator_local &&
+ cv.creator.local &&
(!this.state.showConfirmTransferCommunity ? (
<button
class="btn btn-link btn-animate text-muted"
{this.canAdmin && (
<>
{!this.isAdmin &&
- (!node.comment.banned ? (
+ (!cv.creator.banned ? (
<button
class="btn btn-link btn-animate text-muted"
onClick={linkEvent(
{i18n.t('unban_from_site')}
</button>
))}
- {!node.comment.banned &&
- node.comment.creator_local &&
+ {!cv.creator.banned &&
+ cv.creator.local &&
(!this.state.showConfirmAppointAsAdmin ? (
<button
class="btn btn-link btn-animate text-muted"
{/* Site Creator can transfer to another admin */}
{this.amSiteCreator &&
this.isAdmin &&
- node.comment.creator_local &&
+ cv.creator.local &&
(!this.state.showConfirmTransferSite ? (
<button
class="btn btn-link btn-animate text-muted"
{/* </div> */}
<div class="form-group row">
<button type="submit" class="btn btn-secondary">
- {i18n.t('ban')} {node.comment.creator_name}
+ {i18n.t('ban')} {cv.creator.name}
</button>
</div>
</form>
}
get linkBtn() {
- let node = this.props.node;
+ let cv = this.props.node.comment_view;
return (
<Link
className="btn btn-link btn-animate text-muted"
- to={`/post/${node.comment.post_id}/comment/${node.comment.id}`}
+ to={`/post/${cv.post.id}/comment/${cv.comment.id}`}
title={this.props.showContext ? i18n.t('show_context') : i18n.t('link')}
>
<svg class="icon icon-inline">
get myComment(): boolean {
return (
UserService.Instance.user &&
- this.props.node.comment.creator_id == UserService.Instance.user.id
+ this.props.node.comment_view.creator.id == UserService.Instance.user.id
);
}
return (
this.props.moderators &&
isMod(
- this.props.moderators.map(m => m.user_id),
- this.props.node.comment.creator_id
+ this.props.moderators.map(m => m.moderator.id),
+ this.props.node.comment_view.creator.id
)
);
}
return (
this.props.admins &&
isMod(
- this.props.admins.map(a => a.id),
- this.props.node.comment.creator_id
+ this.props.admins.map(a => a.user.id),
+ this.props.node.comment_view.creator.id
)
);
}
get isPostCreator(): boolean {
- return this.props.node.comment.creator_id == this.props.postCreatorId;
+ return this.props.node.comment_view.creator.id == this.props.postCreatorId;
}
get canMod(): boolean {
if (this.props.admins && this.props.moderators) {
let adminsThenMods = this.props.admins
- .map(a => a.id)
- .concat(this.props.moderators.map(m => m.user_id));
+ .map(a => a.user.id)
+ .concat(this.props.moderators.map(m => m.moderator.id));
return canMod(
UserService.Instance.user,
adminsThenMods,
- this.props.node.comment.creator_id
+ this.props.node.comment_view.creator.id
);
} else {
return false;
this.props.admins &&
canMod(
UserService.Instance.user,
- this.props.admins.map(a => a.id),
- this.props.node.comment.creator_id
+ this.props.admins.map(a => a.user.id),
+ this.props.node.comment_view.creator.id
)
);
}
return (
this.props.moderators &&
UserService.Instance.user &&
- this.props.node.comment.creator_id != UserService.Instance.user.id &&
- UserService.Instance.user.id == this.props.moderators[0].user_id
+ this.props.node.comment_view.creator.id != UserService.Instance.user.id &&
+ UserService.Instance.user.id == this.props.moderators[0].moderator.id
);
}
return (
this.props.admins &&
UserService.Instance.user &&
- this.props.node.comment.creator_id != UserService.Instance.user.id &&
- UserService.Instance.user.id == this.props.admins[0].id
+ this.props.node.comment_view.creator.id != UserService.Instance.user.id &&
+ UserService.Instance.user.id == this.props.admins[0].user.id
);
}
get commentUnlessRemoved(): string {
- let node = this.props.node;
- return node.comment.removed
+ let comment = this.props.node.comment_view.comment;
+ return comment.removed
? `*${i18n.t('removed')}*`
- : node.comment.deleted
+ : comment.deleted
? `*${i18n.t('deleted')}*`
- : node.comment.content;
+ : comment.content;
}
handleReplyClick(i: CommentNode) {
}
handleDeleteClick(i: CommentNode) {
- let deleteForm: DeleteCommentForm = {
- edit_id: i.props.node.comment.id,
- deleted: !i.props.node.comment.deleted,
- auth: null,
+ let comment = i.props.node.comment_view.comment;
+ let deleteForm: DeleteComment = {
+ edit_id: comment.id,
+ deleted: !comment.deleted,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.deleteComment(deleteForm);
+ WebSocketService.Instance.client.deleteComment(deleteForm);
}
handleSaveCommentClick(i: CommentNode) {
- let saved =
- i.props.node.comment.saved == undefined
- ? true
- : !i.props.node.comment.saved;
- let form: SaveCommentForm = {
- comment_id: i.props.node.comment.id,
- save: saved,
+ let cv = i.props.node.comment_view;
+ let save = cv.saved == undefined ? true : !cv.saved;
+ let form: SaveComment = {
+ comment_id: cv.comment.id,
+ save,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.saveComment(form);
+ WebSocketService.Instance.client.saveComment(form);
i.state.saveLoading = true;
i.setState(this.state);
this.state.my_vote = new_vote;
- let form: CommentLikeForm = {
- comment_id: i.comment.id,
+ let form: CreateCommentLike = {
+ comment_id: i.comment_view.comment.id,
score: this.state.my_vote,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.likeComment(form);
+ WebSocketService.Instance.client.likeComment(form);
this.setState(this.state);
setupTippy();
}
this.state.my_vote = new_vote;
- let form: CommentLikeForm = {
- comment_id: i.comment.id,
+ let form: CreateCommentLike = {
+ comment_id: i.comment_view.comment.id,
score: this.state.my_vote,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.likeComment(form);
+ WebSocketService.Instance.client.likeComment(form);
this.setState(this.state);
setupTippy();
}
}
handleModRemoveSubmit(i: CommentNode) {
- event.preventDefault();
- let form: RemoveCommentForm = {
- edit_id: i.props.node.comment.id,
- removed: !i.props.node.comment.removed,
+ let comment = i.props.node.comment_view.comment;
+ let form: RemoveComment = {
+ edit_id: comment.id,
+ removed: !comment.removed,
reason: i.state.removeReason,
- auth: null,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.removeComment(form);
+ WebSocketService.Instance.client.removeComment(form);
i.state.showRemoveDialog = false;
i.setState(i.state);
}
+ isUserMentionType(
+ item: CommentView | UserMentionView
+ ): item is UserMentionView {
+ return (item as UserMentionView).user_mention.id !== undefined;
+ }
+
handleMarkRead(i: CommentNode) {
- // if it has a user_mention_id field, then its a mention
- if (i.props.node.comment.user_mention_id) {
- let form: MarkUserMentionAsReadForm = {
- user_mention_id: i.props.node.comment.user_mention_id,
- read: !i.props.node.comment.read,
+ if (i.isUserMentionType(i.props.node.comment_view)) {
+ let form: MarkUserMentionAsRead = {
+ user_mention_id: i.props.node.comment_view.user_mention.id,
+ read: !i.props.node.comment_view.user_mention.read,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.markUserMentionAsRead(form);
+ WebSocketService.Instance.client.markUserMentionAsRead(form);
} else {
- let form: MarkCommentAsReadForm = {
- edit_id: i.props.node.comment.id,
- read: !i.props.node.comment.read,
- auth: null,
+ let form: MarkCommentAsRead = {
+ comment_id: i.props.node.comment_view.comment.id,
+ read: !i.props.node.comment_view.comment.read,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.markCommentAsRead(form);
+ WebSocketService.Instance.client.markCommentAsRead(form);
}
i.state.readLoading = true;
}
handleModBanBothSubmit(i: CommentNode) {
- event.preventDefault();
+ let cv = i.props.node.comment_view;
if (i.state.banType == BanType.Community) {
// If its an unban, restore all their data
- let ban = !i.props.node.comment.banned_from_community;
+ let ban = !cv.creator_banned_from_community;
if (ban == false) {
i.state.removeData = false;
}
- let form: BanFromCommunityForm = {
- user_id: i.props.node.comment.creator_id,
- community_id: i.props.node.comment.community_id,
+ let form: BanFromCommunity = {
+ user_id: cv.creator.id,
+ community_id: cv.community.id,
ban,
remove_data: i.state.removeData,
reason: i.state.banReason,
expires: getUnixTime(i.state.banExpires),
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.banFromCommunity(form);
+ WebSocketService.Instance.client.banFromCommunity(form);
} else {
// If its an unban, restore all their data
- let ban = !i.props.node.comment.banned;
+ let ban = !cv.creator.banned;
if (ban == false) {
i.state.removeData = false;
}
- let form: BanUserForm = {
- user_id: i.props.node.comment.creator_id,
+ let form: BanUser = {
+ user_id: cv.creator.id,
ban,
remove_data: i.state.removeData,
reason: i.state.banReason,
expires: getUnixTime(i.state.banExpires),
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.banUser(form);
+ WebSocketService.Instance.client.banUser(form);
}
i.state.showBanDialog = false;
}
handleAddModToCommunity(i: CommentNode) {
- let form: AddModToCommunityForm = {
- user_id: i.props.node.comment.creator_id,
- community_id: i.props.node.comment.community_id,
+ let cv = i.props.node.comment_view;
+ let form: AddModToCommunity = {
+ user_id: cv.creator.id,
+ community_id: cv.community.id,
added: !i.isMod,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.addModToCommunity(form);
+ WebSocketService.Instance.client.addModToCommunity(form);
i.state.showConfirmAppointAsMod = false;
i.setState(i.state);
}
}
handleAddAdmin(i: CommentNode) {
- let form: AddAdminForm = {
- user_id: i.props.node.comment.creator_id,
+ let form: AddAdmin = {
+ user_id: i.props.node.comment_view.creator.id,
added: !i.isAdmin,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.addAdmin(form);
+ WebSocketService.Instance.client.addAdmin(form);
i.state.showConfirmAppointAsAdmin = false;
i.setState(i.state);
}
}
handleTransferCommunity(i: CommentNode) {
- let form: TransferCommunityForm = {
- community_id: i.props.node.comment.community_id,
- user_id: i.props.node.comment.creator_id,
+ let cv = i.props.node.comment_view;
+ let form: TransferCommunity = {
+ community_id: cv.community.id,
+ user_id: cv.creator.id,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.transferCommunity(form);
+ WebSocketService.Instance.client.transferCommunity(form);
i.state.showConfirmTransferCommunity = false;
i.setState(i.state);
}
}
handleTransferSite(i: CommentNode) {
- let form: TransferSiteForm = {
- user_id: i.props.node.comment.creator_id,
+ let form: TransferSite = {
+ user_id: i.props.node.comment_view.creator.id,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.transferSite(form);
+ WebSocketService.Instance.client.transferSite(form);
i.state.showConfirmTransferSite = false;
i.setState(i.state);
}
get isCommentNew(): boolean {
let now = moment.utc().subtract(10, 'minutes');
- let then = moment.utc(this.props.node.comment.published);
+ let then = moment.utc(this.props.node.comment_view.comment.published);
return now.isBefore(then);
}
import { Component } from 'inferno';
-import { CommentSortType } from '../interfaces';
+import { CommentSortType, CommentNode as CommentNodeI } from '../interfaces';
import {
- CommentNode as CommentNodeI,
- CommunityUser,
- UserView,
+ CommunityModeratorView,
+ UserViewSafe,
SortType,
} from 'lemmy-js-client';
import { commentSort, commentSortSortType } from '../utils';
interface CommentNodesProps {
nodes: CommentNodeI[];
- moderators?: CommunityUser[];
- admins?: UserView[];
+ moderators?: CommunityModeratorView[];
+ admins?: UserViewSafe[];
postCreatorId?: number;
noBorder?: boolean;
noIndent?: boolean;
<div className="comments">
{this.sorter().map(node => (
<CommentNode
- key={node.comment.id}
+ key={node.comment_view.comment.id}
node={node}
noBorder={this.props.noBorder}
noIndent={this.props.noIndent}
import { Subscription } from 'rxjs';
import {
UserOperation,
- Community,
+ CommunityView,
ListCommunitiesResponse,
CommunityResponse,
- FollowCommunityForm,
- ListCommunitiesForm,
+ FollowCommunity,
+ ListCommunities,
SortType,
- WebSocketJsonResponse,
- Site,
+ SiteView,
} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+import { UserService, WebSocketService } from '../services';
import {
wsJsonToRes,
toast,
getPageFromProps,
isBrowser,
- setAuth,
setIsoData,
wsSubscribe,
+ wsUserOp,
} from '../utils';
import { CommunityLink } from './community-link';
import { i18n } from '../i18next';
const communityLimit = 100;
interface CommunitiesState {
- communities: Community[];
+ communities: CommunityView[];
page: number;
loading: boolean;
- site: Site;
+ site_view: SiteView;
}
interface CommunitiesProps {
communities: [],
loading: true,
page: getPageFromProps(this.props),
- site: this.isoData.site.site,
+ site_view: this.isoData.site_res.site_view,
};
constructor(props: any, context: any) {
if (this.isoData.path == this.context.router.route.match.url) {
this.state.communities = this.isoData.routeData[0].communities;
this.state.communities.sort(
- (a, b) => b.number_of_subscribers - a.number_of_subscribers
+ (a, b) => b.counts.subscribers - a.counts.subscribers
);
this.state.loading = false;
} else {
}
get documentTitle(): string {
- return `${i18n.t('communities')} - ${this.state.site.name}`;
+ return `${i18n.t('communities')} - ${this.state.site_view.site.name}`;
}
render() {
</tr>
</thead>
<tbody>
- {this.state.communities.map(community => (
+ {this.state.communities.map(cv => (
<tr>
<td>
- <CommunityLink community={community} />
- </td>
- <td>{community.category_name}</td>
- <td class="text-right">
- {community.number_of_subscribers}
+ <CommunityLink community={cv.community} />
</td>
+ <td>{cv.category.name}</td>
+ <td class="text-right">{cv.counts.subscribers}</td>
<td class="text-right d-none d-lg-table-cell">
- {community.number_of_posts}
+ {cv.counts.posts}
</td>
<td class="text-right d-none d-lg-table-cell">
- {community.number_of_comments}
+ {cv.counts.comments}
</td>
<td class="text-right">
- {community.subscribed ? (
+ {cv.subscribed ? (
<span
class="pointer btn-link"
onClick={linkEvent(
- community.id,
+ cv.community.id,
this.handleUnsubscribe
)}
>
<span
class="pointer btn-link"
onClick={linkEvent(
- community.id,
+ cv.community.id,
this.handleSubscribe
)}
>
}
handleUnsubscribe(communityId: number) {
- let form: FollowCommunityForm = {
+ let form: FollowCommunity = {
community_id: communityId,
follow: false,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.followCommunity(form);
+ WebSocketService.Instance.client.followCommunity(form);
}
handleSubscribe(communityId: number) {
- let form: FollowCommunityForm = {
+ let form: FollowCommunity = {
community_id: communityId,
follow: true,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.followCommunity(form);
+ WebSocketService.Instance.client.followCommunity(form);
}
refetch() {
- let listCommunitiesForm: ListCommunitiesForm = {
+ let listCommunitiesForm: ListCommunities = {
sort: SortType.TopAll,
limit: communityLimit,
page: this.state.page,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.listCommunities(listCommunitiesForm);
+ WebSocketService.Instance.client.listCommunities(listCommunitiesForm);
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let pathSplit = req.path.split('/');
let page = pathSplit[3] ? Number(pathSplit[3]) : 1;
- let listCommunitiesForm: ListCommunitiesForm = {
+ let listCommunitiesForm: ListCommunities = {
sort: SortType.TopAll,
limit: communityLimit,
page,
+ auth: req.auth,
};
- setAuth(listCommunitiesForm, req.auth);
return [req.client.listCommunities(listCommunitiesForm)];
}
- parseMessage(msg: WebSocketJsonResponse) {
- console.log(msg);
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
return;
- } else if (res.op == UserOperation.ListCommunities) {
- let data = res.data as ListCommunitiesResponse;
+ } else if (op == UserOperation.ListCommunities) {
+ let data = wsJsonToRes<ListCommunitiesResponse>(msg).data;
this.state.communities = data.communities;
this.state.communities.sort(
- (a, b) => b.number_of_subscribers - a.number_of_subscribers
+ (a, b) => b.counts.subscribers - a.counts.subscribers
);
this.state.loading = false;
window.scrollTo(0, 0);
this.setState(this.state);
- } else if (res.op == UserOperation.FollowCommunity) {
- let data = res.data as CommunityResponse;
- let found = this.state.communities.find(c => c.id == data.community.id);
- found.subscribed = data.community.subscribed;
- found.number_of_subscribers = data.community.number_of_subscribers;
+ } else if (op == UserOperation.FollowCommunity) {
+ let data = wsJsonToRes<CommunityResponse>(msg).data;
+ let found = this.state.communities.find(
+ c => c.community.id == data.community_view.community.id
+ );
+ found.subscribed = data.community_view.subscribed;
+ found.counts.subscribers = data.community_view.counts.subscribers;
this.setState(this.state);
}
}
import { Prompt } from 'inferno-router';
import { Subscription } from 'rxjs';
import {
- CommunityForm as CommunityFormI,
+ EditCommunity,
+ CreateCommunity,
UserOperation,
Category,
CommunityResponse,
- WebSocketJsonResponse,
- Community,
+ CommunityView,
} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+import { UserService, WebSocketService } from '../services';
import {
wsJsonToRes,
capitalizeFirstLetter,
toast,
randomStr,
wsSubscribe,
+ wsUserOp,
} from '../utils';
import { i18n } from '../i18next';
import { ImageUploadForm } from './image-upload-form';
interface CommunityFormProps {
- community?: Community; // If a community is given, that means this is an edit
+ community_view?: CommunityView; // If a community is given, that means this is an edit
categories: Category[];
onCancel?(): any;
- onCreate?(community: Community): any;
- onEdit?(community: Community): any;
+ onCreate?(community: CommunityView): any;
+ onEdit?(community: CommunityView): any;
enableNsfw: boolean;
}
interface CommunityFormState {
- communityForm: CommunityFormI;
+ communityForm: CreateCommunity;
loading: boolean;
}
nsfw: false,
icon: null,
banner: null,
+ auth: UserService.Instance.authField(),
},
loading: false,
};
this.handleBannerUpload = this.handleBannerUpload.bind(this);
this.handleBannerRemove = this.handleBannerRemove.bind(this);
- if (this.props.community) {
+ let cv = this.props.community_view;
+ if (cv) {
this.state.communityForm = {
- name: this.props.community.name,
- title: this.props.community.title,
- category_id: this.props.community.category_id,
- description: this.props.community.description,
- edit_id: this.props.community.id,
- nsfw: this.props.community.nsfw,
- icon: this.props.community.icon,
- banner: this.props.community.banner,
- auth: null,
+ name: cv.community.name,
+ title: cv.community.title,
+ category_id: cv.category.id,
+ description: cv.community.description,
+ nsfw: cv.community.nsfw,
+ icon: cv.community.icon,
+ banner: cv.community.banner,
+ auth: UserService.Instance.authField(),
};
}
this.subscription = wsSubscribe(this.parseMessage);
}
+ // TODO this should be checked out
componentDidUpdate() {
if (
!this.state.loading &&
message={i18n.t('block_leaving')}
/>
<form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}>
- {!this.props.community && (
+ {!this.props.community_view && (
<div class="form-group row">
<label class="col-12 col-form-label" htmlFor="community-name">
{i18n.t('name')}
<svg class="icon icon-spinner spin">
<use xlinkHref="#icon-spinner"></use>
</svg>
- ) : this.props.community ? (
+ ) : this.props.community_view ? (
capitalizeFirstLetter(i18n.t('save'))
) : (
capitalizeFirstLetter(i18n.t('create'))
)}
</button>
- {this.props.community && (
+ {this.props.community_view && (
<button
type="button"
class="btn btn-secondary"
handleCreateCommunitySubmit(i: CommunityForm, event: any) {
event.preventDefault();
i.state.loading = true;
- if (i.props.community) {
- WebSocketService.Instance.editCommunity(i.state.communityForm);
+ if (i.props.community_view) {
+ let form: EditCommunity = {
+ ...i.state.communityForm,
+ edit_id: i.props.community_view.community.id,
+ };
+ WebSocketService.Instance.client.editCommunity(form);
} else {
- WebSocketService.Instance.createCommunity(i.state.communityForm);
+ WebSocketService.Instance.client.createCommunity(i.state.communityForm);
}
i.setState(i.state);
}
this.setState(this.state);
}
- parseMessage(msg: WebSocketJsonResponse) {
- let res = wsJsonToRes(msg);
- console.log(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
this.state.loading = false;
this.setState(this.state);
return;
- } else if (res.op == UserOperation.CreateCommunity) {
- let data = res.data as CommunityResponse;
+ } else if (op == UserOperation.CreateCommunity) {
+ let data = wsJsonToRes<CommunityResponse>(msg).data;
this.state.loading = false;
- this.props.onCreate(data.community);
- } else if (res.op == UserOperation.EditCommunity) {
- let data = res.data as CommunityResponse;
+ this.props.onCreate(data.community_view);
+ } else if (op == UserOperation.EditCommunity) {
+ let data = wsJsonToRes<CommunityResponse>(msg).data;
this.state.loading = false;
- this.props.onEdit(data.community);
+ this.props.onEdit(data.community_view);
}
}
}
import { Component } from 'inferno';
import { Link } from 'inferno-router';
-import { Community } from 'lemmy-js-client';
+import { CommunitySafe } from 'lemmy-js-client';
import { hostname, showAvatars } from '../utils';
import { PictrsImage } from './pictrs-image';
-interface CommunityOther {
- name: string;
- id?: number; // Necessary if its federated
- icon?: string;
- local?: boolean;
- actor_id?: string;
-}
-
interface CommunityLinkProps {
- community: Community | CommunityOther;
+ // TODO figure this out better
+ community: CommunitySafe;
realLink?: boolean;
useApubName?: boolean;
muted?: boolean;
GetCommunityResponse,
CommunityResponse,
SortType,
- Post,
- GetPostsForm,
- GetCommunityForm,
+ PostView,
+ GetPosts,
+ GetCommunity,
ListingType,
GetPostsResponse,
PostResponse,
AddModToCommunityResponse,
BanFromCommunityResponse,
- Comment,
- GetCommentsForm,
+ CommentView,
+ GetComments,
GetCommentsResponse,
CommentResponse,
- WebSocketJsonResponse,
GetSiteResponse,
Category,
ListCategoriesResponse,
setIsoData,
wsSubscribe,
isBrowser,
- setAuth,
communityRSSUrl,
+ wsUserOp,
} from '../utils';
import { i18n } from '../i18next';
communityLoading: boolean;
postsLoading: boolean;
commentsLoading: boolean;
- posts: Post[];
- comments: Comment[];
+ posts: PostView[];
+ comments: CommentView[];
dataType: DataType;
sort: SortType;
page: number;
dataType: getDataTypeFromProps(this.props),
sort: getSortTypeFromProps(this.props),
page: getPageFromProps(this.props),
- siteRes: this.isoData.site,
+ siteRes: this.isoData.site_res,
categories: [],
};
} else {
this.fetchCommunity();
this.fetchData();
- WebSocketService.Instance.listCategories();
+ WebSocketService.Instance.client.listCategories();
}
setupTippy();
}
fetchCommunity() {
- let form: GetCommunityForm = {
+ let form: GetCommunity = {
id: this.state.communityId ? this.state.communityId : null,
name: this.state.communityName ? this.state.communityName : null,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.getCommunity(form);
+ WebSocketService.Instance.client.getCommunity(form);
}
componentWillUnmount() {
id = Number(idOrName);
}
- let communityForm: GetCommunityForm = id ? { id } : { name: name_ };
- setAuth(communityForm, req.auth);
+ let communityForm: GetCommunity = id ? { id } : { name: name_ };
+ communityForm.auth = req.auth;
promises.push(req.client.getCommunity(communityForm));
let dataType: DataType = pathSplit[4]
let page = pathSplit[8] ? Number(pathSplit[8]) : 1;
if (dataType == DataType.Post) {
- let getPostsForm: GetPostsForm = {
+ let getPostsForm: GetPosts = {
page,
limit: fetchLimit,
sort,
type_: ListingType.Community,
+ auth: req.auth,
};
this.setIdOrName(getPostsForm, id, name_);
- setAuth(getPostsForm, req.auth);
promises.push(req.client.getPosts(getPostsForm));
} else {
- let getCommentsForm: GetCommentsForm = {
+ let getCommentsForm: GetComments = {
page,
limit: fetchLimit,
sort,
type_: ListingType.Community,
+ auth: req.auth,
};
this.setIdOrName(getCommentsForm, id, name_);
- setAuth(getCommentsForm, req.auth);
promises.push(req.client.getComments(getCommentsForm));
}
}
get documentTitle(): string {
- return `${this.state.communityRes.community.title} - ${this.state.siteRes.site.name}`;
+ return `${this.state.communityRes.community_view.community.title} - ${this.state.siteRes.site_view.site.name}`;
}
render() {
+ let cv = this.state.communityRes.community_view;
return (
<div class="container">
{this.state.communityLoading ? (
<HtmlTags
title={this.documentTitle}
path={this.context.router.route.match.url}
- description={this.state.communityRes.community.description}
- image={this.state.communityRes.community.icon}
+ description={cv.community.description}
+ image={cv.community.icon}
/>
{this.communityInfo()}
{this.selects()}
</div>
<div class="col-12 col-md-4">
<Sidebar
- community={this.state.communityRes.community}
+ community_view={cv}
moderators={this.state.communityRes.moderators}
admins={this.state.siteRes.admins}
online={this.state.communityRes.online}
- enableNsfw={this.state.siteRes.site.enable_nsfw}
+ enableNsfw={this.state.siteRes.site_view.site.enable_nsfw}
categories={this.state.categories}
/>
</div>
}
listings() {
+ let site = this.state.siteRes.site_view.site;
return this.state.dataType == DataType.Post ? (
this.state.postsLoading ? (
<h5>
posts={this.state.posts}
removeDuplicates
sort={this.state.sort}
- enableDownvotes={this.state.siteRes.site.enable_downvotes}
- enableNsfw={this.state.siteRes.site.enable_nsfw}
+ enableDownvotes={site.enable_downvotes}
+ enableNsfw={site.enable_nsfw}
/>
)
) : this.state.commentsLoading ? (
noIndent
sortType={this.state.sort}
showContext
- enableDownvotes={this.state.siteRes.site.enable_downvotes}
+ enableDownvotes={site.enable_downvotes}
/>
);
}
communityInfo() {
+ let community = this.state.communityRes.community_view.community;
return (
<div>
- <BannerIconHeader
- banner={this.state.communityRes.community.banner}
- icon={this.state.communityRes.community.icon}
- />
- <h5 class="mb-0">{this.state.communityRes.community.title}</h5>
+ <BannerIconHeader banner={community.banner} icon={community.icon} />
+ <h5 class="mb-0">{community.title}</h5>
<CommunityLink
- community={this.state.communityRes.community}
+ community={community}
realLink
useApubName
muted
</span>
<a
href={communityRSSUrl(
- this.state.communityRes.community.actor_id,
+ this.state.communityRes.community_view.community.actor_id,
this.state.sort
)}
target="_blank"
const sortStr = paramUpdates.sort || this.state.sort;
const page = paramUpdates.page || this.state.page;
this.props.history.push(
- `/c/${this.state.communityRes.community.name}/data_type/${dataTypeStr}/sort/${sortStr}/page/${page}`
+ `/c/${this.state.communityRes.community_view.community.name}/data_type/${dataTypeStr}/sort/${sortStr}/page/${page}`
);
}
fetchData() {
if (this.state.dataType == DataType.Post) {
- let getPostsForm: GetPostsForm = {
+ let form: GetPosts = {
page: this.state.page,
limit: fetchLimit,
sort: this.state.sort,
type_: ListingType.Community,
community_id: this.state.communityId,
community_name: this.state.communityName,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.getPosts(getPostsForm);
+ WebSocketService.Instance.client.getPosts(form);
} else {
- let getCommentsForm: GetCommentsForm = {
+ let form: GetComments = {
page: this.state.page,
limit: fetchLimit,
sort: this.state.sort,
type_: ListingType.Community,
community_id: this.state.communityId,
community_name: this.state.communityName,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.getComments(getCommentsForm);
+ WebSocketService.Instance.client.getComments(form);
}
}
- parseMessage(msg: WebSocketJsonResponse) {
- console.log(msg);
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
this.context.router.history.push('/');
return;
} else if (msg.reconnect) {
- WebSocketService.Instance.communityJoin({
- community_id: this.state.communityRes.community.id,
+ WebSocketService.Instance.client.communityJoin({
+ community_id: this.state.communityRes.community_view.community.id,
});
this.fetchData();
- } else if (res.op == UserOperation.GetCommunity) {
- let data = res.data as GetCommunityResponse;
+ } else if (op == UserOperation.GetCommunity) {
+ let data = wsJsonToRes<GetCommunityResponse>(msg).data;
this.state.communityRes = data;
this.state.communityLoading = false;
this.setState(this.state);
- WebSocketService.Instance.communityJoin({
- community_id: data.community.id,
+ // TODO why is there no auth in this form?
+ WebSocketService.Instance.client.communityJoin({
+ community_id: data.community_view.community.id,
});
} else if (
- res.op == UserOperation.EditCommunity ||
- res.op == UserOperation.DeleteCommunity ||
- res.op == UserOperation.RemoveCommunity
+ op == UserOperation.EditCommunity ||
+ op == UserOperation.DeleteCommunity ||
+ op == UserOperation.RemoveCommunity
) {
- let data = res.data as CommunityResponse;
- this.state.communityRes.community = data.community;
+ let data = wsJsonToRes<CommunityResponse>(msg).data;
+ this.state.communityRes.community_view = data.community_view;
this.setState(this.state);
- } else if (res.op == UserOperation.FollowCommunity) {
- let data = res.data as CommunityResponse;
- this.state.communityRes.community.subscribed = data.community.subscribed;
- this.state.communityRes.community.number_of_subscribers =
- data.community.number_of_subscribers;
+ } else if (op == UserOperation.FollowCommunity) {
+ let data = wsJsonToRes<CommunityResponse>(msg).data;
+ this.state.communityRes.community_view.subscribed =
+ data.community_view.subscribed;
+ this.state.communityRes.community_view.counts.subscribers =
+ data.community_view.counts.subscribers;
this.setState(this.state);
- } else if (res.op == UserOperation.GetPosts) {
- let data = res.data as GetPostsResponse;
+ } else if (op == UserOperation.GetPosts) {
+ let data = wsJsonToRes<GetPostsResponse>(msg).data;
this.state.posts = data.posts;
this.state.postsLoading = false;
this.setState(this.state);
setupTippy();
} 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
+ op == UserOperation.EditPost ||
+ op == UserOperation.DeletePost ||
+ op == UserOperation.RemovePost ||
+ op == UserOperation.LockPost ||
+ op == UserOperation.StickyPost ||
+ op == UserOperation.SavePost
) {
- let data = res.data as PostResponse;
- editPostFindRes(data, this.state.posts);
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ editPostFindRes(data.post_view, this.state.posts);
this.setState(this.state);
- } else if (res.op == UserOperation.CreatePost) {
- let data = res.data as PostResponse;
- this.state.posts.unshift(data.post);
- notifyPost(data.post, this.context.router);
+ } else if (op == UserOperation.CreatePost) {
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ this.state.posts.unshift(data.post_view);
+ notifyPost(data.post_view, this.context.router);
this.setState(this.state);
- } else if (res.op == UserOperation.CreatePostLike) {
- let data = res.data as PostResponse;
- createPostLikeFindRes(data, this.state.posts);
+ } else if (op == UserOperation.CreatePostLike) {
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ createPostLikeFindRes(data.post_view, this.state.posts);
this.setState(this.state);
- } else if (res.op == UserOperation.AddModToCommunity) {
- let data = res.data as AddModToCommunityResponse;
+ } else if (op == UserOperation.AddModToCommunity) {
+ let data = wsJsonToRes<AddModToCommunityResponse>(msg).data;
this.state.communityRes.moderators = data.moderators;
this.setState(this.state);
- } else if (res.op == UserOperation.BanFromCommunity) {
- let data = res.data as BanFromCommunityResponse;
+ } else if (op == UserOperation.BanFromCommunity) {
+ let data = wsJsonToRes<BanFromCommunityResponse>(msg).data;
+ // TODO this might be incorrect
this.state.posts
- .filter(p => p.creator_id == data.user.id)
- .forEach(p => (p.banned = data.banned));
+ .filter(p => p.creator.id == data.user_view.user.id)
+ .forEach(p => (p.creator_banned_from_community = data.banned));
this.setState(this.state);
- } else if (res.op == UserOperation.GetComments) {
- let data = res.data as GetCommentsResponse;
+ } else if (op == UserOperation.GetComments) {
+ let data = wsJsonToRes<GetCommentsResponse>(msg).data;
this.state.comments = data.comments;
this.state.commentsLoading = false;
this.setState(this.state);
} else if (
- res.op == UserOperation.EditComment ||
- res.op == UserOperation.DeleteComment ||
- res.op == UserOperation.RemoveComment
+ op == UserOperation.EditComment ||
+ op == UserOperation.DeleteComment ||
+ op == UserOperation.RemoveComment
) {
- let data = res.data as CommentResponse;
- editCommentRes(data, this.state.comments);
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ editCommentRes(data.comment_view, this.state.comments);
this.setState(this.state);
- } else if (res.op == UserOperation.CreateComment) {
- let data = res.data as CommentResponse;
+ } else if (op == UserOperation.CreateComment) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
// Necessary since it might be a user reply
if (data.recipient_ids.length == 0) {
- this.state.comments.unshift(data.comment);
+ this.state.comments.unshift(data.comment_view);
this.setState(this.state);
}
- } else if (res.op == UserOperation.SaveComment) {
- let data = res.data as CommentResponse;
- saveCommentRes(data, this.state.comments);
+ } else if (op == UserOperation.SaveComment) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ saveCommentRes(data.comment_view, this.state.comments);
this.setState(this.state);
- } else if (res.op == UserOperation.CreateCommentLike) {
- let data = res.data as CommentResponse;
- createCommentLikeRes(data, this.state.comments);
+ } else if (op == UserOperation.CreateCommentLike) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ createCommentLikeRes(data.comment_view, this.state.comments);
this.setState(this.state);
- } else if (res.op == UserOperation.ListCategories) {
- let data = res.data as ListCategoriesResponse;
+ } else if (op == UserOperation.ListCategories) {
+ let data = wsJsonToRes<ListCategoriesResponse>(msg).data;
this.state.categories = data.categories;
this.setState(this.state);
}
import { CommunityForm } from './community-form';
import { HtmlTags } from './html-tags';
import {
- Community,
+ CommunityView,
UserOperation,
- WebSocketJsonResponse,
- Site,
+ SiteView,
ListCategoriesResponse,
Category,
} from 'lemmy-js-client';
wsJsonToRes,
wsSubscribe,
isBrowser,
+ wsUserOp,
} from '../utils';
import { WebSocketService, UserService } from '../services';
import { i18n } from '../i18next';
import { InitialFetchRequest } from 'shared/interfaces';
interface CreateCommunityState {
- site: Site;
+ site_view: SiteView;
categories: Category[];
loading: boolean;
}
private isoData = setIsoData(this.context);
private subscription: Subscription;
private emptyState: CreateCommunityState = {
- site: this.isoData.site.site,
+ site_view: this.isoData.site_res.site_view,
categories: [],
loading: true,
};
this.state.categories = this.isoData.routeData[0].categories;
this.state.loading = false;
} else {
- WebSocketService.Instance.listCategories();
+ WebSocketService.Instance.client.listCategories();
}
}
}
get documentTitle(): string {
- return `${i18n.t('create_community')} - ${this.state.site.name}`;
+ return `${i18n.t('create_community')} - ${this.state.site_view.site.name}`;
}
render() {
<CommunityForm
categories={this.state.categories}
onCreate={this.handleCommunityCreate}
- enableNsfw={this.state.site.enable_nsfw}
+ enableNsfw={this.state.site_view.site.enable_nsfw}
/>
</div>
</div>
);
}
- handleCommunityCreate(community: Community) {
- this.props.history.push(`/c/${community.name}`);
+ handleCommunityCreate(cv: CommunityView) {
+ this.props.history.push(`/c/${cv.community.name}`);
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
return [req.client.listCategories()];
}
- parseMessage(msg: WebSocketJsonResponse) {
- console.log(msg);
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
// Toast errors are already handled by community-form
return;
- } else if (res.op == UserOperation.ListCategories) {
- let data = res.data as ListCategoriesResponse;
+ } else if (op == UserOperation.ListCategories) {
+ let data = wsJsonToRes<ListCategoriesResponse>(msg).data;
this.state.categories = data.categories;
this.state.loading = false;
this.setState(this.state);
import { HtmlTags } from './html-tags';
import {
isBrowser,
- setAuth,
setIsoData,
toast,
wsJsonToRes,
wsSubscribe,
+ wsUserOp,
} from '../utils';
import { UserService, WebSocketService } from '../services';
import {
UserOperation,
- PostFormParams,
- WebSocketJsonResponse,
ListCommunitiesResponse,
- Community,
- Site,
- ListCommunitiesForm,
+ CommunityView,
+ SiteView,
+ ListCommunities,
SortType,
+ PostView,
} from 'lemmy-js-client';
import { i18n } from '../i18next';
-import { InitialFetchRequest } from 'shared/interfaces';
+import { InitialFetchRequest, PostFormParams } from 'shared/interfaces';
interface CreatePostState {
- site: Site;
- communities: Community[];
+ site_view: SiteView;
+ communities: CommunityView[];
loading: boolean;
}
private isoData = setIsoData(this.context);
private subscription: Subscription;
private emptyState: CreatePostState = {
- site: this.isoData.site.site,
+ site_view: this.isoData.site_res.site_view,
communities: [],
loading: true,
};
}
refetch() {
- let listCommunitiesForm: ListCommunitiesForm = {
+ let listCommunitiesForm: ListCommunities = {
sort: SortType.TopAll,
limit: 9999,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.listCommunities(listCommunitiesForm);
+ WebSocketService.Instance.client.listCommunities(listCommunitiesForm);
}
componentWillUnmount() {
}
get documentTitle(): string {
- return `${i18n.t('create_post')} - ${this.state.site.name}`;
+ return `${i18n.t('create_post')} - ${this.state.site_view.site.name}`;
}
render() {
communities={this.state.communities}
onCreate={this.handlePostCreate}
params={this.params}
- enableDownvotes={this.state.site.enable_downvotes}
- enableNsfw={this.state.site.enable_nsfw}
+ enableDownvotes={this.state.site_view.site.enable_downvotes}
+ enableNsfw={this.state.site_view.site.enable_nsfw}
/>
</div>
</div>
return null;
}
- handlePostCreate(id: number) {
- this.props.history.push(`/post/${id}`);
+ handlePostCreate(post_view: PostView) {
+ this.props.history.push(`/post/${post_view.post.id}`);
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let listCommunitiesForm: ListCommunitiesForm = {
+ let listCommunitiesForm: ListCommunities = {
sort: SortType.TopAll,
limit: 9999,
+ auth: req.auth,
};
- setAuth(listCommunitiesForm, req.auth);
return [req.client.listCommunities(listCommunitiesForm)];
}
- parseMessage(msg: WebSocketJsonResponse) {
- console.log(msg);
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
return;
- } else if (res.op == UserOperation.ListCommunities) {
- let data = res.data as ListCommunitiesResponse;
+ } else if (op == UserOperation.ListCommunities) {
+ let data = wsJsonToRes<ListCommunitiesResponse>(msg).data;
this.state.communities = data.communities;
this.state.loading = false;
this.setState(this.state);
import { HtmlTags } from './html-tags';
import { UserService, WebSocketService } from '../services';
import {
- Site,
- WebSocketJsonResponse,
+ SiteView,
UserOperation,
- UserDetailsResponse,
- UserView,
+ GetUserDetailsResponse,
+ UserViewSafe,
SortType,
- GetUserDetailsForm,
+ GetUserDetails,
} from 'lemmy-js-client';
import {
getRecipientIdFromProps,
isBrowser,
- setAuth,
setIsoData,
toast,
wsJsonToRes,
wsSubscribe,
+ wsUserOp,
} from '../utils';
import { i18n } from '../i18next';
import { InitialFetchRequest } from 'shared/interfaces';
interface CreatePrivateMessageProps {}
interface CreatePrivateMessageState {
- site: Site;
- recipient: UserView;
+ site_view: SiteView;
+ recipient: UserViewSafe;
recipient_id: number;
loading: boolean;
}
private isoData = setIsoData(this.context);
private subscription: Subscription;
private emptyState: CreatePrivateMessageState = {
- site: this.isoData.site.site,
+ site_view: this.isoData.site_res.site_view,
recipient: undefined,
recipient_id: getRecipientIdFromProps(this.props),
loading: true,
}
fetchUserDetails() {
- let form: GetUserDetailsForm = {
+ let form: GetUserDetails = {
user_id: this.state.recipient_id,
sort: SortType.New,
saved_only: false,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.getUserDetails(form);
+ WebSocketService.Instance.client.getUserDetails(form);
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let user_id = Number(req.path.split('/').pop());
- let form: GetUserDetailsForm = {
+ let form: GetUserDetails = {
user_id,
sort: SortType.New,
saved_only: false,
+ auth: req.auth,
};
- setAuth(form, req.auth);
return [req.client.getUserDetails(form)];
}
get documentTitle(): string {
- return `${i18n.t('create_private_message')} - ${this.state.site.name}`;
+ return `${i18n.t('create_private_message')} - ${
+ this.state.site_view.site.name
+ }`;
}
componentWillUnmount() {
<h5>{i18n.t('create_private_message')}</h5>
<PrivateMessageForm
onCreate={this.handlePrivateMessageCreate}
- recipient={this.state.recipient}
+ recipient={this.state.recipient.user}
/>
</div>
</div>
this.context.router.history.push(`/`);
}
- parseMessage(msg: WebSocketJsonResponse) {
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
this.state.loading = false;
this.setState(this.state);
return;
- } else if (res.op == UserOperation.GetUserDetails) {
- let data = res.data as UserDetailsResponse;
- this.state.recipient = data.user;
+ } else if (op == UserOperation.GetUserDetails) {
+ let data = wsJsonToRes<GetUserDetailsResponse>(msg).data;
+ this.state.recipient = data.user_view;
this.state.loading = false;
this.setState(this.state);
}
import { Subscription } from 'rxjs';
import {
UserOperation,
- Comment,
+ CommentView,
SortType,
- GetRepliesForm,
+ GetReplies,
GetRepliesResponse,
- GetUserMentionsForm,
+ GetUserMentions,
GetUserMentionsResponse,
UserMentionResponse,
CommentResponse,
- WebSocketJsonResponse,
- PrivateMessage as PrivateMessageI,
- GetPrivateMessagesForm,
+ PrivateMessageView,
+ GetPrivateMessages,
PrivateMessagesResponse,
PrivateMessageResponse,
- Site,
+ SiteView,
+ UserMentionView,
} from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services';
import {
wsJsonToRes,
fetchLimit,
- isCommentType,
toast,
editCommentRes,
saveCommentRes,
setupTippy,
setIsoData,
wsSubscribe,
- setAuth,
isBrowser,
+ wsUserOp,
} from '../utils';
import { CommentNodes } from './comment-nodes';
import { PrivateMessage } from './private-message';
Messages,
}
-type ReplyType = Comment | PrivateMessageI;
+enum ReplyEnum {
+ Reply,
+ Mention,
+ Message,
+}
+type ReplyType = {
+ id: number;
+ type_: ReplyEnum;
+ view: CommentView | PrivateMessageView | UserMentionView;
+ published: string;
+};
interface InboxState {
unreadOrAll: UnreadOrAll;
messageType: MessageType;
- replies: Comment[];
- mentions: Comment[];
- messages: PrivateMessageI[];
+ replies: CommentView[];
+ mentions: UserMentionView[];
+ messages: PrivateMessageView[];
sort: SortType;
page: number;
- site: Site;
+ site_view: SiteView;
loading: boolean;
}
messages: [],
sort: SortType.New,
page: 1,
- site: this.isoData.site.site,
+ site_view: this.isoData.site_res.site_view,
loading: true,
};
get documentTitle(): string {
return `@${UserService.Instance.user.name} ${i18n.t('inbox')} - ${
- this.state.site.name
+ this.state.site_view.site.name
}`;
}
}
combined(): ReplyType[] {
- return [
- ...this.state.replies,
- ...this.state.mentions,
- ...this.state.messages,
- ].sort((a, b) => b.published.localeCompare(a.published));
+ let id = 0;
+ let replies: ReplyType[] = this.state.replies.map(r => ({
+ id: id++,
+ type_: ReplyEnum.Reply,
+ view: r,
+ published: r.comment.published,
+ }));
+ let mentions: ReplyType[] = this.state.mentions.map(r => ({
+ id: id++,
+ type_: ReplyEnum.Mention,
+ view: r,
+ published: r.comment.published,
+ }));
+ let messages: ReplyType[] = this.state.messages.map(r => ({
+ id: id++,
+ type_: ReplyEnum.Message,
+ view: r,
+ published: r.private_message.published,
+ }));
+
+ return [...replies, ...mentions, ...messages].sort((a, b) =>
+ b.published.localeCompare(a.published)
+ );
+ }
+
+ renderReplyType(i: ReplyType) {
+ switch (i.type_) {
+ case ReplyEnum.Reply:
+ return (
+ <CommentNodes
+ key={i.id}
+ nodes={[{ comment_view: i.view as CommentView }]}
+ noIndent
+ markable
+ showCommunity
+ showContext
+ enableDownvotes={this.state.site_view.site.enable_downvotes}
+ />
+ );
+ case ReplyEnum.Mention:
+ return (
+ <CommentNodes
+ key={i.id}
+ nodes={[{ comment_view: i.view as UserMentionView }]}
+ noIndent
+ markable
+ showCommunity
+ showContext
+ enableDownvotes={this.state.site_view.site.enable_downvotes}
+ />
+ );
+ case ReplyEnum.Message:
+ return (
+ <PrivateMessage
+ key={i.id}
+ private_message_view={i.view as PrivateMessageView}
+ />
+ );
+ default:
+ return <div />;
+ }
}
all() {
- return (
- <div>
- {this.combined().map(i =>
- isCommentType(i) ? (
- <CommentNodes
- key={i.id}
- nodes={[{ comment: i }]}
- noIndent
- markable
- showCommunity
- showContext
- enableDownvotes={this.state.site.enable_downvotes}
- />
- ) : (
- <PrivateMessage key={i.id} privateMessage={i} />
- )
- )}
- </div>
- );
+ return <div>{this.combined().map(i => this.renderReplyType(i))}</div>;
}
replies() {
markable
showCommunity
showContext
- enableDownvotes={this.state.site.enable_downvotes}
+ enableDownvotes={this.state.site_view.site.enable_downvotes}
/>
</div>
);
mentions() {
return (
<div>
- {this.state.mentions.map(mention => (
+ {this.state.mentions.map(umv => (
<CommentNodes
- key={mention.id}
- nodes={[{ comment: mention }]}
+ key={umv.user_mention.id}
+ nodes={[{ comment_view: umv }]}
noIndent
markable
showCommunity
showContext
- enableDownvotes={this.state.site.enable_downvotes}
+ enableDownvotes={this.state.site_view.site.enable_downvotes}
/>
))}
</div>
messages() {
return (
<div>
- {this.state.messages.map(message => (
- <PrivateMessage key={message.id} privateMessage={message} />
+ {this.state.messages.map(pmv => (
+ <PrivateMessage
+ key={pmv.private_message.id}
+ private_message_view={pmv}
+ />
))}
</div>
);
let promises: Promise<any>[] = [];
// It can be /u/me, or /username/1
- let repliesForm: GetRepliesForm = {
+ let repliesForm: GetReplies = {
sort: SortType.New,
unread_only: true,
page: 1,
limit: fetchLimit,
+ auth: req.auth,
};
- setAuth(repliesForm, req.auth);
promises.push(req.client.getReplies(repliesForm));
- let userMentionsForm: GetUserMentionsForm = {
+ let userMentionsForm: GetUserMentions = {
sort: SortType.New,
unread_only: true,
page: 1,
limit: fetchLimit,
+ auth: req.auth,
};
- setAuth(userMentionsForm, req.auth);
promises.push(req.client.getUserMentions(userMentionsForm));
- let privateMessagesForm: GetPrivateMessagesForm = {
+ let privateMessagesForm: GetPrivateMessages = {
unread_only: true,
page: 1,
limit: fetchLimit,
+ auth: req.auth,
};
- setAuth(privateMessagesForm, req.auth);
promises.push(req.client.getPrivateMessages(privateMessagesForm));
return promises;
}
refetch() {
- let repliesForm: GetRepliesForm = {
+ let repliesForm: GetReplies = {
sort: this.state.sort,
unread_only: this.state.unreadOrAll == UnreadOrAll.Unread,
page: this.state.page,
limit: fetchLimit,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.getReplies(repliesForm);
+ WebSocketService.Instance.client.getReplies(repliesForm);
- let userMentionsForm: GetUserMentionsForm = {
+ let userMentionsForm: GetUserMentions = {
sort: this.state.sort,
unread_only: this.state.unreadOrAll == UnreadOrAll.Unread,
page: this.state.page,
limit: fetchLimit,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.getUserMentions(userMentionsForm);
+ WebSocketService.Instance.client.getUserMentions(userMentionsForm);
- let privateMessagesForm: GetPrivateMessagesForm = {
+ let privateMessagesForm: GetPrivateMessages = {
unread_only: this.state.unreadOrAll == UnreadOrAll.Unread,
page: this.state.page,
limit: fetchLimit,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.getPrivateMessages(privateMessagesForm);
+ WebSocketService.Instance.client.getPrivateMessages(privateMessagesForm);
}
handleSortChange(val: SortType) {
}
markAllAsRead(i: Inbox) {
- WebSocketService.Instance.markAllAsRead();
+ WebSocketService.Instance.client.markAllAsRead({
+ auth: UserService.Instance.authField(),
+ });
i.state.replies = [];
i.state.mentions = [];
i.state.messages = [];
i.setState(i.state);
}
- parseMessage(msg: WebSocketJsonResponse) {
- console.log(msg);
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
return;
} else if (msg.reconnect) {
this.refetch();
- } else if (res.op == UserOperation.GetReplies) {
- let data = res.data as GetRepliesResponse;
+ } else if (op == UserOperation.GetReplies) {
+ let data = wsJsonToRes<GetRepliesResponse>(msg).data;
this.state.replies = data.replies;
this.state.loading = false;
this.sendUnreadCount();
window.scrollTo(0, 0);
this.setState(this.state);
setupTippy();
- } else if (res.op == UserOperation.GetUserMentions) {
- let data = res.data as GetUserMentionsResponse;
+ } else if (op == UserOperation.GetUserMentions) {
+ let data = wsJsonToRes<GetUserMentionsResponse>(msg).data;
this.state.mentions = data.mentions;
this.sendUnreadCount();
window.scrollTo(0, 0);
this.setState(this.state);
setupTippy();
- } else if (res.op == UserOperation.GetPrivateMessages) {
- let data = res.data as PrivateMessagesResponse;
- this.state.messages = data.messages;
+ } else if (op == UserOperation.GetPrivateMessages) {
+ let data = wsJsonToRes<PrivateMessagesResponse>(msg).data;
+ this.state.messages = data.private_messages;
this.sendUnreadCount();
window.scrollTo(0, 0);
this.setState(this.state);
setupTippy();
- } else if (res.op == UserOperation.EditPrivateMessage) {
- let data = res.data as PrivateMessageResponse;
- let found: PrivateMessageI = this.state.messages.find(
- m => m.id === data.message.id
+ } else if (op == UserOperation.EditPrivateMessage) {
+ let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
+ let found: PrivateMessageView = this.state.messages.find(
+ m =>
+ m.private_message.id === data.private_message_view.private_message.id
);
if (found) {
- found.content = data.message.content;
- found.updated = data.message.updated;
+ found.private_message.content =
+ data.private_message_view.private_message.content;
+ found.private_message.updated =
+ data.private_message_view.private_message.updated;
}
this.setState(this.state);
- } else if (res.op == UserOperation.DeletePrivateMessage) {
- let data = res.data as PrivateMessageResponse;
- let found: PrivateMessageI = this.state.messages.find(
- m => m.id === data.message.id
+ } else if (op == UserOperation.DeletePrivateMessage) {
+ let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
+ let found: PrivateMessageView = this.state.messages.find(
+ m =>
+ m.private_message.id === data.private_message_view.private_message.id
);
if (found) {
- found.deleted = data.message.deleted;
- found.updated = data.message.updated;
+ found.private_message.deleted =
+ data.private_message_view.private_message.deleted;
+ found.private_message.updated =
+ data.private_message_view.private_message.updated;
}
this.setState(this.state);
- } else if (res.op == UserOperation.MarkPrivateMessageAsRead) {
- let data = res.data as PrivateMessageResponse;
- let found: PrivateMessageI = this.state.messages.find(
- m => m.id === data.message.id
+ } else if (op == UserOperation.MarkPrivateMessageAsRead) {
+ let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
+ let found: PrivateMessageView = this.state.messages.find(
+ m =>
+ m.private_message.id === data.private_message_view.private_message.id
);
if (found) {
- found.updated = data.message.updated;
+ found.private_message.updated =
+ data.private_message_view.private_message.updated;
// If youre in the unread view, just remove it from the list
- if (this.state.unreadOrAll == UnreadOrAll.Unread && data.message.read) {
+ if (
+ this.state.unreadOrAll == UnreadOrAll.Unread &&
+ data.private_message_view.private_message.read
+ ) {
this.state.messages = this.state.messages.filter(
- r => r.id !== data.message.id
+ r =>
+ r.private_message.id !==
+ data.private_message_view.private_message.id
);
} else {
- let found = this.state.messages.find(c => c.id == data.message.id);
- found.read = data.message.read;
+ let found = this.state.messages.find(
+ c =>
+ c.private_message.id ==
+ data.private_message_view.private_message.id
+ );
+ found.private_message.read =
+ data.private_message_view.private_message.read;
}
}
this.sendUnreadCount();
this.setState(this.state);
- } else if (res.op == UserOperation.MarkAllAsRead) {
+ } else if (op == UserOperation.MarkAllAsRead) {
// Moved to be instant
} else if (
- res.op == UserOperation.EditComment ||
- res.op == UserOperation.DeleteComment ||
- res.op == UserOperation.RemoveComment
+ op == UserOperation.EditComment ||
+ op == UserOperation.DeleteComment ||
+ op == UserOperation.RemoveComment
) {
- let data = res.data as CommentResponse;
- editCommentRes(data, this.state.replies);
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ editCommentRes(data.comment_view, this.state.replies);
this.setState(this.state);
- } else if (res.op == UserOperation.MarkCommentAsRead) {
- let data = res.data as CommentResponse;
+ } else if (op == UserOperation.MarkCommentAsRead) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
// If youre in the unread view, just remove it from the list
- if (this.state.unreadOrAll == UnreadOrAll.Unread && data.comment.read) {
+ if (
+ this.state.unreadOrAll == UnreadOrAll.Unread &&
+ data.comment_view.comment.read
+ ) {
this.state.replies = this.state.replies.filter(
- r => r.id !== data.comment.id
+ r => r.comment.id !== data.comment_view.comment.id
);
} else {
- let found = this.state.replies.find(c => c.id == data.comment.id);
- found.read = data.comment.read;
+ let found = this.state.replies.find(
+ c => c.comment.id == data.comment_view.comment.id
+ );
+ found.comment.read = data.comment_view.comment.read;
}
this.sendUnreadCount();
this.setState(this.state);
setupTippy();
- } else if (res.op == UserOperation.MarkUserMentionAsRead) {
- let data = res.data as UserMentionResponse;
-
- let found = this.state.mentions.find(c => c.id == data.mention.id);
- found.content = data.mention.content;
- found.updated = data.mention.updated;
- found.removed = data.mention.removed;
- found.deleted = data.mention.deleted;
- found.upvotes = data.mention.upvotes;
- found.downvotes = data.mention.downvotes;
- found.score = data.mention.score;
+ } else if (op == UserOperation.MarkUserMentionAsRead) {
+ let data = wsJsonToRes<UserMentionResponse>(msg).data;
+
+ // TODO this might not be correct, it might need to use the comment id
+ let found = this.state.mentions.find(
+ c => c.user_mention.id == data.user_mention_view.user_mention.id
+ );
+ found.comment.content = data.user_mention_view.comment.content;
+ found.comment.updated = data.user_mention_view.comment.updated;
+ found.comment.removed = data.user_mention_view.comment.removed;
+ found.comment.deleted = data.user_mention_view.comment.deleted;
+ found.counts.upvotes = data.user_mention_view.counts.upvotes;
+ found.counts.downvotes = data.user_mention_view.counts.downvotes;
+ found.counts.score = data.user_mention_view.counts.score;
// If youre in the unread view, just remove it from the list
- if (this.state.unreadOrAll == UnreadOrAll.Unread && data.mention.read) {
+ if (
+ this.state.unreadOrAll == UnreadOrAll.Unread &&
+ data.user_mention_view.user_mention.read
+ ) {
this.state.mentions = this.state.mentions.filter(
- r => r.id !== data.mention.id
+ r => r.user_mention.id !== data.user_mention_view.user_mention.id
);
} else {
- let found = this.state.mentions.find(c => c.id == data.mention.id);
- found.read = data.mention.read;
+ let found = this.state.mentions.find(
+ c => c.user_mention.id == data.user_mention_view.user_mention.id
+ );
+ // TODO test to make sure these mentions are getting marked as read
+ found.user_mention.read = data.user_mention_view.user_mention.read;
}
this.sendUnreadCount();
this.setState(this.state);
- } else if (res.op == UserOperation.CreateComment) {
- let data = res.data as CommentResponse;
+ } else if (op == UserOperation.CreateComment) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
if (data.recipient_ids.includes(UserService.Instance.user.id)) {
- this.state.replies.unshift(data.comment);
+ this.state.replies.unshift(data.comment_view);
this.setState(this.state);
- } else if (data.comment.creator_id == UserService.Instance.user.id) {
+ } else if (data.comment_view.creator.id == UserService.Instance.user.id) {
+ // TODO this seems wrong, you should be using form_id
toast(i18n.t('reply_sent'));
}
- } else if (res.op == UserOperation.CreatePrivateMessage) {
- let data = res.data as PrivateMessageResponse;
- if (data.message.recipient_id == UserService.Instance.user.id) {
- this.state.messages.unshift(data.message);
+ } else if (op == UserOperation.CreatePrivateMessage) {
+ let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
+ if (
+ data.private_message_view.recipient.id == UserService.Instance.user.id
+ ) {
+ this.state.messages.unshift(data.private_message_view);
this.setState(this.state);
}
- } else if (res.op == UserOperation.SaveComment) {
- let data = res.data as CommentResponse;
- saveCommentRes(data, this.state.replies);
+ } else if (op == UserOperation.SaveComment) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ saveCommentRes(data.comment_view, this.state.replies);
this.setState(this.state);
setupTippy();
- } else if (res.op == UserOperation.CreateCommentLike) {
- let data = res.data as CommentResponse;
- createCommentLikeRes(data, this.state.replies);
+ } else if (op == UserOperation.CreateCommentLike) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ createCommentLikeRes(data.comment_view, this.state.replies);
this.setState(this.state);
}
}
unreadCount(): number {
return (
- this.state.replies.filter(r => !r.read).length +
- this.state.mentions.filter(r => !r.read).length +
+ this.state.replies.filter(r => !r.comment.read).length +
+ this.state.mentions.filter(r => !r.user_mention.read).length +
this.state.messages.filter(
r =>
UserService.Instance.user &&
- !r.read &&
- r.creator_id !== UserService.Instance.user.id
+ !r.private_message.read &&
+ // TODO also seems very strang and wrong
+ r.creator.id !== UserService.Instance.user.id
).length
);
}
export class Instances extends Component<any, InstancesState> {
private isoData = setIsoData(this.context);
private emptyState: InstancesState = {
- siteRes: this.isoData.site,
+ siteRes: this.isoData.site_res,
};
constructor(props: any, context: any) {
}
get documentTitle(): string {
- return `${i18n.t('instances')} - ${this.state.siteRes.site.name}`;
+ return `${i18n.t('instances')} - ${this.state.siteRes.site_view.site.name}`;
}
render() {
import { Component, linkEvent } from 'inferno';
import { Subscription } from 'rxjs';
import {
- LoginForm,
- RegisterForm,
+ Login as LoginForm,
+ Register,
LoginResponse,
UserOperation,
- PasswordResetForm,
+ PasswordReset,
GetSiteResponse,
GetCaptchaResponse,
- WebSocketJsonResponse,
- Site,
+ SiteView,
} from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services';
import {
wsSubscribe,
isBrowser,
setIsoData,
+ wsUserOp,
} from '../utils';
import { i18n } from '../i18next';
import { HtmlTags } from './html-tags';
interface State {
loginForm: LoginForm;
- registerForm: RegisterForm;
+ registerForm: Register;
loginLoading: boolean;
registerLoading: boolean;
captcha: GetCaptchaResponse;
captchaPlaying: boolean;
- site: Site;
+ site_view: SiteView;
}
export class Login extends Component<any, State> {
registerLoading: false,
captcha: undefined,
captchaPlaying: false,
- site: this.isoData.site.site,
+ site_view: this.isoData.site_res.site_view,
};
constructor(props: any, context: any) {
this.subscription = wsSubscribe(this.parseMessage);
if (isBrowser()) {
- WebSocketService.Instance.getCaptcha();
+ WebSocketService.Instance.client.getCaptcha();
}
}
}
get documentTitle(): string {
- return `${i18n.t('login')} - ${this.state.site.name}`;
+ return `${i18n.t('login')} - ${this.state.site_view.site.name}`;
}
render() {
</div>
</div>
)}
- {this.state.site.enable_nsfw && (
+ {this.state.site_view.site.enable_nsfw && (
<div class="form-group row">
<div class="col-sm-10">
<div class="form-check">
event.preventDefault();
i.state.loginLoading = true;
i.setState(i.state);
- WebSocketService.Instance.login(i.state.loginForm);
+ WebSocketService.Instance.client.login(i.state.loginForm);
}
handleLoginUsernameChange(i: Login, event: any) {
event.preventDefault();
i.state.registerLoading = true;
i.setState(i.state);
- WebSocketService.Instance.register(i.state.registerForm);
+ WebSocketService.Instance.client.register(i.state.registerForm);
}
handleRegisterUsernameChange(i: Login, event: any) {
handleRegenCaptcha(_i: Login, event: any) {
event.preventDefault();
- WebSocketService.Instance.getCaptcha();
+ WebSocketService.Instance.client.getCaptcha();
}
handlePasswordReset(i: Login, event: any) {
event.preventDefault();
- let resetForm: PasswordResetForm = {
+ let resetForm: PasswordReset = {
email: i.state.loginForm.username_or_email,
};
- WebSocketService.Instance.passwordReset(resetForm);
+ WebSocketService.Instance.client.passwordReset(resetForm);
}
handleCaptchaPlay(i: Login, event: any) {
return `data:image/png;base64,${this.state.captcha.ok.png}`;
}
- parseMessage(msg: WebSocketJsonResponse) {
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
this.state = this.emptyState;
this.state.registerForm.captcha_answer = undefined;
// Refetch another captcha
- WebSocketService.Instance.getCaptcha();
+ WebSocketService.Instance.client.getCaptcha();
this.setState(this.state);
return;
} else {
- if (res.op == UserOperation.Login) {
- let data = res.data as LoginResponse;
+ if (op == UserOperation.Login) {
+ let data = wsJsonToRes<LoginResponse>(msg).data;
this.state = this.emptyState;
this.setState(this.state);
UserService.Instance.login(data);
- WebSocketService.Instance.userJoin();
+ WebSocketService.Instance.client.userJoin({
+ auth: UserService.Instance.authField(),
+ });
toast(i18n.t('logged_in'));
this.props.history.push('/');
- } else if (res.op == UserOperation.Register) {
- let data = res.data as LoginResponse;
+ } else if (op == UserOperation.Register) {
+ let data = wsJsonToRes<LoginResponse>(msg).data;
this.state = this.emptyState;
this.setState(this.state);
UserService.Instance.login(data);
- WebSocketService.Instance.userJoin();
+ WebSocketService.Instance.client.userJoin({
+ auth: UserService.Instance.authField(),
+ });
this.props.history.push('/communities');
- } else if (res.op == UserOperation.GetCaptcha) {
- let data = res.data as GetCaptchaResponse;
+ } else if (op == UserOperation.GetCaptcha) {
+ let data = wsJsonToRes<GetCaptchaResponse>(msg).data;
if (data.ok) {
this.state.captcha = data;
this.state.registerForm.captcha_uuid = data.ok.uuid;
this.setState(this.state);
}
- } else if (res.op == UserOperation.PasswordReset) {
+ } else if (op == UserOperation.PasswordReset) {
toast(i18n.t('reset_password_mail_sent'));
- } else if (res.op == UserOperation.GetSite) {
- let data = res.data as GetSiteResponse;
- this.state.site = data.site;
+ } else if (op == UserOperation.GetSite) {
+ let data = wsJsonToRes<GetSiteResponse>(msg).data;
+ this.state.site_view = data.site_view;
this.setState(this.state);
}
}
import { Subscription } from 'rxjs';
import {
UserOperation,
- CommunityUser,
+ CommunityFollowerView,
GetFollowedCommunitiesResponse,
- ListCommunitiesForm,
+ ListCommunities,
ListCommunitiesResponse,
- Community,
+ CommunityView,
SortType,
GetSiteResponse,
ListingType,
SiteResponse,
GetPostsResponse,
PostResponse,
- Post,
- GetPostsForm,
- Comment,
- GetCommentsForm,
+ PostView,
+ GetPosts,
+ CommentView,
+ GetComments,
GetCommentsResponse,
CommentResponse,
AddAdminResponse,
BanUserResponse,
- WebSocketJsonResponse,
} from 'lemmy-js-client';
import { DataType, InitialFetchRequest } from '../interfaces';
import { WebSocketService, UserService } from '../services';
setIsoData,
wsSubscribe,
isBrowser,
- setAuth,
+ wsUserOp,
} from '../utils';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
import { HtmlTags } from './html-tags';
interface MainState {
- subscribedCommunities: CommunityUser[];
- trendingCommunities: Community[];
+ subscribedCommunities: CommunityFollowerView[];
+ trendingCommunities: CommunityView[];
siteRes: GetSiteResponse;
showEditSite: boolean;
loading: boolean;
- posts: Post[];
- comments: Comment[];
+ posts: PostView[];
+ comments: CommentView[];
listingType: ListingType;
dataType: DataType;
sort: SortType;
private emptyState: MainState = {
subscribedCommunities: [],
trendingCommunities: [],
- siteRes: this.isoData.site,
+ siteRes: this.isoData.site_res,
showEditSite: false,
loading: true,
posts: [],
this.fetchTrendingCommunities();
this.fetchData();
if (UserService.Instance.user) {
- WebSocketService.Instance.getFollowedCommunities();
+ WebSocketService.Instance.client.getFollowedCommunities({
+ auth: UserService.Instance.authField(),
+ });
}
}
}
fetchTrendingCommunities() {
- let listCommunitiesForm: ListCommunitiesForm = {
+ let listCommunitiesForm: ListCommunities = {
sort: SortType.Hot,
limit: 6,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.listCommunities(listCommunitiesForm);
+ WebSocketService.Instance.client.listCommunities(listCommunitiesForm);
}
componentDidMount() {
// This means it hasn't been set up yet
- if (!this.state.siteRes.site) {
+ if (!this.state.siteRes.site_view) {
this.context.router.history.push('/setup');
}
- WebSocketService.Instance.communityJoin({ community_id: 0 });
+ WebSocketService.Instance.client.communityJoin({ community_id: 0 });
}
componentWillUnmount() {
let promises: Promise<any>[] = [];
if (dataType == DataType.Post) {
- let getPostsForm: GetPostsForm = {
+ let getPostsForm: GetPosts = {
page,
limit: fetchLimit,
sort,
type_,
+ auth: req.auth,
};
- setAuth(getPostsForm, req.auth);
promises.push(req.client.getPosts(getPostsForm));
} else {
- let getCommentsForm: GetCommentsForm = {
+ let getCommentsForm: GetComments = {
page,
limit: fetchLimit,
sort,
type_,
+ auth: req.auth,
};
- setAuth(getCommentsForm, req.auth);
promises.push(req.client.getComments(getCommentsForm));
}
- let trendingCommunitiesForm: ListCommunitiesForm = {
+ let trendingCommunitiesForm: ListCommunities = {
sort: SortType.Hot,
limit: 6,
};
get documentTitle(): string {
return `${
- this.state.siteRes.site ? this.state.siteRes.site.name : 'Lemmy'
+ this.state.siteRes.site_view
+ ? this.state.siteRes.site_view.site.name
+ : 'Lemmy'
}`;
}
title={this.documentTitle}
path={this.context.router.route.match.url}
/>
- {this.state.siteRes.site && (
+ {this.state.siteRes.site_view.site && (
<div class="row">
<main role="main" class="col-12 col-md-8">
{this.posts()}
</T>
</h5>
<ul class="list-inline">
- {this.state.trendingCommunities.map(community => (
+ {this.state.trendingCommunities.map(cv => (
<li class="list-inline-item d-inline">
- <CommunityLink community={community} />
+ <CommunityLink community={cv.community} />
</li>
))}
</ul>
</T>
</h5>
<ul class="list-inline mb-0">
- {this.state.subscribedCommunities.map(community => (
+ {this.state.subscribedCommunities.map(cfv => (
<li class="list-inline-item d-inline">
- <CommunityLink
- community={{
- name: community.community_name,
- id: community.community_id,
- local: community.community_local,
- actor_id: community.community_actor_id,
- icon: community.community_icon,
- }}
- />
+ <CommunityLink community={cfv.community} />
</li>
))}
</ul>
}
sidebar() {
+ let site = this.state.siteRes.site_view.site;
return (
<div>
{!this.state.showEditSite ? (
{this.siteName()}
{this.adminButtons()}
</div>
- <BannerIconHeader banner={this.state.siteRes.site.banner} />
+ <BannerIconHeader banner={site.banner} />
{this.siteInfo()}
</div>
) : (
- <SiteForm
- site={this.state.siteRes.site}
- onCancel={this.handleEditCancel}
- />
+ <SiteForm site={site} onCancel={this.handleEditCancel} />
)}
</div>
);
siteInfo() {
return (
<div>
- {this.state.siteRes.site.description && this.siteDescription()}
+ {this.state.siteRes.site_view.site.description &&
+ this.siteDescription()}
{this.badges()}
{this.admins()}
</div>
return (
<ul class="mt-1 list-inline small mb-0">
<li class="list-inline-item">{i18n.t('admins')}:</li>
- {this.state.siteRes.admins.map(admin => (
+ {this.state.siteRes.admins.map(av => (
<li class="list-inline-item">
- <UserListing
- user={{
- name: admin.name,
- preferred_username: admin.preferred_username,
- avatar: admin.avatar,
- local: admin.local,
- actor_id: admin.actor_id,
- id: admin.id,
- }}
- />
+ <UserListing user={av.user} />
</li>
))}
</ul>
}
badges() {
+ let site_view = this.state.siteRes.site_view;
return (
<ul class="my-2 list-inline">
<li className="list-inline-item badge badge-secondary">
</li>
<li className="list-inline-item badge badge-secondary">
{i18n.t('number_of_users', {
- count: this.state.siteRes.site.number_of_users,
+ count: site_view.counts.users,
})}
</li>
<li className="list-inline-item badge badge-secondary">
{i18n.t('number_of_communities', {
- count: this.state.siteRes.site.number_of_communities,
+ count: site_view.counts.communities,
})}
</li>
<li className="list-inline-item badge badge-secondary">
{i18n.t('number_of_posts', {
- count: this.state.siteRes.site.number_of_posts,
+ count: site_view.counts.posts,
})}
</li>
<li className="list-inline-item badge badge-secondary">
{i18n.t('number_of_comments', {
- count: this.state.siteRes.site.number_of_comments,
+ count: site_view.counts.comments,
})}
</li>
<li className="list-inline-item">
return (
<div
className="md-div"
- dangerouslySetInnerHTML={mdToHtml(this.state.siteRes.site.description)}
+ dangerouslySetInnerHTML={mdToHtml(
+ this.state.siteRes.site_view.site.description
+ )}
/>
);
}
}
listings() {
+ let site = this.state.siteRes.site_view.site;
return this.state.dataType == DataType.Post ? (
<PostListings
posts={this.state.posts}
showCommunity
removeDuplicates
sort={this.state.sort}
- enableDownvotes={this.state.siteRes.site.enable_downvotes}
- enableNsfw={this.state.siteRes.site.enable_nsfw}
+ enableDownvotes={site.enable_downvotes}
+ enableNsfw={site.enable_nsfw}
/>
) : (
<CommentNodes
showCommunity
sortType={this.state.sort}
showContext
- enableDownvotes={this.state.siteRes.site.enable_downvotes}
+ enableDownvotes={site.enable_downvotes}
/>
);
}
get showLocal(): boolean {
return (
- this.isoData.site.federated_instances !== null &&
- this.isoData.site.federated_instances.length > 0
+ this.isoData.site_res.federated_instances !== null &&
+ this.isoData.site_res.federated_instances.length > 0
);
}
return (
UserService.Instance.user &&
this.state.siteRes.admins
- .map(a => a.id)
+ .map(a => a.user.id)
.includes(UserService.Instance.user.id)
);
}
fetchData() {
if (this.state.dataType == DataType.Post) {
- let getPostsForm: GetPostsForm = {
+ let getPostsForm: GetPosts = {
page: this.state.page,
limit: fetchLimit,
sort: this.state.sort,
type_: this.state.listingType,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.getPosts(getPostsForm);
+ WebSocketService.Instance.client.getPosts(getPostsForm);
} else {
- let getCommentsForm: GetCommentsForm = {
+ let getCommentsForm: GetComments = {
page: this.state.page,
limit: fetchLimit,
sort: this.state.sort,
type_: this.state.listingType,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.getComments(getCommentsForm);
+ WebSocketService.Instance.client.getComments(getCommentsForm);
}
}
- parseMessage(msg: WebSocketJsonResponse) {
- console.log(msg);
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
return;
} else if (msg.reconnect) {
- WebSocketService.Instance.communityJoin({ community_id: 0 });
+ WebSocketService.Instance.client.communityJoin({ community_id: 0 });
this.fetchData();
- } else if (res.op == UserOperation.GetFollowedCommunities) {
- let data = res.data as GetFollowedCommunitiesResponse;
+ } else if (op == UserOperation.GetFollowedCommunities) {
+ let data = wsJsonToRes<GetFollowedCommunitiesResponse>(msg).data;
this.state.subscribedCommunities = data.communities;
this.setState(this.state);
- } else if (res.op == UserOperation.ListCommunities) {
- let data = res.data as ListCommunitiesResponse;
+ } else if (op == UserOperation.ListCommunities) {
+ let data = wsJsonToRes<ListCommunitiesResponse>(msg).data;
this.state.trendingCommunities = data.communities;
this.setState(this.state);
- } else if (res.op == UserOperation.EditSite) {
- let data = res.data as SiteResponse;
- this.state.siteRes.site = data.site;
+ } else if (op == UserOperation.EditSite) {
+ let data = wsJsonToRes<SiteResponse>(msg).data;
+ this.state.siteRes.site_view = data.site_view;
this.state.showEditSite = false;
this.setState(this.state);
toast(i18n.t('site_saved'));
- } else if (res.op == UserOperation.GetPosts) {
- let data = res.data as GetPostsResponse;
+ } else if (op == UserOperation.GetPosts) {
+ let data = wsJsonToRes<GetPostsResponse>(msg).data;
this.state.posts = data.posts;
this.state.loading = false;
this.setState(this.state);
setupTippy();
- } else if (res.op == UserOperation.CreatePost) {
- let data = res.data as PostResponse;
+ } else if (op == UserOperation.CreatePost) {
+ let data = wsJsonToRes<PostResponse>(msg).data;
// If you're on subscribed, only push it if you're subscribed.
if (this.state.listingType == ListingType.Subscribed) {
if (
this.state.subscribedCommunities
- .map(c => c.community_id)
- .includes(data.post.community_id)
+ .map(c => c.community.id)
+ .includes(data.post_view.community.id)
) {
- this.state.posts.unshift(data.post);
- notifyPost(data.post, this.context.router);
+ this.state.posts.unshift(data.post_view);
+ notifyPost(data.post_view, this.context.router);
}
} else {
// NSFW posts
- let nsfw = data.post.nsfw || data.post.community_nsfw;
+ let nsfw = data.post_view.post.nsfw || data.post_view.community.nsfw;
// Don't push the post if its nsfw, and don't have that setting on
if (
UserService.Instance.user &&
UserService.Instance.user.show_nsfw)
) {
- this.state.posts.unshift(data.post);
- notifyPost(data.post, this.context.router);
+ this.state.posts.unshift(data.post_view);
+ notifyPost(data.post_view, this.context.router);
}
}
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
+ op == UserOperation.EditPost ||
+ op == UserOperation.DeletePost ||
+ op == UserOperation.RemovePost ||
+ op == UserOperation.LockPost ||
+ op == UserOperation.StickyPost ||
+ op == UserOperation.SavePost
) {
- let data = res.data as PostResponse;
- editPostFindRes(data, this.state.posts);
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ editPostFindRes(data.post_view, this.state.posts);
this.setState(this.state);
- } else if (res.op == UserOperation.CreatePostLike) {
- let data = res.data as PostResponse;
- createPostLikeFindRes(data, this.state.posts);
+ } else if (op == UserOperation.CreatePostLike) {
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ createPostLikeFindRes(data.post_view, this.state.posts);
this.setState(this.state);
- } else if (res.op == UserOperation.AddAdmin) {
- let data = res.data as AddAdminResponse;
+ } else if (op == UserOperation.AddAdmin) {
+ let data = wsJsonToRes<AddAdminResponse>(msg).data;
this.state.siteRes.admins = data.admins;
this.setState(this.state);
- } else if (res.op == UserOperation.BanUser) {
- let data = res.data as BanUserResponse;
- let found = this.state.siteRes.banned.find(u => (u.id = data.user.id));
+ } else if (op == UserOperation.BanUser) {
+ let data = wsJsonToRes<BanUserResponse>(msg).data;
+ let found = this.state.siteRes.banned.find(
+ u => (u.user.id = data.user_view.user.id)
+ );
// Remove the banned if its found in the list, and the action is an unban
if (found && !data.banned) {
this.state.siteRes.banned = this.state.siteRes.banned.filter(
- i => i.id !== data.user.id
+ i => i.user.id !== data.user_view.user.id
);
} else {
- this.state.siteRes.banned.push(data.user);
+ this.state.siteRes.banned.push(data.user_view);
}
this.state.posts
- .filter(p => p.creator_id == data.user.id)
- .forEach(p => (p.banned = data.banned));
+ .filter(p => p.creator.id == data.user_view.user.id)
+ .forEach(p => (p.creator.banned = data.banned));
this.setState(this.state);
- } else if (res.op == UserOperation.GetComments) {
- let data = res.data as GetCommentsResponse;
+ } else if (op == UserOperation.GetComments) {
+ let data = wsJsonToRes<GetCommentsResponse>(msg).data;
this.state.comments = data.comments;
this.state.loading = false;
this.setState(this.state);
} else if (
- res.op == UserOperation.EditComment ||
- res.op == UserOperation.DeleteComment ||
- res.op == UserOperation.RemoveComment
+ op == UserOperation.EditComment ||
+ op == UserOperation.DeleteComment ||
+ op == UserOperation.RemoveComment
) {
- let data = res.data as CommentResponse;
- editCommentRes(data, this.state.comments);
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ editCommentRes(data.comment_view, this.state.comments);
this.setState(this.state);
- } else if (res.op == UserOperation.CreateComment) {
- let data = res.data as CommentResponse;
+ } else if (op == UserOperation.CreateComment) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
// Necessary since it might be a user reply
if (data.recipient_ids.length == 0) {
if (this.state.listingType == ListingType.Subscribed) {
if (
this.state.subscribedCommunities
- .map(c => c.community_id)
- .includes(data.comment.community_id)
+ .map(c => c.community.id)
+ .includes(data.comment_view.community.id)
) {
- this.state.comments.unshift(data.comment);
+ this.state.comments.unshift(data.comment_view);
}
} else {
- this.state.comments.unshift(data.comment);
+ this.state.comments.unshift(data.comment_view);
}
this.setState(this.state);
}
- } else if (res.op == UserOperation.SaveComment) {
- let data = res.data as CommentResponse;
- saveCommentRes(data, this.state.comments);
+ } else if (op == UserOperation.SaveComment) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ saveCommentRes(data.comment_view, this.state.comments);
this.setState(this.state);
- } else if (res.op == UserOperation.CreateCommentLike) {
- let data = res.data as CommentResponse;
- createCommentLikeRes(data, this.state.comments);
+ } else if (op == UserOperation.CreateCommentLike) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ createCommentLikeRes(data.comment_view, this.state.comments);
this.setState(this.state);
}
}
import { Subscription } from 'rxjs';
import {
UserOperation,
- GetModlogForm,
+ GetModlog,
GetModlogResponse,
- ModRemovePost,
- ModLockPost,
- ModStickyPost,
- ModRemoveComment,
- ModRemoveCommunity,
- ModBanFromCommunity,
- ModBan,
- ModAddCommunity,
- ModAdd,
- WebSocketJsonResponse,
- Site,
+ SiteView,
+ ModRemovePostView,
+ ModLockPostView,
+ ModStickyPostView,
+ ModRemoveCommentView,
+ ModRemoveCommunityView,
+ ModBanFromCommunityView,
+ ModBanView,
+ ModAddCommunityView,
+ ModAddView,
} from 'lemmy-js-client';
import { WebSocketService } from '../services';
import {
wsJsonToRes,
- addTypeInfo,
fetchLimit,
toast,
setIsoData,
wsSubscribe,
isBrowser,
+ wsUserOp,
} from '../utils';
import { MomentTime } from './moment-time';
import { HtmlTags } from './html-tags';
import moment from 'moment';
import { i18n } from '../i18next';
import { InitialFetchRequest } from 'shared/interfaces';
+import { UserListing } from './user-listing';
+import { CommunityLink } from './community-link';
+
+enum ModlogEnum {
+ ModRemovePost,
+ ModLockPost,
+ ModStickyPost,
+ ModRemoveComment,
+ ModRemoveCommunity,
+ ModBanFromCommunity,
+ ModAddCommunity,
+ ModAdd,
+ ModBan,
+}
+
+type ModlogType = {
+ id: number;
+ type_: ModlogEnum;
+ view:
+ | ModRemovePostView
+ | ModLockPostView
+ | ModStickyPostView
+ | ModRemoveCommentView
+ | ModRemoveCommunityView
+ | ModBanFromCommunityView
+ | ModBanView
+ | ModAddCommunityView
+ | ModAddView;
+ when_: string;
+};
interface ModlogState {
- combined: {
- type_: string;
- data:
- | ModRemovePost
- | ModLockPost
- | ModStickyPost
- | ModRemoveCommunity
- | ModAdd
- | ModBan;
- }[];
+ res: GetModlogResponse;
communityId?: number;
communityName?: string;
page: number;
- site: Site;
+ site_view: SiteView;
loading: boolean;
}
private isoData = setIsoData(this.context);
private subscription: Subscription;
private emptyState: ModlogState = {
- combined: [],
+ res: {
+ removed_posts: [],
+ locked_posts: [],
+ stickied_posts: [],
+ removed_comments: [],
+ removed_communities: [],
+ banned_from_community: [],
+ banned: [],
+ added_to_community: [],
+ added: [],
+ },
page: 1,
loading: true,
- site: this.isoData.site.site,
+ site_view: this.isoData.site_res.site_view,
};
constructor(props: any, context: any) {
// Only fetch the data if coming from another route
if (this.isoData.path == this.context.router.route.match.url) {
let data = this.isoData.routeData[0];
- this.setCombined(data);
+ this.state.res = data;
this.state.loading = false;
} else {
this.refetch();
}
}
- setCombined(res: GetModlogResponse) {
- let removed_posts = addTypeInfo(res.removed_posts, 'removed_posts');
- let locked_posts = addTypeInfo(res.locked_posts, 'locked_posts');
- let stickied_posts = addTypeInfo(res.stickied_posts, 'stickied_posts');
- let removed_comments = addTypeInfo(
- res.removed_comments,
- 'removed_comments'
- );
- let removed_communities = addTypeInfo(
- res.removed_communities,
- 'removed_communities'
- );
- let banned_from_community = addTypeInfo(
- res.banned_from_community,
- 'banned_from_community'
- );
- let added_to_community = addTypeInfo(
- res.added_to_community,
- 'added_to_community'
+ buildCombined(res: GetModlogResponse): ModlogType[] {
+ let removed_posts: ModlogType[] = res.removed_posts.map(r => ({
+ id: r.mod_remove_post.id,
+ type_: ModlogEnum.ModRemovePost,
+ view: r,
+ when_: r.mod_remove_post.when_,
+ }));
+
+ let locked_posts: ModlogType[] = res.locked_posts.map(r => ({
+ id: r.mod_lock_post.id,
+ type_: ModlogEnum.ModLockPost,
+ view: r,
+ when_: r.mod_lock_post.when_,
+ }));
+
+ let stickied_posts: ModlogType[] = res.stickied_posts.map(r => ({
+ id: r.mod_sticky_post.id,
+ type_: ModlogEnum.ModStickyPost,
+ view: r,
+ when_: r.mod_sticky_post.when_,
+ }));
+
+ let removed_comments: ModlogType[] = res.removed_comments.map(r => ({
+ id: r.mod_remove_comment.id,
+ type_: ModlogEnum.ModRemoveComment,
+ view: r,
+ when_: r.mod_remove_comment.when_,
+ }));
+
+ let removed_communities: ModlogType[] = res.removed_communities.map(r => ({
+ id: r.mod_remove_community.id,
+ type_: ModlogEnum.ModRemoveCommunity,
+ view: r,
+ when_: r.mod_remove_community.when_,
+ }));
+
+ let banned_from_community: ModlogType[] = res.banned_from_community.map(
+ r => ({
+ id: r.mod_ban_from_community.id,
+ type_: ModlogEnum.ModBanFromCommunity,
+ view: r,
+ when_: r.mod_ban_from_community.when_,
+ })
);
- let added = addTypeInfo(res.added, 'added');
- let banned = addTypeInfo(res.banned, 'banned');
- this.state.combined = [];
-
- this.state.combined.push(...removed_posts);
- this.state.combined.push(...locked_posts);
- this.state.combined.push(...stickied_posts);
- this.state.combined.push(...removed_comments);
- this.state.combined.push(...removed_communities);
- this.state.combined.push(...banned_from_community);
- this.state.combined.push(...added_to_community);
- this.state.combined.push(...added);
- this.state.combined.push(...banned);
-
- if (this.state.communityId && this.state.combined.length > 0) {
- this.state.communityName = (this.state.combined[0]
- .data as ModRemovePost).community_name;
+
+ let added_to_community: ModlogType[] = res.added_to_community.map(r => ({
+ id: r.mod_add_community.id,
+ type_: ModlogEnum.ModAddCommunity,
+ view: r,
+ when_: r.mod_add_community.when_,
+ }));
+
+ let added: ModlogType[] = res.added.map(r => ({
+ id: r.mod_add.id,
+ type_: ModlogEnum.ModAdd,
+ view: r,
+ when_: r.mod_add.when_,
+ }));
+
+ let banned: ModlogType[] = res.banned.map(r => ({
+ id: r.mod_ban.id,
+ type_: ModlogEnum.ModBan,
+ view: r,
+ when_: r.mod_ban.when_,
+ }));
+
+ let combined: ModlogType[] = [];
+
+ combined.push(...removed_posts);
+ combined.push(...locked_posts);
+ combined.push(...stickied_posts);
+ combined.push(...removed_comments);
+ combined.push(...removed_communities);
+ combined.push(...banned_from_community);
+ combined.push(...added_to_community);
+ combined.push(...added);
+ combined.push(...banned);
+
+ if (this.state.communityId && combined.length > 0) {
+ this.state.communityName = (combined[0]
+ .view as ModRemovePostView).community.name;
}
// Sort them by time
- this.state.combined.sort((a, b) =>
- b.data.when_.localeCompare(a.data.when_)
- );
+ combined.sort((a, b) => b.when_.localeCompare(a.when_));
+
+ return combined;
+ }
+
+ renderModlogType(i: ModlogType) {
+ switch (i.type_) {
+ case ModlogEnum.ModRemovePost:
+ let mrpv = i.view as ModRemovePostView;
+ return [
+ mrpv.mod_remove_post.removed ? 'Removed ' : 'Restored ',
+ <span>
+ Post <Link to={`/post/${mrpv.post.id}`}>{mrpv.post.name}</Link>
+ </span>,
+ mrpv.mod_remove_post.reason &&
+ ` reason: ${mrpv.mod_remove_post.reason}`,
+ ];
+ case ModlogEnum.ModLockPost:
+ let mlpv = i.view as ModLockPostView;
+ return [
+ mlpv.mod_lock_post.locked ? 'Locked ' : 'Unlocked ',
+ <span>
+ Post <Link to={`/post/${mlpv.post.id}`}>{mlpv.post.name}</Link>
+ </span>,
+ ];
+ case ModlogEnum.ModStickyPost:
+ let mspv = i.view as ModStickyPostView;
+ return [
+ mspv.mod_sticky_post.stickied ? 'Stickied ' : 'Unstickied ',
+ <span>
+ Post <Link to={`/post/${mspv.post.id}`}>{mspv.post.name}</Link>
+ </span>,
+ ];
+ case ModlogEnum.ModRemoveComment:
+ let mrc = i.view as ModRemoveCommentView;
+ return [
+ mrc.mod_remove_comment.removed ? 'Removed ' : 'Restored ',
+ <span>
+ Comment{' '}
+ <Link to={`/post/${mrc.post.id}/comment/${mrc.comment.id}`}>
+ {mrc.comment.content}
+ </Link>
+ </span>,
+ <span>
+ {' '}
+ by <UserListing user={mrc.commenter} />
+ </span>,
+ mrc.mod_remove_comment.reason &&
+ ` reason: ${mrc.mod_remove_comment.reason}`,
+ ];
+ case ModlogEnum.ModRemoveCommunity:
+ let mrco = i.view as ModRemoveCommunityView;
+ return [
+ mrco.mod_remove_community.removed ? 'Removed ' : 'Restored ',
+ <span>
+ Community <CommunityLink community={mrco.community} />
+ </span>,
+ mrco.mod_remove_community.reason &&
+ ` reason: ${mrco.mod_remove_community.reason}`,
+ mrco.mod_remove_community.expires &&
+ ` expires: ${moment
+ .utc(mrco.mod_remove_community.expires)
+ .fromNow()}`,
+ ];
+ case ModlogEnum.ModBanFromCommunity:
+ let mbfc = i.view as ModBanFromCommunityView;
+ return [
+ <span>
+ {mbfc.mod_ban_from_community.banned ? 'Banned ' : 'Unbanned '}{' '}
+ </span>,
+ <span>
+ <UserListing user={mbfc.banned_user} />
+ </span>,
+ <span> from the community </span>,
+ <span>
+ <CommunityLink community={mbfc.community} />
+ </span>,
+ <div>
+ {mbfc.mod_ban_from_community.reason &&
+ ` reason: ${mbfc.mod_ban_from_community.reason}`}
+ </div>,
+ <div>
+ {mbfc.mod_ban_from_community.expires &&
+ ` expires: ${moment
+ .utc(mbfc.mod_ban_from_community.expires)
+ .fromNow()}`}
+ </div>,
+ ];
+ case ModlogEnum.ModAddCommunity:
+ let mac = i.view as ModAddCommunityView;
+ return [
+ <span>
+ {mac.mod_add_community.removed ? 'Removed ' : 'Appointed '}{' '}
+ </span>,
+ <span>
+ <UserListing user={mac.modded_user} />
+ </span>,
+ <span> as a mod to the community </span>,
+ <span>
+ <CommunityLink community={mac.community} />
+ </span>,
+ ];
+ case ModlogEnum.ModBan:
+ let mb = i.view as ModBanView;
+ return [
+ <span>{mb.mod_ban.banned ? 'Banned ' : 'Unbanned '} </span>,
+ <span>
+ <UserListing user={mb.banned_user} />
+ </span>,
+ <div>{mb.mod_ban.reason && ` reason: ${mb.mod_ban.reason}`}</div>,
+ <div>
+ {mb.mod_ban.expires &&
+ ` expires: ${moment.utc(mb.mod_ban.expires).fromNow()}`}
+ </div>,
+ ];
+ case ModlogEnum.ModAdd:
+ let ma = i.view as ModAddView;
+ return [
+ <span>{ma.mod_add.removed ? 'Removed ' : 'Appointed '} </span>,
+ <span>
+ <UserListing user={ma.modded_user} />
+ </span>,
+ <span> as an admin </span>,
+ ];
+ default:
+ return <div />;
+ }
}
combined() {
+ let combined = this.buildCombined(this.state.res);
+
return (
<tbody>
- {this.state.combined.map(i => (
+ {combined.map(i => (
<tr>
<td>
- <MomentTime data={i.data} />
- </td>
- <td>
- <Link to={`/u/${i.data.mod_user_name}`}>
- {i.data.mod_user_name}
- </Link>
+ <MomentTime data={i} />
</td>
<td>
- {i.type_ == 'removed_posts' && (
- <>
- {(i.data as ModRemovePost).removed ? 'Removed' : 'Restored'}
- <span>
- {' '}
- Post{' '}
- <Link to={`/post/${(i.data as ModRemovePost).post_id}`}>
- {(i.data as ModRemovePost).post_name}
- </Link>
- </span>
- <div>
- {(i.data as ModRemovePost).reason &&
- ` reason: ${(i.data as ModRemovePost).reason}`}
- </div>
- </>
- )}
- {i.type_ == 'locked_posts' && (
- <>
- {(i.data as ModLockPost).locked ? 'Locked' : 'Unlocked'}
- <span>
- {' '}
- Post{' '}
- <Link to={`/post/${(i.data as ModLockPost).post_id}`}>
- {(i.data as ModLockPost).post_name}
- </Link>
- </span>
- </>
- )}
- {i.type_ == 'stickied_posts' && (
- <>
- {(i.data as ModStickyPost).stickied
- ? 'Stickied'
- : 'Unstickied'}
- <span>
- {' '}
- Post{' '}
- <Link to={`/post/${(i.data as ModStickyPost).post_id}`}>
- {(i.data as ModStickyPost).post_name}
- </Link>
- </span>
- </>
- )}
- {i.type_ == 'removed_comments' && (
- <>
- {(i.data as ModRemoveComment).removed
- ? 'Removed'
- : 'Restored'}
- <span>
- {' '}
- Comment{' '}
- <Link
- to={`/post/${
- (i.data as ModRemoveComment).post_id
- }/comment/${(i.data as ModRemoveComment).comment_id}`}
- >
- {(i.data as ModRemoveComment).comment_content}
- </Link>
- </span>
- <span>
- {' '}
- by{' '}
- <Link
- to={`/u/${
- (i.data as ModRemoveComment).comment_user_name
- }`}
- >
- {(i.data as ModRemoveComment).comment_user_name}
- </Link>
- </span>
- <div>
- {(i.data as ModRemoveComment).reason &&
- ` reason: ${(i.data as ModRemoveComment).reason}`}
- </div>
- </>
- )}
- {i.type_ == 'removed_communities' && (
- <>
- {(i.data as ModRemoveCommunity).removed
- ? 'Removed'
- : 'Restored'}
- <span>
- {' '}
- Community{' '}
- <Link
- to={`/c/${(i.data as ModRemoveCommunity).community_name}`}
- >
- {(i.data as ModRemoveCommunity).community_name}
- </Link>
- </span>
- <div>
- {(i.data as ModRemoveCommunity).reason &&
- ` reason: ${(i.data as ModRemoveCommunity).reason}`}
- </div>
- <div>
- {(i.data as ModRemoveCommunity).expires &&
- ` expires: ${moment
- .utc((i.data as ModRemoveCommunity).expires)
- .fromNow()}`}
- </div>
- </>
- )}
- {i.type_ == 'banned_from_community' && (
- <>
- <span>
- {(i.data as ModBanFromCommunity).banned
- ? 'Banned '
- : 'Unbanned '}{' '}
- </span>
- <span>
- <Link
- to={`/u/${
- (i.data as ModBanFromCommunity).other_user_name
- }`}
- >
- {(i.data as ModBanFromCommunity).other_user_name}
- </Link>
- </span>
- <span> from the community </span>
- <span>
- <Link
- to={`/c/${
- (i.data as ModBanFromCommunity).community_name
- }`}
- >
- {(i.data as ModBanFromCommunity).community_name}
- </Link>
- </span>
- <div>
- {(i.data as ModBanFromCommunity).reason &&
- ` reason: ${(i.data as ModBanFromCommunity).reason}`}
- </div>
- <div>
- {(i.data as ModBanFromCommunity).expires &&
- ` expires: ${moment
- .utc((i.data as ModBanFromCommunity).expires)
- .fromNow()}`}
- </div>
- </>
- )}
- {i.type_ == 'added_to_community' && (
- <>
- <span>
- {(i.data as ModAddCommunity).removed
- ? 'Removed '
- : 'Appointed '}{' '}
- </span>
- <span>
- <Link
- to={`/u/${(i.data as ModAddCommunity).other_user_name}`}
- >
- {(i.data as ModAddCommunity).other_user_name}
- </Link>
- </span>
- <span> as a mod to the community </span>
- <span>
- <Link
- to={`/c/${(i.data as ModAddCommunity).community_name}`}
- >
- {(i.data as ModAddCommunity).community_name}
- </Link>
- </span>
- </>
- )}
- {i.type_ == 'banned' && (
- <>
- <span>
- {(i.data as ModBan).banned ? 'Banned ' : 'Unbanned '}{' '}
- </span>
- <span>
- <Link to={`/u/${(i.data as ModBan).other_user_name}`}>
- {(i.data as ModBan).other_user_name}
- </Link>
- </span>
- <div>
- {(i.data as ModBan).reason &&
- ` reason: ${(i.data as ModBan).reason}`}
- </div>
- <div>
- {(i.data as ModBan).expires &&
- ` expires: ${moment
- .utc((i.data as ModBan).expires)
- .fromNow()}`}
- </div>
- </>
- )}
- {i.type_ == 'added' && (
- <>
- <span>
- {(i.data as ModAdd).removed ? 'Removed ' : 'Appointed '}{' '}
- </span>
- <span>
- <Link to={`/u/${(i.data as ModAdd).other_user_name}`}>
- {(i.data as ModAdd).other_user_name}
- </Link>
- </span>
- <span> as an admin </span>
- </>
- )}
+ <UserListing user={i.view.moderator} />
</td>
+ <td>{this.renderModlogType(i)}</td>
</tr>
))}
</tbody>
}
get documentTitle(): string {
- return `Modlog - ${this.state.site.name}`;
+ return `Modlog - ${this.state.site_view.site.name}`;
}
render() {
}
refetch() {
- let modlogForm: GetModlogForm = {
+ let modlogForm: GetModlog = {
community_id: this.state.communityId,
page: this.state.page,
limit: fetchLimit,
};
- WebSocketService.Instance.getModlog(modlogForm);
+ WebSocketService.Instance.client.getModlog(modlogForm);
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let communityId = pathSplit[3];
let promises: Promise<any>[] = [];
- let modlogForm: GetModlogForm = {
+ let modlogForm: GetModlog = {
page: 1,
limit: fetchLimit,
};
return promises;
}
- parseMessage(msg: WebSocketJsonResponse) {
- console.log(msg);
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
return;
- } else if (res.op == UserOperation.GetModlog) {
- let data = res.data as GetModlogResponse;
+ } else if (op == UserOperation.GetModlog) {
+ let data = wsJsonToRes<GetModlogResponse>(msg).data;
this.state.loading = false;
window.scrollTo(0, 0);
- this.setCombined(data);
+ this.state.res = data;
this.setState(this.state);
}
}
import { WebSocketService, UserService } from '../services';
import {
UserOperation,
- GetRepliesForm,
+ GetReplies,
GetRepliesResponse,
- GetUserMentionsForm,
+ GetUserMentions,
GetUserMentionsResponse,
- GetPrivateMessagesForm,
+ GetPrivateMessages,
PrivateMessagesResponse,
SortType,
GetSiteResponse,
- Comment,
+ CommentView,
CommentResponse,
- PrivateMessage,
PrivateMessageResponse,
- WebSocketJsonResponse,
+ PrivateMessageView,
} from 'lemmy-js-client';
import {
wsJsonToRes,
isBrowser,
wsSubscribe,
supportLemmyUrl,
+ wsUserOp,
} from '../utils';
import { i18n } from '../i18next';
import { PictrsImage } from './pictrs-image';
interface NavbarProps {
- site: GetSiteResponse;
+ site_res: GetSiteResponse;
}
interface NavbarState {
isLoggedIn: boolean;
expanded: boolean;
- replies: Comment[];
- mentions: Comment[];
- messages: PrivateMessage[];
+ replies: CommentView[];
+ mentions: CommentView[];
+ messages: PrivateMessageView[];
unreadCount: number;
searchParam: string;
toggleSearch: boolean;
private unreadCountSub: Subscription;
private searchTextField: RefObject<HTMLInputElement>;
emptyState: NavbarState = {
- isLoggedIn: !!this.props.site.my_user,
+ isLoggedIn: !!this.props.site_res.my_user,
unreadCount: 0,
replies: [],
mentions: [],
// i18n.changeLanguage('de');
} else {
this.requestNotificationPermission();
- WebSocketService.Instance.userJoin();
+ WebSocketService.Instance.client.userJoin({
+ auth: UserService.Instance.authField(),
+ });
this.fetchUnreads();
}
// A login
if (res !== undefined) {
this.requestNotificationPermission();
- WebSocketService.Instance.getSite();
+ WebSocketService.Instance.client.getSite();
} else {
this.setState({ isLoggedIn: false });
}
// TODO class active corresponding to current page
navbar() {
- let user = this.props.site.my_user;
+ let user = this.props.site_res.my_user;
return (
<nav class="navbar navbar-expand-lg navbar-light shadow-sm p-0 px-3">
<div class="container">
- {this.props.site.site && (
+ {this.props.site_res.site_view && (
<Link
- title={this.props.site.version}
+ title={this.props.site_res.version}
className="d-flex align-items-center navbar-brand mr-md-3"
to="/"
>
- {this.props.site.site.icon && showAvatars() && (
- <PictrsImage src={this.props.site.site.icon} icon />
+ {this.props.site_res.site_view.site.icon && showAvatars() && (
+ <PictrsImage
+ src={this.props.site_res.site_view.site.icon}
+ icon
+ />
)}
- {this.props.site.site.name}
+ {this.props.site_res.site_view.site.name}
</Link>
)}
{this.state.isLoggedIn && (
i.setState(i.state);
}
- parseMessage(msg: WebSocketJsonResponse) {
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
if (msg.error == 'not_logged_in') {
UserService.Instance.logout();
}
return;
} else if (msg.reconnect) {
- WebSocketService.Instance.userJoin();
+ WebSocketService.Instance.client.userJoin({
+ auth: UserService.Instance.authField(),
+ });
this.fetchUnreads();
- } else if (res.op == UserOperation.GetReplies) {
- let data = res.data as GetRepliesResponse;
- let unreadReplies = data.replies.filter(r => !r.read);
+ } else if (op == UserOperation.GetReplies) {
+ let data = wsJsonToRes<GetRepliesResponse>(msg).data;
+ let unreadReplies = data.replies.filter(r => !r.comment.read);
this.state.replies = unreadReplies;
this.state.unreadCount = this.calculateUnreadCount();
this.setState(this.state);
this.sendUnreadCount();
- } else if (res.op == UserOperation.GetUserMentions) {
- let data = res.data as GetUserMentionsResponse;
- let unreadMentions = data.mentions.filter(r => !r.read);
+ } else if (op == UserOperation.GetUserMentions) {
+ let data = wsJsonToRes<GetUserMentionsResponse>(msg).data;
+ let unreadMentions = data.mentions.filter(r => !r.comment.read);
this.state.mentions = unreadMentions;
this.state.unreadCount = this.calculateUnreadCount();
this.setState(this.state);
this.sendUnreadCount();
- } else if (res.op == UserOperation.GetPrivateMessages) {
- let data = res.data as PrivateMessagesResponse;
- let unreadMessages = data.messages.filter(r => !r.read);
+ } else if (op == UserOperation.GetPrivateMessages) {
+ let data = wsJsonToRes<PrivateMessagesResponse>(msg).data;
+ let unreadMessages = data.private_messages.filter(
+ r => !r.private_message.read
+ );
this.state.messages = unreadMessages;
this.state.unreadCount = this.calculateUnreadCount();
this.setState(this.state);
this.sendUnreadCount();
- } else if (res.op == UserOperation.GetSite) {
+ } else if (op == UserOperation.GetSite) {
// This is only called on a successful login
- let data = res.data as GetSiteResponse;
+ let data = wsJsonToRes<GetSiteResponse>(msg).data;
UserService.Instance.user = data.my_user;
setTheme(UserService.Instance.user.theme);
i18n.changeLanguage(getLanguage());
this.state.isLoggedIn = true;
this.setState(this.state);
- } else if (res.op == UserOperation.CreateComment) {
- let data = res.data as CommentResponse;
+ } else if (op == UserOperation.CreateComment) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
if (this.state.isLoggedIn) {
if (data.recipient_ids.includes(UserService.Instance.user.id)) {
- this.state.replies.push(data.comment);
+ this.state.replies.push(data.comment_view);
this.state.unreadCount++;
this.setState(this.state);
this.sendUnreadCount();
- notifyComment(data.comment, this.context.router);
+ notifyComment(data.comment_view, this.context.router);
}
}
- } else if (res.op == UserOperation.CreatePrivateMessage) {
- let data = res.data as PrivateMessageResponse;
+ } else if (op == UserOperation.CreatePrivateMessage) {
+ let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
if (this.state.isLoggedIn) {
- if (data.message.recipient_id == UserService.Instance.user.id) {
- this.state.messages.push(data.message);
+ if (
+ data.private_message_view.recipient.id == UserService.Instance.user.id
+ ) {
+ this.state.messages.push(data.private_message_view);
this.state.unreadCount++;
this.setState(this.state);
this.sendUnreadCount();
- notifyPrivateMessage(data.message, this.context.router);
+ notifyPrivateMessage(data.private_message_view, this.context.router);
}
}
}
fetchUnreads() {
console.log('Fetching unreads...');
- let repliesForm: GetRepliesForm = {
+ let repliesForm: GetReplies = {
sort: SortType.New,
unread_only: true,
page: 1,
limit: fetchLimit,
+ auth: UserService.Instance.authField(),
};
- let userMentionsForm: GetUserMentionsForm = {
+ let userMentionsForm: GetUserMentions = {
sort: SortType.New,
unread_only: true,
page: 1,
limit: fetchLimit,
+ auth: UserService.Instance.authField(),
};
- let privateMessagesForm: GetPrivateMessagesForm = {
+ let privateMessagesForm: GetPrivateMessages = {
unread_only: true,
page: 1,
limit: fetchLimit,
+ auth: UserService.Instance.authField(),
};
if (this.currentLocation !== '/inbox') {
- WebSocketService.Instance.getReplies(repliesForm);
- WebSocketService.Instance.getUserMentions(userMentionsForm);
- WebSocketService.Instance.getPrivateMessages(privateMessagesForm);
+ WebSocketService.Instance.client.getReplies(repliesForm);
+ WebSocketService.Instance.client.getUserMentions(userMentionsForm);
+ WebSocketService.Instance.client.getPrivateMessages(privateMessagesForm);
}
}
calculateUnreadCount(): number {
return (
- this.state.replies.filter(r => !r.read).length +
- this.state.mentions.filter(r => !r.read).length +
- this.state.messages.filter(r => !r.read).length
+ this.state.replies.filter(r => !r.comment.read).length +
+ this.state.mentions.filter(r => !r.comment.read).length +
+ this.state.messages.filter(r => !r.private_message.read).length
);
}
get canAdmin(): boolean {
return (
UserService.Instance.user &&
- this.props.site.admins
- .map(a => a.id)
+ this.props.site_res.admins
+ .map(a => a.user.id)
.includes(UserService.Instance.user.id)
);
}
import {
UserOperation,
LoginResponse,
- PasswordChangeForm,
- WebSocketJsonResponse,
- Site,
+ PasswordChange as PasswordChangeForm,
+ SiteView,
} from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services';
import {
setIsoData,
isBrowser,
wsSubscribe,
+ wsUserOp,
} from '../utils';
import { i18n } from '../i18next';
import { HtmlTags } from './html-tags';
interface State {
passwordChangeForm: PasswordChangeForm;
loading: boolean;
- site: Site;
+ site_view: SiteView;
}
export class PasswordChange extends Component<any, State> {
password_verify: undefined,
},
loading: false,
- site: this.isoData.site.site,
+ site_view: this.isoData.site_res.site_view,
};
constructor(props: any, context: any) {
}
get documentTitle(): string {
- return `${i18n.t('password_change')} - ${this.state.site.name}`;
+ return `${i18n.t('password_change')} - ${this.state.site_view.site.name}`;
}
render() {
i.state.loading = true;
i.setState(i.state);
- WebSocketService.Instance.passwordChange(i.state.passwordChangeForm);
+ WebSocketService.Instance.client.passwordChange(i.state.passwordChangeForm);
}
- parseMessage(msg: WebSocketJsonResponse) {
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
this.state.loading = false;
this.setState(this.state);
return;
- } else if (res.op == UserOperation.PasswordChange) {
- let data = res.data as LoginResponse;
+ } else if (op == UserOperation.PasswordChange) {
+ let data = wsJsonToRes<LoginResponse>(msg).data;
this.state = this.emptyState;
this.setState(this.state);
UserService.Instance.login(data);
import { MarkdownTextArea } from './markdown-textarea';
import { Subscription } from 'rxjs';
import {
- PostForm as PostFormI,
- PostFormParams,
- Post,
+ CreatePost,
+ EditPost,
+ PostView,
PostResponse,
UserOperation,
- Community,
+ CommunityView,
SortType,
- SearchForm,
+ Search,
SearchType,
SearchResponse,
- WebSocketJsonResponse,
} from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services';
+import { PostFormParams } from '../interfaces';
import {
wsJsonToRes,
getPageTitle,
validTitle,
wsSubscribe,
isBrowser,
+ wsUserOp,
} from '../utils';
var Choices;
const MAX_POST_TITLE_LENGTH = 200;
interface PostFormProps {
- post?: Post; // If a post is given, that means this is an edit
- communities?: Community[];
+ post_view?: PostView; // If a post is given, that means this is an edit
+ communities?: CommunityView[];
params?: PostFormParams;
onCancel?(): any;
- onCreate?(id: number): any;
- onEdit?(post: Post): any;
+ onCreate?(post: PostView): any;
+ onEdit?(post: PostView): any;
enableNsfw: boolean;
enableDownvotes: boolean;
}
interface PostFormState {
- postForm: PostFormI;
+ postForm: CreatePost;
loading: boolean;
imageLoading: boolean;
previewMode: boolean;
suggestedTitle: string;
- suggestedPosts: Post[];
- crossPosts: Post[];
+ suggestedPosts: PostView[];
+ crossPosts: PostView[];
}
export class PostForm extends Component<PostFormProps, PostFormState> {
private choices: any;
private emptyState: PostFormState = {
postForm: {
+ community_id: null,
name: null,
nsfw: false,
- auth: null,
- community_id: null,
+ auth: UserService.Instance.authField(),
},
loading: false,
imageLoading: false,
this.state = this.emptyState;
- if (this.props.post) {
+ // Means its an edit
+ if (this.props.post_view) {
this.state.postForm = {
- body: this.props.post.body,
- // NOTE: debouncing breaks both these for some reason, unless you use defaultValue
- name: this.props.post.name,
- community_id: this.props.post.community_id,
- edit_id: this.props.post.id,
- url: this.props.post.url,
- nsfw: this.props.post.nsfw,
- auth: null,
+ body: this.props.post_view.post.body,
+ name: this.props.post_view.post.name,
+ community_id: this.props.post_view.community.id,
+ url: this.props.post_view.post.url,
+ nsfw: this.props.post_view.post.nsfw,
+ auth: UserService.Instance.authField(),
};
}
/>
</div>
</div>
- {!this.props.post && (
+ {!this.props.post_view && (
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="post-community">
{i18n.t('community')}
onInput={linkEvent(this, this.handlePostCommunityChange)}
>
<option>{i18n.t('select_a_community')}</option>
- {this.props.communities.map(community => (
- <option value={community.id}>
- {community.local
- ? community.name
- : `${hostname(community.actor_id)}/${community.name}`}
+ {this.props.communities.map(cv => (
+ <option value={cv.community.id}>
+ {cv.community.local
+ ? cv.community.name
+ : `${hostname(cv.community.actor_id)}/${
+ cv.community.name
+ }`}
</option>
))}
</select>
<svg class="icon icon-spinner spin">
<use xlinkHref="#icon-spinner"></use>
</svg>
- ) : this.props.post ? (
+ ) : this.props.post_view ? (
capitalizeFirstLetter(i18n.t('save'))
) : (
capitalizeFirstLetter(i18n.t('create'))
)}
</button>
- {this.props.post && (
+ {this.props.post_view && (
<button
type="button"
class="btn btn-secondary"
i.state.postForm.url = undefined;
}
- if (i.props.post) {
- WebSocketService.Instance.editPost(i.state.postForm);
+ if (i.props.post_view) {
+ let form: EditPost = {
+ ...i.state.postForm,
+ edit_id: i.props.post_view.post.id,
+ };
+ WebSocketService.Instance.client.editPost(form);
} else {
- WebSocketService.Instance.createPost(i.state.postForm);
+ WebSocketService.Instance.client.createPost(i.state.postForm);
}
i.state.loading = true;
i.setState(i.state);
fetchPageTitle() {
if (validURL(this.state.postForm.url)) {
- let form: SearchForm = {
+ let form: Search = {
q: this.state.postForm.url,
type_: SearchType.Url,
sort: SortType.TopAll,
page: 1,
limit: 6,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.search(form);
+ WebSocketService.Instance.client.search(form);
// Fetch the page title
getPageTitle(this.state.postForm.url).then(d => {
}
fetchSimilarPosts() {
- let form: SearchForm = {
+ let form: Search = {
q: this.state.postForm.name,
type_: SearchType.Posts,
sort: SortType.TopAll,
community_id: this.state.postForm.community_id,
page: 1,
limit: 6,
+ auth: UserService.Instance.authField(false),
};
if (this.state.postForm.name !== '') {
- WebSocketService.Instance.search(form);
+ WebSocketService.Instance.client.search(form);
} else {
this.state.suggestedPosts = [];
}
}
}
- if (this.props.post) {
- this.state.postForm.community_id = this.props.post.community_id;
+ if (this.props.post_view) {
+ this.state.postForm.community_id = this.props.post_view.community.id;
} else if (
this.props.params &&
(this.props.params.community_id || this.props.params.community_name)
) {
if (this.props.params.community_name) {
let foundCommunityId = this.props.communities.find(
- r => r.name == this.props.params.community_name
- ).id;
+ r => r.community.name == this.props.params.community_name
+ ).community.id;
this.state.postForm.community_id = foundCommunityId;
} else if (this.props.params.community_id) {
this.state.postForm.community_id = this.props.params.community_id;
}
}
- parseMessage(msg: WebSocketJsonResponse) {
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
this.state.loading = false;
this.setState(this.state);
return;
- } else if (res.op == UserOperation.CreatePost) {
- let data = res.data as PostResponse;
- if (data.post.creator_id == UserService.Instance.user.id) {
+ } else if (op == UserOperation.CreatePost) {
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ if (data.post_view.creator.id == UserService.Instance.user.id) {
this.state.loading = false;
- this.props.onCreate(data.post.id);
+ this.props.onCreate(data.post_view);
}
- } else if (res.op == UserOperation.EditPost) {
- let data = res.data as PostResponse;
- if (data.post.creator_id == UserService.Instance.user.id) {
+ } else if (op == UserOperation.EditPost) {
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ if (data.post_view.creator.id == UserService.Instance.user.id) {
this.state.loading = false;
- this.props.onEdit(data.post);
+ this.props.onEdit(data.post_view);
}
- } else if (res.op == UserOperation.Search) {
- let data = res.data as SearchResponse;
+ } else if (op == UserOperation.Search) {
+ let data = wsJsonToRes<SearchResponse>(msg).data;
if (data.type_ == SearchType[SearchType.Posts]) {
this.state.suggestedPosts = data.posts;
import { Link } from 'inferno-router';
import { WebSocketService, UserService } from '../services';
import {
- Post,
- CreatePostLikeForm,
- DeletePostForm,
- RemovePostForm,
- LockPostForm,
- StickyPostForm,
- SavePostForm,
- CommunityUser,
- UserView,
- BanFromCommunityForm,
- BanUserForm,
- AddModToCommunityForm,
- AddAdminForm,
- TransferSiteForm,
- TransferCommunityForm,
+ PostView,
+ CreatePostLike,
+ DeletePost,
+ RemovePost,
+ LockPost,
+ StickyPost,
+ SavePost,
+ UserViewSafe,
+ BanFromCommunity,
+ BanUser,
+ AddModToCommunity,
+ AddAdmin,
+ TransferSite,
+ TransferCommunity,
+ CommunityModeratorView,
} from 'lemmy-js-client';
import { BanType } from '../interfaces';
import { MomentTime } from './moment-time';
}
interface PostListingProps {
- post: Post;
+ post_view: PostView;
+ duplicates?: PostView[];
showCommunity?: boolean;
showBody?: boolean;
- moderators?: CommunityUser[];
- admins?: UserView[];
+ moderators?: CommunityModeratorView[];
+ admins?: UserViewSafe[];
enableDownvotes: boolean;
enableNsfw: boolean;
}
viewSource: false,
showAdvanced: false,
showMoreMobile: false,
- my_vote: this.props.post.my_vote,
- score: this.props.post.score,
- upvotes: this.props.post.upvotes,
- downvotes: this.props.post.downvotes,
+ my_vote: this.props.post_view.my_vote,
+ score: this.props.post_view.counts.score,
+ upvotes: this.props.post_view.counts.upvotes,
+ downvotes: this.props.post_view.counts.downvotes,
};
constructor(props: any, context: any) {
}
componentWillReceiveProps(nextProps: PostListingProps) {
- this.state.my_vote = nextProps.post.my_vote;
- this.state.upvotes = nextProps.post.upvotes;
- this.state.downvotes = nextProps.post.downvotes;
- this.state.score = nextProps.post.score;
- if (this.props.post.id !== nextProps.post.id) {
+ this.state.my_vote = nextProps.post_view.my_vote;
+ this.state.upvotes = nextProps.post_view.counts.upvotes;
+ this.state.downvotes = nextProps.post_view.counts.downvotes;
+ this.state.score = nextProps.post_view.counts.score;
+ if (this.props.post_view.post.id !== nextProps.post_view.post.id) {
this.state.imageExpanded = false;
}
this.setState(this.state);
) : (
<div class="col-12">
<PostForm
- post={this.props.post}
+ post_view={this.props.post_view}
onEdit={this.handleEditPost}
onCancel={this.handleEditCancel}
enableNsfw={this.props.enableNsfw}
}
body() {
+ let post = this.props.post_view.post;
return (
<div class="row">
<div class="col-12">
- {this.props.post.url &&
- this.props.showBody &&
- this.props.post.embed_title && (
- <IFramelyCard post={this.props.post} />
- )}
+ {post.url && this.props.showBody && post.embed_title && (
+ <IFramelyCard post={post} />
+ )}
{this.props.showBody &&
- this.props.post.body &&
+ post.body &&
(this.state.viewSource ? (
- <pre>{this.props.post.body}</pre>
+ <pre>{post.body}</pre>
) : (
<div
className="md-div"
- dangerouslySetInnerHTML={mdToHtml(this.props.post.body)}
+ dangerouslySetInnerHTML={mdToHtml(post.body)}
/>
))}
</div>
}
imgThumb(src: string) {
- let post = this.props.post;
+ let post_view = this.props.post_view;
return (
<PictrsImage
src={src}
thumbnail
- nsfw={post.nsfw || post.community_nsfw}
+ nsfw={post_view.post.nsfw || post_view.community.nsfw}
/>
);
}
getImageSrc(): string {
- let post = this.props.post;
+ let post = this.props.post_view.post;
if (isImage(post.url)) {
if (post.url.includes('pictrs')) {
return post.url;
}
thumbnail() {
- let post = this.props.post;
+ let post = this.props.post_view.post;
if (isImage(post.url)) {
return (
}
createdLine() {
- let post = this.props.post;
+ let post_view = this.props.post_view;
return (
<ul class="list-inline mb-1 text-muted small">
<li className="list-inline-item">
- <UserListing
- user={{
- name: post.creator_name,
- preferred_username: post.creator_preferred_username,
- avatar: post.creator_avatar,
- id: post.creator_id,
- local: post.creator_local,
- actor_id: post.creator_actor_id,
- published: post.creator_published,
- }}
- />
+ <UserListing user={post_view.creator} />
{this.isMod && (
<span className="mx-1 badge badge-light">{i18n.t('mod')}</span>
{this.isAdmin && (
<span className="mx-1 badge badge-light">{i18n.t('admin')}</span>
)}
- {(post.banned_from_community || post.banned) && (
+ {(post_view.creator_banned_from_community ||
+ post_view.creator.banned) && (
<span className="mx-1 badge badge-danger">{i18n.t('banned')}</span>
)}
{this.props.showCommunity && (
<span>
<span class="mx-1"> {i18n.t('to')} </span>
- <CommunityLink
- community={{
- name: post.community_name,
- id: post.community_id,
- local: post.community_local,
- actor_id: post.community_actor_id,
- icon: post.community_icon,
- }}
- />
+ <CommunityLink community={post_view.community} />
</span>
)}
</li>
<li className="list-inline-item">•</li>
- {post.url && !(hostname(post.url) == externalHost) && (
+ {post_view.post.url && !(hostname(post_view.post.url) == externalHost) && (
<>
<li className="list-inline-item">
<a
className="text-muted font-italic"
- href={post.url}
+ href={post_view.post.url}
target="_blank"
- title={post.url}
+ title={post_view.post.url}
rel="noopener"
>
- {hostname(post.url)}
+ {hostname(post_view.post.url)}
</a>
</li>
<li className="list-inline-item">•</li>
)}
<li className="list-inline-item">
<span>
- <MomentTime data={post} />
+ <MomentTime data={post_view.post} />
</span>
</li>
- {post.body && (
+ {post_view.post.body && (
<>
<li className="list-inline-item">•</li>
<li className="list-inline-item">
{/* Using a link with tippy doesn't work on touch devices unfortunately */}
<Link
className="text-muted"
- data-tippy-content={md.render(previewLines(post.body))}
+ data-tippy-content={md.render(
+ previewLines(post_view.post.body)
+ )}
data-tippy-allowHtml={true}
- to={`/post/${post.id}`}
+ to={`/post/${post_view.post.id}`}
>
<svg class="mr-1 icon icon-inline">
<use xlinkHref="#icon-book-open"></use>
}
postTitleLine() {
- let post = this.props.post;
+ let post = this.props.post_view.post;
return (
<div className="post-title overflow-hidden">
<h5>
{post.name}
</Link>
)}
- {(isImage(post.url) || this.props.post.thumbnail_url) &&
+ {(isImage(post.url) || post.thumbnail_url) &&
(!this.state.imageExpanded ? (
<span
class="text-monospace unselectable pointer ml-2 text-muted small"
}
commentsLine(mobile: boolean = false) {
- let post = this.props.post;
+ let post_view = this.props.post_view;
return (
<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">
<Link
className="text-muted small"
title={i18n.t('number_of_comments', {
- count: post.number_of_comments,
+ count: post_view.counts.comments,
})}
- to={`/post/${post.id}`}
+ to={`/post/${post_view.post.id}`}
>
<svg class="mr-1 icon icon-inline">
<use xlinkHref="#icon-message-square"></use>
</svg>
{i18n.t('number_of_comments', {
- count: post.number_of_comments,
+ count: post_view.counts.comments,
})}
</Link>
</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')
+ post_view.saved ? i18n.t('unsave') : i18n.t('save')
}
>
<small>
<svg
- class={`icon icon-inline ${post.saved && 'text-warning'}`}
+ class={`icon icon-inline ${
+ post_view.saved && 'text-warning'
+ }`}
>
<use xlinkHref="#icon-star"></use>
</svg>
class="btn btn-link btn-animate text-muted py-0 pl-1 pr-0"
onClick={linkEvent(this, this.handleSavePostClick)}
data-tippy-content={
- post.saved ? i18n.t('unsave') : i18n.t('save')
+ post_view.saved ? i18n.t('unsave') : i18n.t('save')
}
>
- <svg class={`icon icon-inline ${post.saved && 'text-warning'}`}>
+ <svg
+ class={`icon icon-inline ${post_view.saved && 'text-warning'}`}
+ >
<use xlinkHref="#icon-star"></use>
</svg>
</button>
duplicatesLine() {
return (
- this.props.post.duplicates && (
+ this.props.duplicates && (
<ul class="list-inline mb-1 small text-muted">
<>
<li className="list-inline-item mr-2">
{i18n.t('cross_posted_to')}
</li>
- {this.props.post.duplicates.map(post => (
+ {this.props.duplicates.map(pv => (
<li className="list-inline-item mr-2">
- <Link to={`/post/${post.id}`}>
- {post.community_local
- ? post.community_name
- : `${post.community_name}@${hostname(
- post.community_actor_id
- )}`}
+ <Link to={`/post/${pv.post.id}`}>
+ {pv.community.local
+ ? pv.community.name
+ : `${pv.community.name}@${hostname(pv.community.actor_id)}`}
</Link>
</li>
))}
}
postActions(mobile: boolean = false) {
- let post = this.props.post;
+ let post_view = this.props.post_view;
return (
UserService.Instance.user && (
<>
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')
+ post_view.saved ? i18n.t('unsave') : i18n.t('save')
}
>
<svg
- class={`icon icon-inline ${post.saved && 'text-warning'}`}
+ class={`icon icon-inline ${
+ post_view.saved && 'text-warning'
+ }`}
>
<use xlinkHref="#icon-star"></use>
</svg>
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleDeleteClick)}
data-tippy-content={
- !post.deleted ? i18n.t('delete') : i18n.t('restore')
+ !post_view.post.deleted ? i18n.t('delete') : i18n.t('restore')
}
>
<svg
- class={`icon icon-inline ${post.deleted && 'text-danger'}`}
+ class={`icon icon-inline ${
+ post_view.post.deleted && 'text-danger'
+ }`}
>
<use xlinkHref="#icon-trash"></use>
</svg>
</button>
) : (
<>
- {this.props.showBody && post.body && (
+ {this.props.showBody && post_view.post.body && (
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleViewSource)}
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleModLock)}
data-tippy-content={
- post.locked ? i18n.t('unlock') : i18n.t('lock')
+ post_view.post.locked ? i18n.t('unlock') : i18n.t('lock')
}
>
<svg
- class={`icon icon-inline ${post.locked && 'text-danger'}`}
+ class={`icon icon-inline ${
+ post_view.post.locked && 'text-danger'
+ }`}
>
<use xlinkHref="#icon-lock"></use>
</svg>
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleModSticky)}
data-tippy-content={
- post.stickied ? i18n.t('unsticky') : i18n.t('sticky')
+ post_view.post.stickied
+ ? i18n.t('unsticky')
+ : i18n.t('sticky')
}
>
<svg
class={`icon icon-inline ${
- post.stickied && 'text-success'
+ post_view.post.stickied && 'text-success'
}`}
>
<use xlinkHref="#icon-pin"></use>
)}
{/* Mods can ban from community, and appoint as mods to community */}
{(this.canMod || this.canAdmin) &&
- (!post.removed ? (
+ (!post_view.post.removed ? (
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleModRemoveShow)}
{this.canMod && (
<>
{!this.isMod &&
- (!post.banned_from_community ? (
+ (!post_view.creator_banned_from_community ? (
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(
{i18n.t('unban')}
</button>
))}
- {!post.banned_from_community && post.creator_local && (
- <button
- class="btn btn-link btn-animate text-muted py-0"
- onClick={linkEvent(this, this.handleAddModToCommunity)}
- >
- {this.isMod
- ? i18n.t('remove_as_mod')
- : i18n.t('appoint_as_mod')}
- </button>
- )}
+ {!post_view.creator_banned_from_community &&
+ post_view.creator.local && (
+ <button
+ class="btn btn-link btn-animate text-muted py-0"
+ onClick={linkEvent(this, this.handleAddModToCommunity)}
+ >
+ {this.isMod
+ ? i18n.t('remove_as_mod')
+ : i18n.t('appoint_as_mod')}
+ </button>
+ )}
</>
)}
{/* Community creators and admins can transfer community to another mod */}
{(this.amCommunityCreator || this.canAdmin) &&
this.isMod &&
- post.creator_local &&
+ post_view.creator.local &&
(!this.state.showConfirmTransferCommunity ? (
<button
class="btn btn-link btn-animate text-muted py-0"
{this.canAdmin && (
<>
{!this.isAdmin &&
- (!post.banned ? (
+ (!post_view.creator.banned ? (
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleModBanShow)}
{i18n.t('unban_from_site')}
</button>
))}
- {!post.banned && post.creator_local && (
+ {!post_view.creator.banned && post_view.creator.local && (
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleAddAdmin)}
}
removeAndBanDialogs() {
- let post = this.props.post;
+ let post = this.props.post_view;
return (
<>
{this.state.showRemoveDialog && (
{/* </div> */}
<div class="form-group row">
<button type="submit" class="btn btn-secondary">
- {i18n.t('ban')} {post.creator_name}
+ {i18n.t('ban')} {post.creator.name}
</button>
</div>
</form>
}
mobileThumbnail() {
- return this.props.post.thumbnail_url || isImage(this.props.post.url) ? (
+ let post = this.props.post_view.post;
+ return post.thumbnail_url || isImage(post.url) ? (
<div class="row">
<div className={`${this.state.imageExpanded ? 'col-12' : 'col-8'}`}>
{this.postTitleLine()}
}
showMobilePreview() {
+ let post = this.props.post_view.post;
return (
- this.props.post.body &&
+ post.body &&
!this.props.showBody && (
<div
className="md-div mb-1"
dangerouslySetInnerHTML={{
- __html: md.render(previewLines(this.props.post.body)),
+ __html: md.render(previewLines(post.body)),
}}
/>
)
private get myPost(): boolean {
return (
UserService.Instance.user &&
- this.props.post.creator_id == UserService.Instance.user.id
+ this.props.post_view.creator.id == UserService.Instance.user.id
);
}
return (
this.props.moderators &&
isMod(
- this.props.moderators.map(m => m.user_id),
- this.props.post.creator_id
+ this.props.moderators.map(m => m.moderator.id),
+ this.props.post_view.creator.id
)
);
}
return (
this.props.admins &&
isMod(
- this.props.admins.map(a => a.id),
- this.props.post.creator_id
+ this.props.admins.map(a => a.user.id),
+ this.props.post_view.creator.id
)
);
}
get canMod(): boolean {
if (this.props.admins && this.props.moderators) {
let adminsThenMods = this.props.admins
- .map(a => a.id)
- .concat(this.props.moderators.map(m => m.user_id));
+ .map(a => a.user.id)
+ .concat(this.props.moderators.map(m => m.moderator.id));
return canMod(
UserService.Instance.user,
adminsThenMods,
- this.props.post.creator_id
+ this.props.post_view.creator.id
);
} else {
return false;
get canModOnSelf(): boolean {
if (this.props.admins && this.props.moderators) {
let adminsThenMods = this.props.admins
- .map(a => a.id)
- .concat(this.props.moderators.map(m => m.user_id));
+ .map(a => a.user.id)
+ .concat(this.props.moderators.map(m => m.moderator.id));
return canMod(
UserService.Instance.user,
adminsThenMods,
- this.props.post.creator_id,
+ this.props.post_view.creator.id,
true
);
} else {
this.props.admins &&
canMod(
UserService.Instance.user,
- this.props.admins.map(a => a.id),
- this.props.post.creator_id
+ this.props.admins.map(a => a.user.id),
+ this.props.post_view.creator.id
)
);
}
return (
this.props.moderators &&
UserService.Instance.user &&
- this.props.post.creator_id != UserService.Instance.user.id &&
- UserService.Instance.user.id == this.props.moderators[0].user_id
+ this.props.post_view.creator.id != UserService.Instance.user.id &&
+ UserService.Instance.user.id == this.props.moderators[0].moderator.id
);
}
return (
this.props.admins &&
UserService.Instance.user &&
- this.props.post.creator_id != UserService.Instance.user.id &&
- UserService.Instance.user.id == this.props.admins[0].id
+ this.props.post_view.creator.id != UserService.Instance.user.id &&
+ UserService.Instance.user.id == this.props.admins[0].user.id
);
}
i.state.my_vote = new_vote;
- let form: CreatePostLikeForm = {
- post_id: i.props.post.id,
+ let form: CreatePostLike = {
+ post_id: i.props.post_view.post.id,
score: i.state.my_vote,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.likePost(form);
+ WebSocketService.Instance.client.likePost(form);
i.setState(i.state);
setupTippy();
}
i.state.my_vote = new_vote;
- let form: CreatePostLikeForm = {
- post_id: i.props.post.id,
+ let form: CreatePostLike = {
+ post_id: i.props.post_view.post.id,
score: i.state.my_vote,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.likePost(form);
+ WebSocketService.Instance.client.likePost(form);
i.setState(i.state);
setupTippy();
}
}
handleDeleteClick(i: PostListing) {
- let deleteForm: DeletePostForm = {
- edit_id: i.props.post.id,
- deleted: !i.props.post.deleted,
- auth: null,
+ let deleteForm: DeletePost = {
+ edit_id: i.props.post_view.post.id,
+ deleted: !i.props.post_view.post.deleted,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.deletePost(deleteForm);
+ WebSocketService.Instance.client.deletePost(deleteForm);
}
handleSavePostClick(i: PostListing) {
- let saved = i.props.post.saved == undefined ? true : !i.props.post.saved;
- let form: SavePostForm = {
- post_id: i.props.post.id,
+ let saved =
+ i.props.post_view.saved == undefined ? true : !i.props.post_view.saved;
+ let form: SavePost = {
+ post_id: i.props.post_view.post.id,
save: saved,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.savePost(form);
+ WebSocketService.Instance.client.savePost(form);
}
get crossPostParams(): string {
- let params = `?title=${this.props.post.name}`;
- let post = this.props.post;
+ let post = this.props.post_view.post;
+ let params = `?title=${post.name}`;
if (post.url) {
params += `&url=${encodeURIComponent(post.url)}`;
}
- if (this.props.post.body) {
- params += `&body=${this.props.post.body}`;
+ if (post.body) {
+ params += `&body=${post.body}`;
}
return params;
}
handleModRemoveSubmit(i: PostListing) {
event.preventDefault();
- let form: RemovePostForm = {
- edit_id: i.props.post.id,
- removed: !i.props.post.removed,
+ let form: RemovePost = {
+ edit_id: i.props.post_view.post.id,
+ removed: !i.props.post_view.post.removed,
reason: i.state.removeReason,
- auth: null,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.removePost(form);
+ WebSocketService.Instance.client.removePost(form);
i.state.showRemoveDialog = false;
i.setState(i.state);
}
handleModLock(i: PostListing) {
- let form: LockPostForm = {
- edit_id: i.props.post.id,
- locked: !i.props.post.locked,
- auth: null,
+ let form: LockPost = {
+ edit_id: i.props.post_view.post.id,
+ locked: !i.props.post_view.post.locked,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.lockPost(form);
+ WebSocketService.Instance.client.lockPost(form);
}
handleModSticky(i: PostListing) {
- let form: StickyPostForm = {
- edit_id: i.props.post.id,
- stickied: !i.props.post.stickied,
- auth: null,
+ let form: StickyPost = {
+ edit_id: i.props.post_view.post.id,
+ stickied: !i.props.post_view.post.stickied,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.stickyPost(form);
+ WebSocketService.Instance.client.stickyPost(form);
}
handleModBanFromCommunityShow(i: PostListing) {
if (i.state.banType == BanType.Community) {
// If its an unban, restore all their data
- let ban = !i.props.post.banned_from_community;
+ let ban = !i.props.post_view.creator_banned_from_community;
if (ban == false) {
i.state.removeData = false;
}
- let form: BanFromCommunityForm = {
- user_id: i.props.post.creator_id,
- community_id: i.props.post.community_id,
+ let form: BanFromCommunity = {
+ user_id: i.props.post_view.creator.id,
+ community_id: i.props.post_view.community.id,
ban,
remove_data: i.state.removeData,
reason: i.state.banReason,
expires: getUnixTime(i.state.banExpires),
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.banFromCommunity(form);
+ WebSocketService.Instance.client.banFromCommunity(form);
} else {
// If its an unban, restore all their data
- let ban = !i.props.post.banned;
+ let ban = !i.props.post_view.creator.banned;
if (ban == false) {
i.state.removeData = false;
}
- let form: BanUserForm = {
- user_id: i.props.post.creator_id,
+ let form: BanUser = {
+ user_id: i.props.post_view.creator.id,
ban,
remove_data: i.state.removeData,
reason: i.state.banReason,
expires: getUnixTime(i.state.banExpires),
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.banUser(form);
+ WebSocketService.Instance.client.banUser(form);
}
i.state.showBanDialog = false;
}
handleAddModToCommunity(i: PostListing) {
- let form: AddModToCommunityForm = {
- user_id: i.props.post.creator_id,
- community_id: i.props.post.community_id,
+ let form: AddModToCommunity = {
+ user_id: i.props.post_view.creator.id,
+ community_id: i.props.post_view.community.id,
added: !i.isMod,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.addModToCommunity(form);
+ WebSocketService.Instance.client.addModToCommunity(form);
i.setState(i.state);
}
handleAddAdmin(i: PostListing) {
- let form: AddAdminForm = {
- user_id: i.props.post.creator_id,
+ let form: AddAdmin = {
+ user_id: i.props.post_view.creator.id,
added: !i.isAdmin,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.addAdmin(form);
+ WebSocketService.Instance.client.addAdmin(form);
i.setState(i.state);
}
}
handleTransferCommunity(i: PostListing) {
- let form: TransferCommunityForm = {
- community_id: i.props.post.community_id,
- user_id: i.props.post.creator_id,
+ let form: TransferCommunity = {
+ community_id: i.props.post_view.community.id,
+ user_id: i.props.post_view.creator.id,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.transferCommunity(form);
+ WebSocketService.Instance.client.transferCommunity(form);
i.state.showConfirmTransferCommunity = false;
i.setState(i.state);
}
}
handleTransferSite(i: PostListing) {
- let form: TransferSiteForm = {
- user_id: i.props.post.creator_id,
+ let form: TransferSite = {
+ user_id: i.props.post_view.creator.id,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.transferSite(form);
+ WebSocketService.Instance.client.transferSite(form);
i.state.showConfirmTransferSite = false;
i.setState(i.state);
}
import { Component } from 'inferno';
import { Link } from 'inferno-router';
-import { Post, SortType } from 'lemmy-js-client';
+import { PostView, SortType } from 'lemmy-js-client';
import { postSort } from '../utils';
import { PostListing } from './post-listing';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
interface PostListingsProps {
- posts: Post[];
+ posts: PostView[];
showCommunity?: boolean;
removeDuplicates?: boolean;
sort?: SortType;
}
export class PostListings extends Component<PostListingsProps, any> {
+ private duplicatesMap = new Map<number, PostView[]>();
+
constructor(props: any, context: any) {
super(props, context);
}
return (
<div>
{this.props.posts.length > 0 ? (
- this.outer().map(post => (
+ this.outer().map(post_view => (
<>
<PostListing
- post={post}
+ post_view={post_view}
+ duplicates={this.duplicatesMap.get(post_view.post.id)}
showCommunity={this.props.showCommunity}
enableDownvotes={this.props.enableDownvotes}
enableNsfw={this.props.enableNsfw}
);
}
- outer(): Post[] {
+ outer(): PostView[] {
let out = this.props.posts;
if (this.props.removeDuplicates) {
out = this.removeDuplicates(out);
return out;
}
- removeDuplicates(posts: Post[]): Post[] {
+ removeDuplicates(posts: PostView[]): PostView[] {
// A map from post url to list of posts (dupes)
- let urlMap = new Map<string, Post[]>();
+ let urlMap = new Map<string, PostView[]>();
// Loop over the posts, find ones with same urls
- for (let post of posts) {
+ for (let pv of posts) {
if (
- post.url &&
- !post.deleted &&
- !post.removed &&
- !post.community_deleted &&
- !post.community_removed
+ pv.post.url &&
+ !pv.post.deleted &&
+ !pv.post.removed &&
+ !pv.community.deleted &&
+ !pv.community.removed
) {
- if (!urlMap.get(post.url)) {
- urlMap.set(post.url, [post]);
+ if (!urlMap.get(pv.post.url)) {
+ urlMap.set(pv.post.url, [pv]);
} else {
- urlMap.get(post.url).push(post);
+ urlMap.get(pv.post.url).push(pv);
}
}
}
if (e[1].length == 1) {
urlMap.delete(e[0]);
} else {
- e[1].sort((a, b) => a.published.localeCompare(b.published));
+ e[1].sort((a, b) => a.post.published.localeCompare(b.post.published));
}
}
for (let i = 0; i < posts.length; i++) {
- let post = posts[i];
- if (post.url) {
- let found = urlMap.get(post.url);
+ let pv = posts[i];
+ if (pv.post.url) {
+ let found = urlMap.get(pv.post.url);
if (found) {
// If its the oldest, add
- if (post.id == found[0].id) {
- post.duplicates = found.slice(1);
+ if (pv.post.id == found[0].post.id) {
+ this.duplicatesMap.set(pv.post.id, found.slice(1));
}
// Otherwise, delete it
else {
import { Subscription } from 'rxjs';
import {
UserOperation,
- Post as PostI,
+ PostView,
GetPostResponse,
PostResponse,
- MarkCommentAsReadForm,
+ MarkCommentAsRead,
CommentResponse,
CommunityResponse,
- CommentNode as CommentNodeI,
BanFromCommunityResponse,
BanUserResponse,
AddModToCommunityResponse,
AddAdminResponse,
SearchType,
SortType,
- SearchForm,
- GetPostForm,
+ Search,
+ GetPost,
SearchResponse,
GetSiteResponse,
GetCommunityResponse,
- WebSocketJsonResponse,
ListCategoriesResponse,
Category,
} from 'lemmy-js-client';
CommentSortType,
CommentViewType,
InitialFetchRequest,
+ CommentNode as CommentNodeI,
} from '../interfaces';
import { WebSocketService, UserService } from '../services';
import {
getIdFromProps,
getCommentIdFromProps,
wsSubscribe,
- setAuth,
isBrowser,
previewLines,
isImage,
+ wsUserOp,
} from '../utils';
import { PostListing } from './post-listing';
import { Sidebar } from './sidebar';
commentViewType: CommentViewType;
scrolled?: boolean;
loading: boolean;
- crossPosts: PostI[];
+ crossPosts: PostView[];
siteRes: GetSiteResponse;
categories: Category[];
}
scrolled: false,
loading: true,
crossPosts: [],
- siteRes: this.isoData.site,
+ siteRes: this.isoData.site_res,
categories: [],
};
}
} else {
this.fetchPost();
- WebSocketService.Instance.listCategories();
+ WebSocketService.Instance.client.listCategories();
}
}
fetchPost() {
- let form: GetPostForm = {
+ let form: GetPost = {
id: this.state.postId,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.getPost(form);
+ WebSocketService.Instance.client.getPost(form);
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
let id = Number(pathSplit[2]);
- let postForm: GetPostForm = {
+ let postForm: GetPost = {
id,
+ auth: req.auth,
};
- setAuth(postForm, req.auth);
promises.push(req.client.getPost(postForm));
promises.push(req.client.listCategories());
}
componentDidMount() {
- WebSocketService.Instance.postJoin({ post_id: this.state.postId });
+ WebSocketService.Instance.client.postJoin({ post_id: this.state.postId });
autosize(document.querySelectorAll('textarea'));
}
this.markScrolledAsRead(this.state.commentId);
}
+ // TODO this needs some re-work
markScrolledAsRead(commentId: number) {
- let found = this.state.postRes.comments.find(c => c.id == commentId);
- let parent = this.state.postRes.comments.find(c => found.parent_id == c.id);
+ let found = this.state.postRes.comments.find(
+ c => c.comment.id == commentId
+ );
+ let parent = this.state.postRes.comments.find(
+ c => found.comment.parent_id == c.comment.id
+ );
let parent_user_id = parent
- ? parent.creator_id
- : this.state.postRes.post.creator_id;
+ ? parent.creator.id
+ : this.state.postRes.post_view.creator.id;
if (
UserService.Instance.user &&
UserService.Instance.user.id == parent_user_id
) {
- let form: MarkCommentAsReadForm = {
- edit_id: found.id,
+ let form: MarkCommentAsRead = {
+ comment_id: found.creator.id,
read: true,
- auth: null,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.markCommentAsRead(form);
+ WebSocketService.Instance.client.markCommentAsRead(form);
UserService.Instance.unreadCountSub.next(
UserService.Instance.unreadCountSub.value - 1
);
}
get documentTitle(): string {
- return `${this.state.postRes.post.name} - ${this.state.siteRes.site.name}`;
+ return `${this.state.postRes.post_view.post.name} - ${this.state.siteRes.site_view.site.name}`;
}
get imageTag(): string {
+ let post = this.state.postRes.post_view.post;
return (
- this.state.postRes.post.thumbnail_url ||
- (this.state.postRes.post.url
- ? isImage(this.state.postRes.post.url)
- ? this.state.postRes.post.url
- : undefined
- : undefined)
+ post.thumbnail_url ||
+ (post.url ? (isImage(post.url) ? post.url : undefined) : undefined)
);
}
get descriptionTag(): string {
- return this.state.postRes.post.body
- ? previewLines(this.state.postRes.post.body)
- : undefined;
+ let body = this.state.postRes.post_view.post.body;
+ return body ? previewLines(body) : undefined;
}
render() {
+ let pv = this.state.postRes.post_view;
return (
<div class="container">
{this.state.loading ? (
description={this.descriptionTag}
/>
<PostListing
- post={this.state.postRes.post}
+ post_view={pv}
+ duplicates={this.state.crossPosts}
showBody
showCommunity
moderators={this.state.postRes.moderators}
admins={this.state.siteRes.admins}
- enableDownvotes={this.state.siteRes.site.enable_downvotes}
- enableNsfw={this.state.siteRes.site.enable_nsfw}
+ enableDownvotes={
+ this.state.siteRes.site_view.site.enable_downvotes
+ }
+ enableNsfw={this.state.siteRes.site_view.site.enable_nsfw}
/>
<div className="mb-2" />
<CommentForm
postId={this.state.postId}
- disabled={this.state.postRes.post.locked}
+ disabled={pv.post.locked}
/>
{this.state.postRes.comments.length > 0 && this.sortRadios()}
{this.state.commentViewType == CommentViewType.Tree &&
<CommentNodes
nodes={commentsToFlatNodes(this.state.postRes.comments)}
noIndent
- locked={this.state.postRes.post.locked}
+ locked={this.state.postRes.post_view.post.locked}
moderators={this.state.postRes.moderators}
admins={this.state.siteRes.admins}
- postCreatorId={this.state.postRes.post.creator_id}
+ postCreatorId={this.state.postRes.post_view.creator.id}
showContext
- enableDownvotes={this.state.siteRes.site.enable_downvotes}
+ enableDownvotes={this.state.siteRes.site_view.site.enable_downvotes}
sort={this.state.commentSort}
/>
</div>
return (
<div class="mb-3">
<Sidebar
- community={this.state.postRes.community}
+ community_view={this.state.postRes.community_view}
moderators={this.state.postRes.moderators}
admins={this.state.siteRes.admins}
online={this.state.postRes.online}
- enableNsfw={this.state.siteRes.site.enable_nsfw}
+ enableNsfw={this.state.siteRes.site_view.site.enable_nsfw}
showIcon
categories={this.state.categories}
/>
buildCommentsTree(): CommentNodeI[] {
let map = new Map<number, CommentNodeI>();
- for (let comment of this.state.postRes.comments) {
+ for (let comment_view of this.state.postRes.comments) {
let node: CommentNodeI = {
- comment: comment,
+ comment_view: comment_view,
children: [],
};
- map.set(comment.id, { ...node });
+ map.set(comment_view.comment.id, { ...node });
}
let tree: CommentNodeI[] = [];
- for (let comment of this.state.postRes.comments) {
- let child = map.get(comment.id);
- if (comment.parent_id) {
- let parent_ = map.get(comment.parent_id);
+ for (let comment_view of this.state.postRes.comments) {
+ let child = map.get(comment_view.comment.id);
+ if (comment_view.comment.parent_id) {
+ let parent_ = map.get(comment_view.comment.parent_id);
parent_.children.push(child);
} else {
tree.push(child);
setDepth(node: CommentNodeI, i: number = 0): void {
for (let child of node.children) {
- child.comment.depth = i;
+ child.depth = i;
this.setDepth(child, i + 1);
}
}
<div>
<CommentNodes
nodes={nodes}
- locked={this.state.postRes.post.locked}
+ locked={this.state.postRes.post_view.post.locked}
moderators={this.state.postRes.moderators}
admins={this.state.siteRes.admins}
- postCreatorId={this.state.postRes.post.creator_id}
+ postCreatorId={this.state.postRes.post_view.creator.id}
sort={this.state.commentSort}
- enableDownvotes={this.state.siteRes.site.enable_downvotes}
+ enableDownvotes={this.state.siteRes.site_view.site.enable_downvotes}
/>
</div>
);
}
- parseMessage(msg: WebSocketJsonResponse) {
- console.log(msg);
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
return;
} else if (msg.reconnect) {
let postId = Number(this.props.match.params.id);
- WebSocketService.Instance.postJoin({ post_id: postId });
- WebSocketService.Instance.getPost({
+ WebSocketService.Instance.client.postJoin({ post_id: postId });
+ WebSocketService.Instance.client.getPost({
id: postId,
+ auth: UserService.Instance.authField(false),
});
- } else if (res.op == UserOperation.GetPost) {
- let data = res.data as GetPostResponse;
+ } else if (op == UserOperation.GetPost) {
+ let data = wsJsonToRes<GetPostResponse>(msg).data;
this.state.postRes = data;
this.state.loading = false;
// Get cross-posts
- if (this.state.postRes.post.url) {
- let form: SearchForm = {
- q: this.state.postRes.post.url,
+ if (this.state.postRes.post_view.post.url) {
+ let form: Search = {
+ q: this.state.postRes.post_view.post.url,
type_: SearchType.Url,
sort: SortType.TopAll,
page: 1,
limit: 6,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.search(form);
+ WebSocketService.Instance.client.search(form);
}
this.setState(this.state);
setupTippy();
- } else if (res.op == UserOperation.CreateComment) {
- let data = res.data as CommentResponse;
+ } else if (op == UserOperation.CreateComment) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
// Necessary since it might be a user reply
if (data.recipient_ids.length == 0) {
- this.state.postRes.comments.unshift(data.comment);
+ this.state.postRes.comments.unshift(data.comment_view);
this.setState(this.state);
}
} else if (
- res.op == UserOperation.EditComment ||
- res.op == UserOperation.DeleteComment ||
- res.op == UserOperation.RemoveComment
+ op == UserOperation.EditComment ||
+ op == UserOperation.DeleteComment ||
+ op == UserOperation.RemoveComment
) {
- let data = res.data as CommentResponse;
- editCommentRes(data, this.state.postRes.comments);
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ editCommentRes(data.comment_view, this.state.postRes.comments);
this.setState(this.state);
- } else if (res.op == UserOperation.SaveComment) {
- let data = res.data as CommentResponse;
- saveCommentRes(data, this.state.postRes.comments);
+ } else if (op == UserOperation.SaveComment) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ saveCommentRes(data.comment_view, this.state.postRes.comments);
this.setState(this.state);
setupTippy();
- } else if (res.op == UserOperation.CreateCommentLike) {
- let data = res.data as CommentResponse;
- createCommentLikeRes(data, this.state.postRes.comments);
+ } else if (op == UserOperation.CreateCommentLike) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ createCommentLikeRes(data.comment_view, this.state.postRes.comments);
this.setState(this.state);
- } else if (res.op == UserOperation.CreatePostLike) {
- let data = res.data as PostResponse;
- createPostLikeRes(data, this.state.postRes.post);
+ } else if (op == UserOperation.CreatePostLike) {
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ createPostLikeRes(data.post_view, this.state.postRes.post_view);
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
+ op == UserOperation.EditPost ||
+ op == UserOperation.DeletePost ||
+ op == UserOperation.RemovePost ||
+ op == UserOperation.LockPost ||
+ op == UserOperation.StickyPost ||
+ op == UserOperation.SavePost
) {
- let data = res.data as PostResponse;
- this.state.postRes.post = data.post;
- this.setState(this.state);
- setupTippy();
- } else if (res.op == UserOperation.SavePost) {
- let data = res.data as PostResponse;
- this.state.postRes.post = data.post;
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ this.state.postRes.post_view = data.post_view;
this.setState(this.state);
setupTippy();
} else if (
- res.op == UserOperation.EditCommunity ||
- res.op == UserOperation.DeleteCommunity ||
- res.op == UserOperation.RemoveCommunity
+ op == UserOperation.EditCommunity ||
+ op == UserOperation.DeleteCommunity ||
+ op == UserOperation.RemoveCommunity ||
+ op == UserOperation.FollowCommunity
) {
- let data = res.data as CommunityResponse;
- this.state.postRes.community = data.community;
- this.state.postRes.post.community_id = data.community.id;
- this.state.postRes.post.community_name = data.community.name;
+ let data = wsJsonToRes<CommunityResponse>(msg).data;
+ this.state.postRes.community_view = data.community_view;
+ this.state.postRes.post_view.community = data.community_view.community;
this.setState(this.state);
- } else if (res.op == UserOperation.FollowCommunity) {
- let data = res.data as CommunityResponse;
- this.state.postRes.community.subscribed = data.community.subscribed;
- this.state.postRes.community.number_of_subscribers =
- data.community.number_of_subscribers;
this.setState(this.state);
- } else if (res.op == UserOperation.BanFromCommunity) {
- let data = res.data as BanFromCommunityResponse;
+ } else if (op == UserOperation.BanFromCommunity) {
+ let data = wsJsonToRes<BanFromCommunityResponse>(msg).data;
this.state.postRes.comments
- .filter(c => c.creator_id == data.user.id)
- .forEach(c => (c.banned_from_community = data.banned));
- if (this.state.postRes.post.creator_id == data.user.id) {
- this.state.postRes.post.banned_from_community = data.banned;
+ .filter(c => c.creator.id == data.user_view.user.id)
+ .forEach(c => (c.creator_banned_from_community = data.banned));
+ if (this.state.postRes.post_view.creator.id == data.user_view.user.id) {
+ this.state.postRes.post_view.creator_banned_from_community =
+ data.banned;
}
this.setState(this.state);
- } else if (res.op == UserOperation.AddModToCommunity) {
- let data = res.data as AddModToCommunityResponse;
+ } else if (op == UserOperation.AddModToCommunity) {
+ let data = wsJsonToRes<AddModToCommunityResponse>(msg).data;
this.state.postRes.moderators = data.moderators;
this.setState(this.state);
- } else if (res.op == UserOperation.BanUser) {
- let data = res.data as BanUserResponse;
+ } else if (op == UserOperation.BanUser) {
+ let data = wsJsonToRes<BanUserResponse>(msg).data;
this.state.postRes.comments
- .filter(c => c.creator_id == data.user.id)
- .forEach(c => (c.banned = data.banned));
- if (this.state.postRes.post.creator_id == data.user.id) {
- this.state.postRes.post.banned = data.banned;
+ .filter(c => c.creator.id == data.user_view.user.id)
+ .forEach(c => (c.creator.banned = data.banned));
+ if (this.state.postRes.post_view.creator.id == data.user_view.user.id) {
+ this.state.postRes.post_view.creator.banned = data.banned;
}
this.setState(this.state);
- } else if (res.op == UserOperation.AddAdmin) {
- let data = res.data as AddAdminResponse;
+ } else if (op == UserOperation.AddAdmin) {
+ let data = wsJsonToRes<AddAdminResponse>(msg).data;
this.state.siteRes.admins = data.admins;
this.setState(this.state);
- } else if (res.op == UserOperation.Search) {
- let data = res.data as SearchResponse;
+ } else if (op == UserOperation.Search) {
+ let data = wsJsonToRes<SearchResponse>(msg).data;
this.state.crossPosts = data.posts.filter(
- p => p.id != Number(this.props.match.params.id)
+ p => p.post.id != Number(this.props.match.params.id)
);
- if (this.state.crossPosts.length) {
- this.state.postRes.post.duplicates = this.state.crossPosts;
- }
this.setState(this.state);
- } else if (res.op == UserOperation.TransferSite) {
- let data = res.data as GetSiteResponse;
+ } else if (op == UserOperation.TransferSite) {
+ let data = wsJsonToRes<GetSiteResponse>(msg).data;
this.state.siteRes = data;
this.setState(this.state);
- } else if (res.op == UserOperation.TransferCommunity) {
- let data = res.data as GetCommunityResponse;
- this.state.postRes.community = data.community;
+ } else if (op == UserOperation.TransferCommunity) {
+ let data = wsJsonToRes<GetCommunityResponse>(msg).data;
+ this.state.postRes.community_view = data.community_view;
+ this.state.postRes.post_view.community = data.community_view.community;
this.state.postRes.moderators = data.moderators;
this.setState(this.state);
- } else if (res.op == UserOperation.ListCategories) {
- let data = res.data as ListCategoriesResponse;
+ } else if (op == UserOperation.ListCategories) {
+ let data = wsJsonToRes<ListCategoriesResponse>(msg).data;
this.state.categories = data.categories;
this.setState(this.state);
}
import { Prompt } from 'inferno-router';
import { Subscription } from 'rxjs';
import {
- PrivateMessageForm as PrivateMessageFormI,
- EditPrivateMessageForm,
- PrivateMessage,
+ CreatePrivateMessage,
+ EditPrivateMessage,
+ PrivateMessageView,
PrivateMessageResponse,
- UserView,
+ UserSafe,
UserOperation,
- WebSocketJsonResponse,
} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+import { UserService, WebSocketService } from '../services';
import {
capitalizeFirstLetter,
wsJsonToRes,
setupTippy,
wsSubscribe,
isBrowser,
+ wsUserOp,
} from '../utils';
import { UserListing } from './user-listing';
import { MarkdownTextArea } from './markdown-textarea';
import { T } from 'inferno-i18next';
interface PrivateMessageFormProps {
- recipient: UserView;
- privateMessage?: PrivateMessage; // If a pm is given, that means this is an edit
+ recipient: UserSafe;
+ privateMessage?: PrivateMessageView; // If a pm is given, that means this is an edit
onCancel?(): any;
- onCreate?(message: PrivateMessage): any;
- onEdit?(message: PrivateMessage): any;
+ onCreate?(message: PrivateMessageView): any;
+ onEdit?(message: PrivateMessageView): any;
}
interface PrivateMessageFormState {
- privateMessageForm: PrivateMessageFormI;
+ privateMessageForm: CreatePrivateMessage;
loading: boolean;
previewMode: boolean;
showDisclaimer: boolean;
privateMessageForm: {
content: null,
recipient_id: this.props.recipient.id,
+ auth: UserService.Instance.authField(),
},
loading: false,
previewMode: false,
this.parseMessage = this.parseMessage.bind(this);
this.subscription = wsSubscribe(this.parseMessage);
+ // Its an edit
if (this.props.privateMessage) {
- this.state.privateMessageForm = {
- content: this.props.privateMessage.content,
- recipient_id: this.props.privateMessage.recipient_id,
- };
+ this.state.privateMessageForm.content = this.props.privateMessage.private_message.content;
}
}
</label>
<div class="col-sm-10 form-control-plaintext">
- <UserListing
- user={{
- name: this.props.recipient.name,
- preferred_username: this.props.recipient.preferred_username,
- avatar: this.props.recipient.avatar,
- id: this.props.recipient.id,
- local: this.props.recipient.local,
- actor_id: this.props.recipient.actor_id,
- }}
- />
+ <UserListing user={this.props.recipient} />
</div>
</div>
)}
handlePrivateMessageSubmit(i: PrivateMessageForm, event: any) {
event.preventDefault();
if (i.props.privateMessage) {
- let editForm: EditPrivateMessageForm = {
- edit_id: i.props.privateMessage.id,
+ let form: EditPrivateMessage = {
+ edit_id: i.props.privateMessage.private_message.id,
content: i.state.privateMessageForm.content,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.editPrivateMessage(editForm);
+ WebSocketService.Instance.client.editPrivateMessage(form);
} else {
- WebSocketService.Instance.createPrivateMessage(
+ WebSocketService.Instance.client.createPrivateMessage(
i.state.privateMessageForm
);
}
i.setState(i.state);
}
- parseMessage(msg: WebSocketJsonResponse) {
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
this.state.loading = false;
this.setState(this.state);
return;
} else if (
- res.op == UserOperation.EditPrivateMessage ||
- res.op == UserOperation.DeletePrivateMessage ||
- res.op == UserOperation.MarkPrivateMessageAsRead
+ op == UserOperation.EditPrivateMessage ||
+ op == UserOperation.DeletePrivateMessage ||
+ op == UserOperation.MarkPrivateMessageAsRead
) {
- let data = res.data as PrivateMessageResponse;
+ let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
this.state.loading = false;
- this.props.onEdit(data.message);
- } else if (res.op == UserOperation.CreatePrivateMessage) {
- let data = res.data as PrivateMessageResponse;
+ this.props.onEdit(data.private_message_view);
+ } else if (op == UserOperation.CreatePrivateMessage) {
+ let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
this.state.loading = false;
- this.props.onCreate(data.message);
+ this.props.onCreate(data.private_message_view);
this.setState(this.state);
}
}
import { Component, linkEvent } from 'inferno';
import {
- PrivateMessage as PrivateMessageI,
- DeletePrivateMessageForm,
- MarkPrivateMessageAsReadForm,
- UserView,
+ PrivateMessageView,
+ DeletePrivateMessage,
+ MarkPrivateMessageAsRead,
+ UserSafe,
} from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services';
import { mdToHtml, toast } from '../utils';
}
interface PrivateMessageProps {
- privateMessage: PrivateMessageI;
+ private_message_view: PrivateMessageView;
}
export class PrivateMessage extends Component<
get mine(): boolean {
return (
UserService.Instance.user &&
- UserService.Instance.user.id == this.props.privateMessage.creator_id
+ UserService.Instance.user.id == this.props.private_message_view.creator.id
);
}
render() {
- let message = this.props.privateMessage;
- let userOther: UserView = this.mine
- ? {
- name: message.recipient_name,
- preferred_username: message.recipient_preferred_username,
- id: message.recipient_id,
- avatar: message.recipient_avatar,
- local: message.recipient_local,
- actor_id: message.recipient_actor_id,
- published: message.published,
- number_of_posts: 0,
- post_score: 0,
- number_of_comments: 0,
- comment_score: 0,
- banned: false,
- }
- : {
- name: message.creator_name,
- preferred_username: message.creator_preferred_username,
- id: message.creator_id,
- avatar: message.creator_avatar,
- local: message.creator_local,
- actor_id: message.creator_actor_id,
- published: message.published,
- number_of_posts: 0,
- post_score: 0,
- number_of_comments: 0,
- comment_score: 0,
- banned: false,
- };
+ let message_view = this.props.private_message_view;
+ // TODO check this again
+ let userOther: UserSafe = this.mine
+ ? message_view.recipient
+ : message_view.creator;
return (
<div class="border-top border-light">
</li>
<li className="list-inline-item">
<span>
- <MomentTime data={message} />
+ <MomentTime data={message_view.private_message} />
</span>
</li>
<li className="list-inline-item">
{this.state.showEdit && (
<PrivateMessageForm
recipient={userOther}
- privateMessage={message}
+ privateMessage={message_view}
onEdit={this.handlePrivateMessageEdit}
onCreate={this.handlePrivateMessageCreate}
onCancel={this.handleReplyCancel}
class="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleMarkRead)}
data-tippy-content={
- message.read
+ message_view.private_message.read
? i18n.t('mark_as_unread')
: i18n.t('mark_as_read')
}
>
<svg
class={`icon icon-inline ${
- message.read && 'text-success'
+ message_view.private_message.read && 'text-success'
}`}
>
<use xlinkHref="#icon-check"></use>
class="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleDeleteClick)}
data-tippy-content={
- !message.deleted
+ !message_view.private_message.deleted
? i18n.t('delete')
: i18n.t('restore')
}
>
<svg
class={`icon icon-inline ${
- message.deleted && 'text-danger'
+ message_view.private_message.deleted &&
+ 'text-danger'
}`}
>
<use xlinkHref="#icon-trash"></use>
}
get messageUnlessRemoved(): string {
- let message = this.props.privateMessage;
+ let message = this.props.private_message_view.private_message;
return message.deleted ? `*${i18n.t('deleted')}*` : message.content;
}
}
handleDeleteClick(i: PrivateMessage) {
- let form: DeletePrivateMessageForm = {
- edit_id: i.props.privateMessage.id,
- deleted: !i.props.privateMessage.deleted,
+ let form: DeletePrivateMessage = {
+ edit_id: i.props.private_message_view.private_message.id,
+ deleted: !i.props.private_message_view.private_message.deleted,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.deletePrivateMessage(form);
+ WebSocketService.Instance.client.deletePrivateMessage(form);
}
handleReplyCancel() {
}
handleMarkRead(i: PrivateMessage) {
- let form: MarkPrivateMessageAsReadForm = {
- edit_id: i.props.privateMessage.id,
- read: !i.props.privateMessage.read,
+ let form: MarkPrivateMessageAsRead = {
+ edit_id: i.props.private_message_view.private_message.id,
+ read: !i.props.private_message_view.private_message.read,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.markPrivateMessageAsRead(form);
+ WebSocketService.Instance.client.markPrivateMessageAsRead(form);
}
handleMessageCollapse(i: PrivateMessage) {
this.setState(this.state);
}
- handlePrivateMessageCreate(message: PrivateMessageI) {
+ handlePrivateMessageCreate(message: PrivateMessageView) {
if (
UserService.Instance.user &&
- message.creator_id == UserService.Instance.user.id
+ message.creator.id == UserService.Instance.user.id
) {
this.state.showReply = false;
this.setState(this.state);
import { Subscription } from 'rxjs';
import {
UserOperation,
- Post,
- Comment,
- Community,
- UserView,
+ PostView,
+ CommentView,
+ CommunityView,
+ UserViewSafe,
SortType,
- SearchForm,
+ Search as SearchForm,
SearchResponse,
SearchType,
PostResponse,
CommentResponse,
- WebSocketJsonResponse,
Site,
} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+import { UserService, WebSocketService } from '../services';
import {
wsJsonToRes,
fetchLimit,
commentsToFlatNodes,
setIsoData,
wsSubscribe,
- setAuth,
+ wsUserOp,
} from '../utils';
import { PostListing } from './post-listing';
import { HtmlTags } from './html-tags';
users: [],
},
loading: false,
- site: this.isoData.site.site,
+ site: this.isoData.site_res.site_view.site,
};
static getSearchQueryFromProps(q: string): string {
sort: this.getSortTypeFromProps(pathSplit[7]),
page: this.getPageFromProps(pathSplit[9]),
limit: fetchLimit,
+ auth: req.auth,
};
- setAuth(form, req.auth);
if (form.q != '') {
promises.push(req.client.search(form));
all() {
let combined: {
type_: string;
- data: Comment | Post | Community | UserView;
+ data: CommentView | PostView | CommunityView | UserViewSafe;
+ published: string;
}[] = [];
let comments = this.state.searchResponse.comments.map(e => {
- return { type_: 'comments', data: e };
+ return { type_: 'comments', data: e, published: e.comment.published };
});
let posts = this.state.searchResponse.posts.map(e => {
- return { type_: 'posts', data: e };
+ return { type_: 'posts', data: e, published: e.post.published };
});
let communities = this.state.searchResponse.communities.map(e => {
- return { type_: 'communities', data: e };
+ return {
+ type_: 'communities',
+ data: e,
+ published: e.community.published,
+ };
});
let users = this.state.searchResponse.users.map(e => {
- return { type_: 'users', data: e };
+ return { type_: 'users', data: e, published: e.user.published };
});
combined.push(...comments);
// Sort it
if (this.state.sort == SortType.New) {
- combined.sort((a, b) => b.data.published.localeCompare(a.data.published));
+ combined.sort((a, b) => b.published.localeCompare(a.published));
} else {
combined.sort(
(a, b) =>
- ((b.data as Comment | Post).score |
- (b.data as Community).number_of_subscribers |
- (b.data as UserView).comment_score) -
- ((a.data as Comment | Post).score |
- (a.data as Community).number_of_subscribers |
- (a.data as UserView).comment_score)
+ ((b.data as CommentView | PostView).counts.score |
+ (b.data as CommunityView).counts.subscribers |
+ (b.data as UserViewSafe).counts.comment_score) -
+ ((a.data as CommentView | PostView).counts.score |
+ (a.data as CommunityView).counts.subscribers |
+ (a.data as UserViewSafe).counts.comment_score)
);
}
<div class="col-12">
{i.type_ == 'posts' && (
<PostListing
- key={(i.data as Post).id}
- post={i.data as Post}
+ key={(i.data as PostView).post.id}
+ post_view={i.data as PostView}
showCommunity
enableDownvotes={this.state.site.enable_downvotes}
enableNsfw={this.state.site.enable_nsfw}
)}
{i.type_ == 'comments' && (
<CommentNodes
- key={(i.data as Comment).id}
- nodes={[{ comment: i.data as Comment }]}
+ key={(i.data as CommentView).comment.id}
+ nodes={[{ comment_view: i.data as CommentView }]}
locked
noIndent
enableDownvotes={this.state.site.enable_downvotes}
/>
)}
{i.type_ == 'communities' && (
- <div>{this.communityListing(i.data as Community)}</div>
+ <div>{this.communityListing(i.data as CommunityView)}</div>
)}
{i.type_ == 'users' && (
- <div>{this.userListing(i.data as UserView)}</div>
+ <div>{this.userListing(i.data as UserViewSafe)}</div>
)}
</div>
</div>
<div class="row">
<div class="col-12">
<PostListing
- post={post}
+ post_view={post}
showCommunity
enableDownvotes={this.state.site.enable_downvotes}
enableNsfw={this.state.site.enable_nsfw}
);
}
- communityListing(community: Community) {
+ communityListing(community_view: CommunityView) {
return (
<>
<span>
- <CommunityLink community={community} />
+ <CommunityLink community={community_view.community} />
</span>
- <span>{` - ${community.title} -
+ <span>{` - ${community_view.community.title} -
${i18n.t('number_of_subscribers', {
- count: community.number_of_subscribers,
+ count: community_view.counts.subscribers,
})}
`}</span>
</>
);
}
- userListing(user: UserView) {
+ userListing(user_view: UserViewSafe) {
return [
<span>
- <UserListing user={user} showApubName />
+ <UserListing user={user_view.user} showApubName />
</span>,
<span>{` - ${i18n.t('number_of_comments', {
- count: user.number_of_comments,
+ count: user_view.counts.comment_count,
})}`}</span>,
];
}
sort: this.state.sort,
page: this.state.page,
limit: fetchLimit,
+ auth: UserService.Instance.authField(false),
};
if (this.state.q != '') {
- WebSocketService.Instance.search(form);
+ WebSocketService.Instance.client.search(form);
}
}
);
}
- parseMessage(msg: WebSocketJsonResponse) {
+ parseMessage(msg: any) {
console.log(msg);
- let res = wsJsonToRes(msg);
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
return;
- } else if (res.op == UserOperation.Search) {
- let data = res.data as SearchResponse;
+ } else if (op == UserOperation.Search) {
+ let data = wsJsonToRes<SearchResponse>(msg).data;
this.state.searchResponse = data;
this.state.loading = false;
window.scrollTo(0, 0);
this.setState(this.state);
- } else if (res.op == UserOperation.CreateCommentLike) {
- let data = res.data as CommentResponse;
- createCommentLikeRes(data, this.state.searchResponse.comments);
+ } else if (op == UserOperation.CreateCommentLike) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ createCommentLikeRes(
+ data.comment_view,
+ this.state.searchResponse.comments
+ );
this.setState(this.state);
- } else if (res.op == UserOperation.CreatePostLike) {
- let data = res.data as PostResponse;
- createPostLikeFindRes(data, this.state.searchResponse.posts);
+ } else if (op == UserOperation.CreatePostLike) {
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ createPostLikeFindRes(data.post_view, this.state.searchResponse.posts);
this.setState(this.state);
}
}
import { Helmet } from 'inferno-helmet';
import { Subscription } from 'rxjs';
import { retryWhen, delay, take } from 'rxjs/operators';
-import {
- RegisterForm,
- LoginResponse,
- UserOperation,
- WebSocketJsonResponse,
-} from 'lemmy-js-client';
+import { Register, LoginResponse, UserOperation } from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services';
-import { wsJsonToRes, toast } from '../utils';
+import { wsUserOp, wsJsonToRes, toast } from '../utils';
import { SiteForm } from './site-form';
import { i18n } from '../i18next';
interface State {
- userForm: RegisterForm;
+ userForm: Register;
doneRegisteringUser: boolean;
userLoading: boolean;
}
i.state.userLoading = true;
i.setState(i.state);
event.preventDefault();
- WebSocketService.Instance.register(i.state.userForm);
+ WebSocketService.Instance.client.register(i.state.userForm);
}
handleRegisterUsernameChange(i: Setup, event: any) {
i.setState(i.state);
}
- parseMessage(msg: WebSocketJsonResponse) {
- let res = wsJsonToRes(msg);
+ parseMessage(msg: any) {
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
this.state.userLoading = false;
this.setState(this.state);
return;
- } else if (res.op == UserOperation.Register) {
- let data = res.data as LoginResponse;
+ } else if (op == UserOperation.Register) {
+ let data = wsJsonToRes<LoginResponse>(msg).data;
this.state.userLoading = false;
this.state.doneRegisteringUser = true;
UserService.Instance.login(data);
this.setState(this.state);
- } else if (res.op == UserOperation.CreateSite) {
+ } else if (op == UserOperation.CreateSite) {
window.location.href = '/';
}
}
import { Component, linkEvent } from 'inferno';
import { Link } from 'inferno-router';
import {
- Community,
- CommunityUser,
- FollowCommunityForm,
- DeleteCommunityForm,
- RemoveCommunityForm,
- UserView,
- AddModToCommunityForm,
+ CommunityView,
+ CommunityModeratorView,
+ FollowCommunity,
+ DeleteCommunity,
+ RemoveCommunity,
+ UserViewSafe,
+ AddModToCommunity,
Category,
} from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services';
import { i18n } from '../i18next';
interface SidebarProps {
- community: Community;
+ community_view: CommunityView;
categories: Category[];
- moderators: CommunityUser[];
- admins: UserView[];
+ moderators: CommunityModeratorView[];
+ admins: UserViewSafe[];
online: number;
enableNsfw: boolean;
showIcon?: boolean;
) : (
<CommunityForm
categories={this.props.categories}
- community={this.props.community}
+ community_view={this.props.community_view}
onEdit={this.handleEditCommunity}
onCancel={this.handleEditCancel}
enableNsfw={this.props.enableNsfw}
}
communityTitle() {
- let community = this.props.community;
+ let community = this.props.community_view.community;
+ let subscribed = this.props.community_view.subscribed;
return (
<div>
<h5 className="mb-0">
<BannerIconHeader icon={community.icon} banner={community.banner} />
)}
<span class="mr-2">{community.title}</span>
- {community.subscribed && (
+ {subscribed && (
<a
class="btn btn-secondary btn-sm mr-2"
href="#"
}
badges() {
- let community = this.props.community;
+ let community_view = this.props.community_view;
return (
<ul class="my-1 list-inline">
<li className="list-inline-item badge badge-secondary">
</li>
<li className="list-inline-item badge badge-secondary">
{i18n.t('number_of_subscribers', {
- count: community.number_of_subscribers,
+ count: community_view.counts.subscribers,
})}
</li>
<li className="list-inline-item badge badge-secondary">
{i18n.t('number_of_posts', {
- count: community.number_of_posts,
+ count: community_view.counts.posts,
})}
</li>
<li className="list-inline-item badge badge-secondary">
{i18n.t('number_of_comments', {
- count: community.number_of_comments,
+ count: community_view.counts.comments,
})}
</li>
<li className="list-inline-item">
<Link className="badge badge-secondary" to="/communities">
- {community.category_name}
+ {community_view.category.name}
</Link>
</li>
<li className="list-inline-item">
<Link
className="badge badge-secondary"
- to={`/modlog/community/${this.props.community.id}`}
+ to={`/modlog/community/${this.props.community_view.community.id}`}
>
{i18n.t('modlog')}
</Link>
<li class="list-inline-item">{i18n.t('mods')}: </li>
{this.props.moderators.map(mod => (
<li class="list-inline-item">
- <UserListing
- user={{
- name: mod.user_name,
- preferred_username: mod.user_preferred_username,
- avatar: mod.avatar,
- id: mod.user_id,
- local: mod.user_local,
- actor_id: mod.user_actor_id,
- }}
- />
+ <UserListing user={mod.moderator} />
</li>
))}
</ul>
}
createPost() {
- let community = this.props.community;
+ let community_view = this.props.community_view;
return (
- community.subscribed && (
+ community_view.subscribed && (
<Link
className={`btn btn-secondary btn-block mb-2 ${
- community.deleted || community.removed ? 'no-click' : ''
+ community_view.community.deleted || community_view.community.removed
+ ? 'no-click'
+ : ''
}`}
- to={`/create_post?community_id=${community.id}`}
+ to={`/create_post?community_id=${community_view.community.id}`}
>
{i18n.t('create_a_post')}
</Link>
}
subscribe() {
- let community = this.props.community;
+ let community_view = this.props.community_view;
return (
<div class="mb-2">
- {!community.subscribed && (
+ {!community_view.subscribed && (
<a
class="btn btn-secondary btn-block"
href="#"
- onClick={linkEvent(community.id, this.handleSubscribe)}
+ onClick={linkEvent(
+ community_view.community.id,
+ this.handleSubscribe
+ )}
>
{i18n.t('subscribe')}
</a>
}
description() {
- let community = this.props.community;
+ let description = this.props.community_view.community.description;
return (
- community.description && (
+ description && (
<div
className="md-div"
- dangerouslySetInnerHTML={mdToHtml(community.description)}
+ dangerouslySetInnerHTML={mdToHtml(description)}
/>
)
);
}
adminButtons() {
- let community = this.props.community;
+ let community_view = this.props.community_view;
return (
<>
<ul class="list-inline mb-1 text-muted font-weight-bold">
class="pointer"
onClick={linkEvent(this, this.handleDeleteClick)}
data-tippy-content={
- !community.deleted ? i18n.t('delete') : i18n.t('restore')
+ !community_view.community.deleted
+ ? i18n.t('delete')
+ : i18n.t('restore')
}
>
<svg
class={`icon icon-inline ${
- community.deleted && 'text-danger'
+ community_view.community.deleted && 'text-danger'
}`}
>
<use xlinkHref="#icon-trash"></use>
)}
{this.canAdmin && (
<li className="list-inline-item">
- {!this.props.community.removed ? (
+ {!this.props.community_view.community.removed ? (
<span
class="pointer"
onClick={linkEvent(this, this.handleModRemoveShow)}
handleDeleteClick(i: Sidebar, event: any) {
event.preventDefault();
- let deleteForm: DeleteCommunityForm = {
- edit_id: i.props.community.id,
- deleted: !i.props.community.deleted,
+ let deleteForm: DeleteCommunity = {
+ edit_id: i.props.community_view.community.id,
+ deleted: !i.props.community_view.community.deleted,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.deleteCommunity(deleteForm);
+ WebSocketService.Instance.client.deleteCommunity(deleteForm);
}
handleShowConfirmLeaveModTeamClick(i: Sidebar) {
}
handleLeaveModTeamClick(i: Sidebar) {
- let form: AddModToCommunityForm = {
+ let form: AddModToCommunity = {
user_id: UserService.Instance.user.id,
- community_id: i.props.community.id,
+ community_id: i.props.community_view.community.id,
added: false,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.addModToCommunity(form);
+ WebSocketService.Instance.client.addModToCommunity(form);
i.state.showConfirmLeaveModTeam = false;
i.setState(i.state);
}
handleUnsubscribe(communityId: number, event: any) {
event.preventDefault();
- let form: FollowCommunityForm = {
+ let form: FollowCommunity = {
community_id: communityId,
follow: false,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.followCommunity(form);
+ WebSocketService.Instance.client.followCommunity(form);
}
handleSubscribe(communityId: number, event: any) {
event.preventDefault();
- let form: FollowCommunityForm = {
+ let form: FollowCommunity = {
community_id: communityId,
follow: true,
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.followCommunity(form);
+ WebSocketService.Instance.client.followCommunity(form);
}
private get amCreator(): boolean {
- return this.props.community.creator_id == UserService.Instance.user.id;
+ return this.props.community_view.creator.id == UserService.Instance.user.id;
}
get canMod(): boolean {
return (
UserService.Instance.user &&
this.props.moderators
- .map(m => m.user_id)
+ .map(m => m.moderator.id)
.includes(UserService.Instance.user.id)
);
}
get canAdmin(): boolean {
return (
UserService.Instance.user &&
- this.props.admins.map(a => a.id).includes(UserService.Instance.user.id)
+ this.props.admins
+ .map(a => a.user.id)
+ .includes(UserService.Instance.user.id)
);
}
handleModRemoveSubmit(i: Sidebar, event: any) {
event.preventDefault();
- let removeForm: RemoveCommunityForm = {
- edit_id: i.props.community.id,
- removed: !i.props.community.removed,
+ let removeForm: RemoveCommunity = {
+ edit_id: i.props.community_view.community.id,
+ removed: !i.props.community_view.community.removed,
reason: i.state.removeReason,
expires: getUnixTime(i.state.removeExpires),
+ auth: UserService.Instance.authField(),
};
- WebSocketService.Instance.removeCommunity(removeForm);
+ WebSocketService.Instance.client.removeCommunity(removeForm);
i.state.showRemoveDialog = false;
i.setState(i.state);
import { Prompt } from 'inferno-router';
import { MarkdownTextArea } from './markdown-textarea';
import { ImageUploadForm } from './image-upload-form';
-import { Site, SiteForm as SiteFormI } from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+import { Site, EditSite } from 'lemmy-js-client';
+import { UserService, WebSocketService } from '../services';
import { capitalizeFirstLetter, randomStr } from '../utils';
import { i18n } from '../i18next';
}
interface SiteFormState {
- siteForm: SiteFormI;
+ siteForm: EditSite;
loading: boolean;
}
name: null,
icon: null,
banner: null,
+ auth: UserService.Instance.authField(),
},
loading: false,
};
enable_nsfw: this.props.site.enable_nsfw,
icon: this.props.site.icon,
banner: this.props.site.banner,
+ auth: UserService.Instance.authField(),
};
}
}
event.preventDefault();
i.state.loading = true;
if (i.props.site) {
- WebSocketService.Instance.editSite(i.state.siteForm);
+ WebSocketService.Instance.client.editSite(i.state.siteForm);
} else {
- WebSocketService.Instance.createSite(i.state.siteForm);
+ WebSocketService.Instance.client.createSite(i.state.siteForm);
}
i.setState(i.state);
}
-import { User } from 'lemmy-js-client';
+import { User_ } from 'lemmy-js-client';
import { Helmet } from 'inferno-helmet';
import { Component } from 'inferno';
interface Props {
- user: User | undefined;
+ user: User_ | undefined;
}
export class Theme extends Component<Props> {
import { Component, linkEvent } from 'inferno';
import { i18n } from '../i18next';
-import { Post, Comment, SortType, UserDetailsResponse } from 'lemmy-js-client';
+import {
+ PostView,
+ CommentView,
+ SortType,
+ GetUserDetailsResponse,
+ UserViewSafe,
+} from 'lemmy-js-client';
import { UserDetailsView } from '../interfaces';
import { commentsToFlatNodes, setupTippy } from '../utils';
import { PostListing } from './post-listing';
import { CommentNodes } from './comment-nodes';
interface UserDetailsProps {
- userRes: UserDetailsResponse;
+ userRes: GetUserDetailsResponse;
+ admins: UserViewSafe[];
page: number;
limit: number;
sort: SortType;
interface UserDetailsState {}
+enum ItemEnum {
+ Comment,
+ Post,
+}
+type ItemType = {
+ id: number;
+ type_: ItemEnum;
+ view: CommentView | PostView;
+ published: string;
+ score: number;
+};
+
export class UserDetails extends Component<UserDetailsProps, UserDetailsState> {
constructor(props: any, context: any) {
super(props, context);
}
}
+ renderItemType(i: ItemType) {
+ switch (i.type_) {
+ case ItemEnum.Comment:
+ let c = i.view as CommentView;
+ return (
+ <CommentNodes
+ key={i.id}
+ nodes={[{ comment_view: c }]}
+ admins={this.props.admins}
+ noBorder
+ noIndent
+ showCommunity
+ showContext
+ enableDownvotes={this.props.enableDownvotes}
+ />
+ );
+ case ItemEnum.Post:
+ let p = i.view as PostView;
+ return (
+ <PostListing
+ key={i.id}
+ post_view={p}
+ admins={this.props.admins}
+ showCommunity
+ enableDownvotes={this.props.enableDownvotes}
+ enableNsfw={this.props.enableNsfw}
+ />
+ );
+ default:
+ return <div />;
+ }
+ }
+
overview() {
- const comments = this.props.userRes.comments.map((c: Comment) => {
- return { type: 'comments', data: c };
- });
- const posts = this.props.userRes.posts.map((p: Post) => {
- return { type: 'posts', data: p };
- });
-
- const combined: { type: string; data: Comment | Post }[] = [
- ...comments,
- ...posts,
- ];
+ let id = 0;
+ let comments: ItemType[] = this.props.userRes.comments.map(r => ({
+ id: id++,
+ type_: ItemEnum.Comment,
+ view: r,
+ published: r.comment.published,
+ score: r.counts.score,
+ }));
+ let posts: ItemType[] = this.props.userRes.posts.map(r => ({
+ id: id++,
+ type_: ItemEnum.Comment,
+ view: r,
+ published: r.post.published,
+ score: r.counts.score,
+ }));
+
+ let combined = [...comments, ...posts];
// Sort it
if (this.props.sort === SortType.New) {
- combined.sort((a, b) => b.data.published.localeCompare(a.data.published));
+ combined.sort((a, b) => b.published.localeCompare(a.published));
} else {
- combined.sort((a, b) => b.data.score - a.data.score);
+ combined.sort((a, b) => b.score - a.score);
}
return (
<div>
- {combined.map(i => (
- <>
- <div>
- {i.type === 'posts' ? (
- <PostListing
- key={(i.data as Post).id}
- post={i.data as Post}
- admins={this.props.userRes.admins}
- showCommunity
- enableDownvotes={this.props.enableDownvotes}
- enableNsfw={this.props.enableNsfw}
- />
- ) : (
- <CommentNodes
- key={(i.data as Comment).id}
- nodes={[{ comment: i.data as Comment }]}
- admins={this.props.userRes.admins}
- noBorder
- noIndent
- showCommunity
- showContext
- enableDownvotes={this.props.enableDownvotes}
- />
- )}
- </div>
- <hr class="my-3" />
- </>
- ))}
+ {combined.map(i => [this.renderItemType(i), <hr class="my-3" />])}
</div>
);
}
<div>
<CommentNodes
nodes={commentsToFlatNodes(this.props.userRes.comments)}
- admins={this.props.userRes.admins}
+ admins={this.props.admins}
noIndent
showCommunity
showContext
{this.props.userRes.posts.map(post => (
<>
<PostListing
- post={post}
- admins={this.props.userRes.admins}
+ post_view={post}
+ admins={this.props.admins}
showCommunity
enableDownvotes={this.props.enableDownvotes}
enableNsfw={this.props.enableNsfw}
import { Component } from 'inferno';
import { Link } from 'inferno-router';
-import { UserView } from 'lemmy-js-client';
+import { UserSafe } from 'lemmy-js-client';
import { showAvatars, hostname, isCakeDay } from '../utils';
import { CakeDay } from './cake-day';
import { PictrsImage } from './pictrs-image';
-export interface UserOther {
- name: string;
- preferred_username?: string;
- id?: number; // Necessary if its federated
- avatar?: string;
- local?: boolean;
- actor_id?: string;
- published?: string;
-}
-
interface UserListingProps {
- user: UserView | UserOther;
+ user: UserSafe;
realLink?: boolean;
useApubName?: boolean;
muted?: boolean;
UserOperation,
SortType,
ListingType,
- UserSettingsForm,
+ SaveUserSettings,
LoginResponse,
- DeleteAccountForm,
- WebSocketJsonResponse,
+ DeleteAccount,
GetSiteResponse,
- UserDetailsResponse,
+ GetUserDetailsResponse,
AddAdminResponse,
- GetUserDetailsForm,
+ GetUserDetails,
CommentResponse,
PostResponse,
BanUserResponse,
editCommentRes,
saveCommentRes,
createPostLikeFindRes,
- setAuth,
previewLines,
editPostFindRes,
+ wsUserOp,
} from '../utils';
import { UserListing } from './user-listing';
import { HtmlTags } from './html-tags';
import { CommunityLink } from './community-link';
interface UserState {
- userRes: UserDetailsResponse;
+ userRes: GetUserDetailsResponse;
userId: number;
userName: string;
view: UserDetailsView;
sort: SortType;
page: number;
loading: boolean;
- userSettingsForm: UserSettingsForm;
+ userSettingsForm: SaveUserSettings;
userSettingsLoading: boolean;
deleteAccountLoading: boolean;
deleteAccountShowConfirm: boolean;
- deleteAccountForm: DeleteAccountForm;
+ deleteAccountForm: DeleteAccount;
siteRes: GetSiteResponse;
}
lang: null,
show_avatars: null,
send_notifications_to_email: null,
- auth: null,
bio: null,
preferred_username: null,
+ auth: UserService.Instance.authField(),
},
userSettingsLoading: null,
deleteAccountLoading: null,
deleteAccountShowConfirm: false,
deleteAccountForm: {
password: null,
+ auth: UserService.Instance.authField(),
},
- siteRes: this.isoData.site,
+ siteRes: this.isoData.site_res,
};
constructor(props: any, context: any) {
}
fetchUserData() {
- let form: GetUserDetailsForm = {
+ let form: GetUserDetails = {
user_id: this.state.userId,
username: this.state.userName,
sort: this.state.sort,
saved_only: this.state.view === UserDetailsView.Saved,
page: this.state.page,
limit: fetchLimit,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.getUserDetails(form);
+ WebSocketService.Instance.client.getUserDetails(form);
}
get isCurrentUser() {
return (
UserService.Instance.user &&
- UserService.Instance.user.id == this.state.userRes.user.id
+ UserService.Instance.user.id == this.state.userRes.user_view.user.id
);
}
let sort = this.getSortTypeFromProps(pathSplit[6]);
let page = this.getPageFromProps(Number(pathSplit[8]));
- let form: GetUserDetailsForm = {
+ let form: GetUserDetails = {
sort,
saved_only: view === UserDetailsView.Saved,
page,
limit: fetchLimit,
+ auth: req.auth,
};
this.setIdOrName(form, user_id, username);
- setAuth(form, req.auth);
promises.push(req.client.getUserDetails(form));
return promises;
}
}
get documentTitle(): string {
- return `@${this.state.userRes.user.name} - ${this.state.siteRes.site.name}`;
+ return `@${this.state.userRes.user_view.user.name} - ${this.state.siteRes.site_view.site.name}`;
}
get bioTag(): string {
- return this.state.userRes.user.bio
- ? previewLines(this.state.userRes.user.bio)
+ return this.state.userRes.user_view.user.bio
+ ? previewLines(this.state.userRes.user_view.user.bio)
: undefined;
}
title={this.documentTitle}
path={this.context.router.route.match.url}
description={this.bioTag}
- image={this.state.userRes.user.avatar}
+ image={this.state.userRes.user_view.user.avatar}
/>
{this.userInfo()}
<hr />
{!this.state.loading && this.selects()}
<UserDetails
userRes={this.state.userRes}
+ admins={this.state.siteRes.admins}
sort={this.state.sort}
page={this.state.page}
limit={fetchLimit}
- enableDownvotes={this.state.siteRes.site.enable_downvotes}
- enableNsfw={this.state.siteRes.site.enable_nsfw}
+ enableDownvotes={
+ this.state.siteRes.site_view.site.enable_downvotes
+ }
+ enableNsfw={this.state.siteRes.site_view.site.enable_nsfw}
view={this.state.view}
onPageChange={this.handlePageChange}
/>
}
userInfo() {
- let user = this.state.userRes.user;
+ let uv = this.state.userRes.user_view;
return (
<div>
- <BannerIconHeader banner={user.banner} icon={user.avatar} />
+ <BannerIconHeader banner={uv.user.banner} icon={uv.user.avatar} />
<div class="mb-3">
<div class="">
<div class="mb-0 d-flex flex-wrap">
<div>
- {user.preferred_username && (
- <h5 class="mb-0">{user.preferred_username}</h5>
+ {uv.user.preferred_username && (
+ <h5 class="mb-0">{uv.user.preferred_username}</h5>
)}
<ul class="list-inline mb-2">
<li className="list-inline-item">
<UserListing
- user={user}
+ user={uv.user}
realLink
useApubName
muted
hideAvatar
/>
</li>
- {user.banned && (
+ {uv.user.banned && (
<li className="list-inline-item badge badge-danger">
{i18n.t('banned')}
</li>
<>
<a
className={`d-flex align-self-start btn btn-secondary mr-2 ${
- !user.matrix_user_id && 'invisible'
+ !uv.user.matrix_user_id && 'invisible'
}`}
target="_blank"
rel="noopener"
- href={`https://matrix.to/#/${user.matrix_user_id}`}
+ href={`https://matrix.to/#/${uv.user.matrix_user_id}`}
>
{i18n.t('send_secure_message')}
</a>
<Link
className={'d-flex align-self-start btn btn-secondary'}
- to={`/create_private_message/recipient/${user.id}`}
+ to={`/create_private_message/recipient/${uv.user.id}`}
>
{i18n.t('send_message')}
</Link>
</>
)}
</div>
- {user.bio && (
+ {uv.user.bio && (
<div className="d-flex align-items-center mb-2">
<div
className="md-div"
- dangerouslySetInnerHTML={mdToHtml(user.bio)}
+ dangerouslySetInnerHTML={mdToHtml(uv.user.bio)}
/>
</div>
)}
<div>
<ul class="list-inline mb-2">
<li className="list-inline-item badge badge-light">
- {i18n.t('number_of_posts', { count: user.number_of_posts })}
+ {i18n.t('number_of_posts', { count: uv.counts.post_count })}
</li>
<li className="list-inline-item badge badge-light">
{i18n.t('number_of_comments', {
- count: user.number_of_comments,
+ count: uv.counts.comment_count,
})}
</li>
</ul>
</div>
<div class="text-muted">
- {i18n.t('joined')} <MomentTime data={user} showAgo />
+ {i18n.t('joined')} <MomentTime data={uv.user} showAgo />
</div>
<div className="d-flex align-items-center text-muted mb-2">
<svg class="icon">
</svg>
<span className="ml-2">
{i18n.t('cake_day_title')}{' '}
- {moment.utc(user.published).local().format('MMM DD, YYYY')}
+ {moment.utc(uv.user.published).local().format('MMM DD, YYYY')}
</span>
</div>
</div>
/>
</div>
</div>
- {this.state.siteRes.site.enable_nsfw && (
+ {this.state.siteRes.site_view.site.enable_nsfw && (
<div class="form-group">
<div class="form-check">
<input
<div class="card-body">
<h5>{i18n.t('moderates')}</h5>
<ul class="list-unstyled mb-0">
- {this.state.userRes.moderates.map(community => (
+ {this.state.userRes.moderates.map(cmv => (
<li>
- <CommunityLink
- community={{
- name: community.community_name,
- id: community.community_id,
- local: community.community_local,
- actor_id: community.community_actor_id,
- icon: community.community_icon,
- }}
- />
+ <CommunityLink community={cmv.community} />
</li>
))}
</ul>
<div class="card-body">
<h5>{i18n.t('subscribed')}</h5>
<ul class="list-unstyled mb-0">
- {this.state.userRes.follows.map(community => (
+ {this.state.userRes.follows.map(cfv => (
<li>
- <CommunityLink
- community={{
- name: community.community_name,
- id: community.community_id,
- local: community.community_local,
- actor_id: community.community_actor_id,
- icon: community.community_icon,
- }}
- />
+ <CommunityLink community={cfv.community} />
</li>
))}
</ul>
}
handleUserSettingsSortTypeChange(val: SortType) {
- this.state.userSettingsForm.default_sort_type = Object.keys(
- SortType
- ).indexOf(val);
+ this.state.userSettingsForm.default_sort_type = val;
this.setState(this.state);
}
handleUserSettingsListingTypeChange(val: ListingType) {
- this.state.userSettingsForm.default_listing_type = Object.keys(
- ListingType
- ).indexOf(val);
+ this.state.userSettingsForm.default_listing_type = val;
this.setState(this.state);
}
i.state.userSettingsForm.matrix_user_id = event.target.value;
if (
i.state.userSettingsForm.matrix_user_id == '' &&
- !i.state.userRes.user.matrix_user_id
+ !i.state.userRes.user_view.user.matrix_user_id
) {
i.state.userSettingsForm.matrix_user_id = undefined;
}
i.state.userSettingsLoading = true;
i.setState(i.state);
- WebSocketService.Instance.saveUserSettings(i.state.userSettingsForm);
+ WebSocketService.Instance.client.saveUserSettings(i.state.userSettingsForm);
}
handleDeleteAccountShowConfirmToggle(i: User, event: any) {
i.state.deleteAccountLoading = true;
i.setState(i.state);
- WebSocketService.Instance.deleteAccount(i.state.deleteAccountForm);
+ WebSocketService.Instance.client.deleteAccount(i.state.deleteAccountForm);
i.handleLogoutClick(i);
}
}
}
- parseMessage(msg: WebSocketJsonResponse) {
+ parseMessage(msg: any) {
console.log(msg);
- const res = wsJsonToRes(msg);
+ let op = wsUserOp(msg);
if (msg.error) {
toast(i18n.t(msg.error), 'danger');
if (msg.error == 'couldnt_find_that_username_or_email') {
return;
} else if (msg.reconnect) {
this.fetchUserData();
- } else if (res.op == UserOperation.GetUserDetails) {
+ } else if (op == UserOperation.GetUserDetails) {
// Since the UserDetails contains posts/comments as well as some general user info we listen here as well
// and set the parent state if it is not set or differs
// TODO this might need to get abstracted
- const data = res.data as UserDetailsResponse;
+ let data = wsJsonToRes<GetUserDetailsResponse>(msg).data;
this.state.userRes = data;
this.setUserInfo();
this.state.loading = false;
this.setState(this.state);
- } else if (res.op == UserOperation.SaveUserSettings) {
- const data = res.data as LoginResponse;
+ } else if (op == UserOperation.SaveUserSettings) {
+ let data = wsJsonToRes<LoginResponse>(msg).data;
UserService.Instance.login(data);
- this.state.userRes.user.bio = this.state.userSettingsForm.bio;
- this.state.userRes.user.preferred_username = this.state.userSettingsForm.preferred_username;
- this.state.userRes.user.banner = this.state.userSettingsForm.banner;
- this.state.userRes.user.avatar = this.state.userSettingsForm.avatar;
+ this.state.userRes.user_view.user.bio = this.state.userSettingsForm.bio;
+ this.state.userRes.user_view.user.preferred_username = this.state.userSettingsForm.preferred_username;
+ this.state.userRes.user_view.user.banner = this.state.userSettingsForm.banner;
+ this.state.userRes.user_view.user.avatar = this.state.userSettingsForm.avatar;
this.state.userSettingsLoading = false;
this.setState(this.state);
window.scrollTo(0, 0);
- } else if (res.op == UserOperation.DeleteAccount) {
+ } else if (op == UserOperation.DeleteAccount) {
this.setState({
deleteAccountLoading: false,
deleteAccountShowConfirm: false,
});
this.context.router.history.push('/');
- } else if (res.op == UserOperation.AddAdmin) {
- const data = res.data as AddAdminResponse;
+ } else if (op == UserOperation.AddAdmin) {
+ let data = wsJsonToRes<AddAdminResponse>(msg).data;
this.state.siteRes.admins = data.admins;
this.setState(this.state);
- } else if (res.op == UserOperation.CreateCommentLike) {
- const data = res.data as CommentResponse;
- createCommentLikeRes(data, this.state.userRes.comments);
+ } else if (op == UserOperation.CreateCommentLike) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ createCommentLikeRes(data.comment_view, this.state.userRes.comments);
this.setState(this.state);
} else if (
- res.op == UserOperation.EditComment ||
- res.op == UserOperation.DeleteComment ||
- res.op == UserOperation.RemoveComment
+ op == UserOperation.EditComment ||
+ op == UserOperation.DeleteComment ||
+ op == UserOperation.RemoveComment
) {
- const data = res.data as CommentResponse;
- editCommentRes(data, this.state.userRes.comments);
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ editCommentRes(data.comment_view, this.state.userRes.comments);
this.setState(this.state);
- } else if (res.op == UserOperation.CreateComment) {
- const data = res.data as CommentResponse;
+ } else if (op == UserOperation.CreateComment) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
if (
UserService.Instance.user &&
- data.comment.creator_id == UserService.Instance.user.id
+ data.comment_view.creator.id == UserService.Instance.user.id
) {
toast(i18n.t('reply_sent'));
}
- } else if (res.op == UserOperation.SaveComment) {
- const data = res.data as CommentResponse;
- saveCommentRes(data, this.state.userRes.comments);
+ } else if (op == UserOperation.SaveComment) {
+ let data = wsJsonToRes<CommentResponse>(msg).data;
+ saveCommentRes(data.comment_view, this.state.userRes.comments);
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
+ op == UserOperation.EditPost ||
+ op == UserOperation.DeletePost ||
+ op == UserOperation.RemovePost ||
+ op == UserOperation.LockPost ||
+ op == UserOperation.StickyPost ||
+ op == UserOperation.SavePost
) {
- let data = res.data as PostResponse;
- editPostFindRes(data, this.state.userRes.posts);
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ editPostFindRes(data.post_view, this.state.userRes.posts);
this.setState(this.state);
- } else if (res.op == UserOperation.CreatePostLike) {
- const data = res.data as PostResponse;
- createPostLikeFindRes(data, this.state.userRes.posts);
+ } else if (op == UserOperation.CreatePostLike) {
+ let data = wsJsonToRes<PostResponse>(msg).data;
+ createPostLikeFindRes(data.post_view, this.state.userRes.posts);
this.setState(this.state);
- } else if (res.op == UserOperation.BanUser) {
- const data = res.data as BanUserResponse;
+ } else if (op == UserOperation.BanUser) {
+ let data = wsJsonToRes<BanUserResponse>(msg).data;
this.state.userRes.comments
- .filter(c => c.creator_id == data.user.id)
- .forEach(c => (c.banned = data.banned));
+ .filter(c => c.creator.id == data.user_view.user.id)
+ .forEach(c => (c.creator.banned = data.banned));
this.state.userRes.posts
- .filter(c => c.creator_id == data.user.id)
- .forEach(c => (c.banned = data.banned));
+ .filter(c => c.creator.id == data.user_view.user.id)
+ .forEach(c => (c.creator.banned = data.banned));
this.setState(this.state);
}
}
-import { GetSiteResponse, LemmyHttp } from 'lemmy-js-client';
+import {
+ CommentView,
+ GetSiteResponse,
+ LemmyHttp,
+ UserMentionView,
+} from 'lemmy-js-client';
export interface IsoData {
path: string;
routeData: any[];
- site: GetSiteResponse;
+ site_res: GetSiteResponse;
// Lang and theme
lang: string;
// communities?: ListCommunitiesResponse;
client: LemmyHttp;
}
+export interface CommentNode {
+ comment_view: CommentView | UserMentionView;
+ children?: CommentNode[];
+ depth?: number;
+}
+
+export interface PostFormParams {
+ name: string;
+ url?: string;
+ body?: string;
+ community_name?: string;
+ community_id?: number;
+}
+
export enum CommentSortType {
Hot,
Top,
// import Cookies from 'js-cookie';
import IsomorphicCookie from 'isomorphic-cookie';
-import { User, LoginResponse } from 'lemmy-js-client';
+import { User_, LoginResponse } from 'lemmy-js-client';
import jwt_decode from 'jwt-decode';
import { Subject, BehaviorSubject } from 'rxjs';
+import { i18n } from '../i18next';
+import { toast } from '../utils';
interface Claims {
id: number;
export class UserService {
private static _instance: UserService;
- public user: User;
+ public user: User_;
public claims: Claims;
public jwtSub: Subject<string> = new Subject<string>();
public unreadCountSub: BehaviorSubject<number> = new BehaviorSubject<number>(
return IsomorphicCookie.load('jwt');
}
+ public authField(throwErr: boolean = true): string {
+ if (this.auth == null && throwErr) {
+ toast(i18n.t('not_logged_in'), 'danger');
+ throw 'Not logged in';
+ } else {
+ return this.auth;
+ }
+ }
+
private setClaims(jwt: string) {
this.claims = jwt_decode(jwt);
this.jwtSub.next(jwt);
import { wsUri } from '../env';
import {
LemmyWebsocket,
- LoginForm,
- RegisterForm,
- CommunityForm,
- DeleteCommunityForm,
- RemoveCommunityForm,
- PostForm,
- DeletePostForm,
- RemovePostForm,
- LockPostForm,
- StickyPostForm,
- SavePostForm,
- CommentForm,
- DeleteCommentForm,
- RemoveCommentForm,
- MarkCommentAsReadForm,
- SaveCommentForm,
- CommentLikeForm,
- GetPostForm,
- GetPostsForm,
- CreatePostLikeForm,
- GetCommunityForm,
- FollowCommunityForm,
- GetFollowedCommunitiesForm,
- GetUserDetailsForm,
- ListCommunitiesForm,
- GetModlogForm,
- BanFromCommunityForm,
- AddModToCommunityForm,
- TransferCommunityForm,
- AddAdminForm,
- TransferSiteForm,
- BanUserForm,
- SiteForm,
- UserView,
- GetRepliesForm,
- GetUserMentionsForm,
- MarkUserMentionAsReadForm,
- SearchForm,
- UserSettingsForm,
- DeleteAccountForm,
- PasswordResetForm,
- PasswordChangeForm,
- PrivateMessageForm,
- EditPrivateMessageForm,
- DeletePrivateMessageForm,
- MarkPrivateMessageAsReadForm,
- GetPrivateMessagesForm,
- GetCommentsForm,
- UserJoinForm,
- GetSiteConfig,
- GetSiteForm,
- SiteConfigForm,
- MarkAllAsReadForm,
+ UserViewSafe,
WebSocketJsonResponse,
- CommunityJoinForm,
- PostJoinForm,
} from 'lemmy-js-client';
-import { UserService } from './';
-import { i18n } from '../i18next';
-import { toast, isBrowser } from '../utils';
+import { isBrowser } from '../utils';
import { Observable } from 'rxjs';
import { share } from 'rxjs/operators';
import {
};
public subject: Observable<any>;
- public admins: UserView[];
- public banned: UserView[];
- private client = new LemmyWebsocket();
+ public admins: UserViewSafe[];
+ public banned: UserViewSafe[];
+ public client = new LemmyWebsocket();
private constructor() {
this.ws = new ReconnectingWebSocket(wsUri, [], this.wsOptions);
console.log(`Connected to ${wsUri}`);
if (!firstConnect) {
- let res: WebSocketJsonResponse = {
+ let res: WebSocketJsonResponse<any> = {
reconnect: true,
};
obs.next(res);
public static get Instance() {
return this._instance || (this._instance = new this());
}
-
- public userJoin() {
- let form: UserJoinForm = { auth: UserService.Instance.auth };
- this.ws.send(this.client.userJoin(form));
- }
-
- public postJoin(form: PostJoinForm) {
- this.ws.send(this.client.postJoin(form));
- }
-
- public communityJoin(form: CommunityJoinForm) {
- this.ws.send(this.client.communityJoin(form));
- }
-
- public login(form: LoginForm) {
- this.ws.send(this.client.login(form));
- }
-
- public register(form: RegisterForm) {
- this.ws.send(this.client.register(form));
- }
-
- public getCaptcha() {
- this.ws.send(this.client.getCaptcha());
- }
-
- public createCommunity(form: CommunityForm) {
- this.setAuth(form); // TODO all these setauths at some point would be good to make required
- this.ws.send(this.client.createCommunity(form));
- }
-
- public editCommunity(form: CommunityForm) {
- this.setAuth(form);
- this.ws.send(this.client.editCommunity(form));
- }
-
- public deleteCommunity(form: DeleteCommunityForm) {
- this.setAuth(form);
- this.ws.send(this.client.deleteCommunity(form));
- }
-
- public removeCommunity(form: RemoveCommunityForm) {
- this.setAuth(form);
- this.ws.send(this.client.removeCommunity(form));
- }
-
- public followCommunity(form: FollowCommunityForm) {
- this.setAuth(form);
- this.ws.send(this.client.followCommunity(form));
- }
-
- public listCommunities(form: ListCommunitiesForm) {
- this.setAuth(form, false);
- this.ws.send(this.client.listCommunities(form));
- }
-
- public getFollowedCommunities() {
- let form: GetFollowedCommunitiesForm = { auth: UserService.Instance.auth };
- this.ws.send(this.client.getFollowedCommunities(form));
- }
-
- public listCategories() {
- this.ws.send(this.client.listCategories());
- }
-
- public createPost(form: PostForm) {
- this.setAuth(form);
- this.ws.send(this.client.createPost(form));
- }
-
- public getPost(form: GetPostForm) {
- this.setAuth(form, false);
- this.ws.send(this.client.getPost(form));
- }
-
- public getCommunity(form: GetCommunityForm) {
- this.setAuth(form, false);
- this.ws.send(this.client.getCommunity(form));
- }
-
- public createComment(form: CommentForm) {
- this.setAuth(form);
- this.ws.send(this.client.createComment(form));
- }
-
- public editComment(form: CommentForm) {
- this.setAuth(form);
- this.ws.send(this.client.editComment(form));
- }
-
- public deleteComment(form: DeleteCommentForm) {
- this.setAuth(form);
- this.ws.send(this.client.deleteComment(form));
- }
-
- public removeComment(form: RemoveCommentForm) {
- this.setAuth(form);
- this.ws.send(this.client.removeComment(form));
- }
-
- public markCommentAsRead(form: MarkCommentAsReadForm) {
- this.setAuth(form);
- this.ws.send(this.client.markCommentAsRead(form));
- }
-
- public likeComment(form: CommentLikeForm) {
- this.setAuth(form);
- this.ws.send(this.client.likeComment(form));
- }
-
- public saveComment(form: SaveCommentForm) {
- this.setAuth(form);
- this.ws.send(this.client.saveComment(form));
- }
-
- public getPosts(form: GetPostsForm) {
- this.setAuth(form, false);
- this.ws.send(this.client.getPosts(form));
- }
-
- public getComments(form: GetCommentsForm) {
- this.setAuth(form, false);
- this.ws.send(this.client.getComments(form));
- }
-
- public likePost(form: CreatePostLikeForm) {
- this.setAuth(form);
- this.ws.send(this.client.likePost(form));
- }
-
- public editPost(form: PostForm) {
- this.setAuth(form);
- this.ws.send(this.client.editPost(form));
- }
-
- public deletePost(form: DeletePostForm) {
- this.setAuth(form);
- this.ws.send(this.client.deletePost(form));
- }
-
- public removePost(form: RemovePostForm) {
- this.setAuth(form);
- this.ws.send(this.client.removePost(form));
- }
-
- public lockPost(form: LockPostForm) {
- this.setAuth(form);
- this.ws.send(this.client.lockPost(form));
- }
-
- public stickyPost(form: StickyPostForm) {
- this.setAuth(form);
- this.ws.send(this.client.stickyPost(form));
- }
-
- public savePost(form: SavePostForm) {
- this.setAuth(form);
- this.ws.send(this.client.savePost(form));
- }
-
- public banFromCommunity(form: BanFromCommunityForm) {
- this.setAuth(form);
- this.ws.send(this.client.banFromCommunity(form));
- }
-
- public addModToCommunity(form: AddModToCommunityForm) {
- this.setAuth(form);
- this.ws.send(this.client.addModToCommunity(form));
- }
-
- public transferCommunity(form: TransferCommunityForm) {
- this.setAuth(form);
- this.ws.send(this.client.transferCommunity(form));
- }
-
- public transferSite(form: TransferSiteForm) {
- this.setAuth(form);
- this.ws.send(this.client.transferSite(form));
- }
-
- public banUser(form: BanUserForm) {
- this.setAuth(form);
- this.ws.send(this.client.banUser(form));
- }
-
- public addAdmin(form: AddAdminForm) {
- this.setAuth(form);
- this.ws.send(this.client.addAdmin(form));
- }
-
- public getUserDetails(form: GetUserDetailsForm) {
- this.setAuth(form, false);
- this.ws.send(this.client.getUserDetails(form));
- }
-
- public getReplies(form: GetRepliesForm) {
- this.setAuth(form);
- this.ws.send(this.client.getReplies(form));
- }
-
- public getUserMentions(form: GetUserMentionsForm) {
- this.setAuth(form);
- this.ws.send(this.client.getUserMentions(form));
- }
-
- public markUserMentionAsRead(form: MarkUserMentionAsReadForm) {
- this.setAuth(form);
- this.ws.send(this.client.markUserMentionAsRead(form));
- }
-
- public getModlog(form: GetModlogForm) {
- this.ws.send(this.client.getModlog(form));
- }
-
- public createSite(form: SiteForm) {
- this.setAuth(form);
- this.ws.send(this.client.createSite(form));
- }
-
- public editSite(form: SiteForm) {
- this.setAuth(form);
- this.ws.send(this.client.editSite(form));
- }
-
- public getSite(form: GetSiteForm = {}) {
- this.setAuth(form, false);
- this.ws.send(this.client.getSite(form));
- }
-
- public getSiteConfig() {
- let form: GetSiteConfig = {};
- this.setAuth(form);
- this.ws.send(this.client.getSiteConfig(form));
- }
-
- public search(form: SearchForm) {
- this.setAuth(form, false);
- this.ws.send(this.client.search(form));
- }
-
- public markAllAsRead() {
- let form: MarkAllAsReadForm = { auth: null };
- this.setAuth(form);
- this.ws.send(this.client.markAllAsRead(form));
- }
-
- public saveUserSettings(form: UserSettingsForm) {
- this.setAuth(form);
- this.ws.send(this.client.saveUserSettings(form));
- }
-
- public deleteAccount(form: DeleteAccountForm) {
- this.setAuth(form);
- this.ws.send(this.client.deleteAccount(form));
- }
-
- public passwordReset(form: PasswordResetForm) {
- this.ws.send(this.client.passwordReset(form));
- }
-
- public passwordChange(form: PasswordChangeForm) {
- this.ws.send(this.client.passwordChange(form));
- }
-
- public createPrivateMessage(form: PrivateMessageForm) {
- this.setAuth(form);
- this.ws.send(this.client.createPrivateMessage(form));
- }
-
- public editPrivateMessage(form: EditPrivateMessageForm) {
- this.setAuth(form);
- this.ws.send(this.client.editPrivateMessage(form));
- }
-
- public deletePrivateMessage(form: DeletePrivateMessageForm) {
- this.setAuth(form);
- this.ws.send(this.client.deletePrivateMessage(form));
- }
-
- public markPrivateMessageAsRead(form: MarkPrivateMessageAsReadForm) {
- this.setAuth(form);
- this.ws.send(this.client.markPrivateMessageAsRead(form));
- }
-
- public getPrivateMessages(form: GetPrivateMessagesForm) {
- this.setAuth(form);
- this.ws.send(this.client.getPrivateMessages(form));
- }
-
- public saveSiteConfig(form: SiteConfigForm) {
- this.setAuth(form);
- this.ws.send(this.client.saveSiteConfig(form));
- }
-
- public setAuth(obj: any, throwErr: boolean = true) {
- obj.auth = UserService.Instance.auth;
- if (obj.auth == null && throwErr) {
- toast(i18n.t('not_logged_in'), 'danger');
- throw 'Not logged in';
- }
- }
}
if (isBrowser()) {
import {
UserOperation,
- Comment,
- CommentNode as CommentNodeI,
- Post,
- PrivateMessage,
- User,
+ CommentView,
+ User_,
SortType,
ListingType,
SearchType,
WebSocketResponse,
WebSocketJsonResponse,
- SearchForm,
+ Search,
SearchResponse,
- CommentResponse,
- PostResponse,
+ PostView,
+ PrivateMessageView,
} from 'lemmy-js-client';
-import { CommentSortType, DataType, IsoData } from './interfaces';
+import {
+ CommentSortType,
+ DataType,
+ IsoData,
+ CommentNode as CommentNodeI,
+} from './interfaces';
import { UserService, WebSocketService } from './services';
var Tribute;
.join('');
}
-export function wsJsonToRes(msg: WebSocketJsonResponse): WebSocketResponse {
- let opStr: string = msg.op;
+export function wsJsonToRes<ResponseType>(
+ msg: WebSocketJsonResponse<ResponseType>
+): WebSocketResponse<ResponseType> {
return {
- op: UserOperation[opStr],
+ op: wsUserOp(msg),
data: msg.data,
};
}
+export function wsUserOp(msg: any): UserOperation {
+ let opStr: string = msg.op;
+ return UserOperation[opStr];
+}
+
export const md = new markdown_it({
html: false,
linkify: true,
defs: objectFlip(emojiShortName),
});
-export function hotRankComment(comment: Comment): number {
- return hotRank(comment.score, comment.published);
+export function hotRankComment(comment_view: CommentView): number {
+ return hotRank(comment_view.counts.score, comment_view.comment.published);
+}
+
+export function hotRankActivePost(post_view: PostView): number {
+ return hotRank(post_view.counts.score, post_view.counts.newest_comment_time);
}
-export function hotRankPost(post: Post): number {
- return hotRank(post.score, post.newest_activity_time);
+export function hotRankPost(post_view: PostView): number {
+ return hotRank(post_view.counts.score, post_view.post.published);
}
export function hotRank(score: number, timeStr: string): number {
return text ? new Date(text).getTime() / 1000 : undefined;
}
-export function addTypeInfo<T>(
- arr: T[],
- name: string
-): { type_: string; data: T }[] {
- return arr.map(e => {
- return { type_: name, data: e };
- });
-}
-
export function canMod(
- user: User,
+ user: User_,
modIds: number[],
creator_id: number,
onSelf: boolean = false
);
}
-export function isCommentType(
- item: Comment | PrivateMessage | Post
-): item is Comment {
- return (
- (item as Comment).community_id !== undefined &&
- (item as Comment).content !== undefined
- );
-}
-
-export function isPostType(
- item: Comment | PrivateMessage | Post
-): item is Post {
- return (item as Post).stickied !== undefined;
-}
-
export function toast(text: string, background: string = 'success') {
if (isBrowser()) {
let backgroundColor = `var(--${background})`;
}
}
-export function notifyPost(post: Post, router: any) {
+export function notifyPost(post_view: PostView, router: any) {
let info: NotifyInfo = {
- name: post.community_name,
- icon: post.community_icon ? post.community_icon : defaultFavIcon,
- link: `/post/${post.id}`,
- body: post.name,
+ name: post_view.community.name,
+ icon: post_view.community.icon ? post_view.community.icon : defaultFavIcon,
+ link: `/post/${post_view.post.id}`,
+ body: post_view.post.name,
};
notify(info, router);
}
-export function notifyComment(comment: Comment, router: any) {
+export function notifyComment(comment_view: CommentView, router: any) {
let info: NotifyInfo = {
- name: comment.creator_name,
- icon: comment.creator_avatar ? comment.creator_avatar : defaultFavIcon,
- link: `/post/${comment.post_id}/comment/${comment.id}`,
- body: comment.content,
+ name: comment_view.creator.name,
+ icon: comment_view.creator.avatar
+ ? comment_view.creator.avatar
+ : defaultFavIcon,
+ link: `/post/${comment_view.post.id}/comment/${comment_view.comment.id}`,
+ body: comment_view.comment.content,
};
notify(info, router);
}
-export function notifyPrivateMessage(pm: PrivateMessage, router: any) {
+export function notifyPrivateMessage(pmv: PrivateMessageView, router: any) {
let info: NotifyInfo = {
- name: pm.creator_name,
- icon: pm.creator_avatar ? pm.creator_avatar : defaultFavIcon,
+ name: pmv.creator.name,
+ icon: pmv.creator.avatar ? pmv.creator.avatar : defaultFavIcon,
link: `/inbox`,
- body: pm.content,
+ body: pmv.private_message.content,
};
notify(info, router);
}
function userSearch(text: string, cb: any) {
if (text) {
- let form: SearchForm = {
+ let form: Search = {
q: text,
type_: SearchType.Users,
sort: SortType.TopAll,
page: 1,
limit: mentionDropdownFetchLimit,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.search(form);
+ WebSocketService.Instance.client.search(form);
let userSub = WebSocketService.Instance.subject.subscribe(
msg => {
let res = wsJsonToRes(msg);
if (res.op == UserOperation.Search) {
let data = res.data as SearchResponse;
- let users = data.users.map(u => {
+ let users = data.users.map(uv => {
return {
- key: `@${u.name}@${hostname(u.actor_id)}`,
- name: u.name,
- local: u.local,
- id: u.id,
+ key: `@${uv.user.name}@${hostname(uv.user.actor_id)}`,
+ name: uv.user.name,
+ local: uv.user.local,
+ id: uv.user.id,
};
});
cb(users);
function communitySearch(text: string, cb: any) {
if (text) {
- let form: SearchForm = {
+ let form: Search = {
q: text,
type_: SearchType.Communities,
sort: SortType.TopAll,
page: 1,
limit: mentionDropdownFetchLimit,
+ auth: UserService.Instance.authField(false),
};
- WebSocketService.Instance.search(form);
+ WebSocketService.Instance.client.search(form);
let communitySub = WebSocketService.Instance.subject.subscribe(
msg => {
let res = wsJsonToRes(msg);
if (res.op == UserOperation.Search) {
let data = res.data as SearchResponse;
- let communities = data.communities.map(c => {
+ let communities = data.communities.map(cv => {
return {
- key: `!${c.name}@${hostname(c.actor_id)}`,
- name: c.name,
- local: c.local,
- id: c.id,
+ key: `!${cv.community.name}@${hostname(cv.community.actor_id)}`,
+ name: cv.community.name,
+ local: cv.community.local,
+ id: cv.community.id,
};
});
cb(communities);
return props.match.params.username;
}
-export function editCommentRes(data: CommentResponse, comments: Comment[]) {
- let found = comments.find(c => c.id == data.comment.id);
+export function editCommentRes(data: CommentView, comments: CommentView[]) {
+ let found = comments.find(c => c.comment.id == data.comment.id);
if (found) {
- found.content = data.comment.content;
- found.updated = data.comment.updated;
- found.removed = data.comment.removed;
- found.deleted = data.comment.deleted;
- found.upvotes = data.comment.upvotes;
- found.downvotes = data.comment.downvotes;
- found.score = data.comment.score;
+ found.comment.content = data.comment.content;
+ found.comment.updated = data.comment.updated;
+ found.comment.removed = data.comment.removed;
+ found.comment.deleted = data.comment.deleted;
+ found.counts.upvotes = data.counts.upvotes;
+ found.counts.downvotes = data.counts.downvotes;
+ found.counts.score = data.counts.score;
}
}
-export function saveCommentRes(data: CommentResponse, comments: Comment[]) {
- let found = comments.find(c => c.id == data.comment.id);
+export function saveCommentRes(data: CommentView, comments: CommentView[]) {
+ let found = comments.find(c => c.comment.id == data.comment.id);
if (found) {
- found.saved = data.comment.saved;
+ found.saved = data.saved;
}
}
export function createCommentLikeRes(
- data: CommentResponse,
- comments: Comment[]
+ data: CommentView,
+ comments: CommentView[]
) {
- let found: Comment = comments.find(c => c.id === data.comment.id);
+ let found = comments.find(c => c.comment.id === data.comment.id);
if (found) {
- found.score = data.comment.score;
- found.upvotes = data.comment.upvotes;
- found.downvotes = data.comment.downvotes;
- if (data.comment.my_vote !== null) {
- found.my_vote = data.comment.my_vote;
+ found.counts.score = data.counts.score;
+ found.counts.upvotes = data.counts.upvotes;
+ found.counts.downvotes = data.counts.downvotes;
+ if (data.my_vote !== null) {
+ found.my_vote = data.my_vote;
}
}
}
-export function createPostLikeFindRes(data: PostResponse, posts: Post[]) {
- let found = posts.find(c => c.id == data.post.id);
+export function createPostLikeFindRes(data: PostView, posts: PostView[]) {
+ let found = posts.find(p => p.post.id == data.post.id);
if (found) {
createPostLikeRes(data, found);
}
}
-export function createPostLikeRes(data: PostResponse, post: Post) {
- if (post) {
- post.score = data.post.score;
- post.upvotes = data.post.upvotes;
- post.downvotes = data.post.downvotes;
- if (data.post.my_vote !== null) {
- post.my_vote = data.post.my_vote;
+export function createPostLikeRes(data: PostView, post_view: PostView) {
+ if (post_view) {
+ post_view.counts.score = data.counts.score;
+ post_view.counts.upvotes = data.counts.upvotes;
+ post_view.counts.downvotes = data.counts.downvotes;
+ if (data.my_vote !== null) {
+ post_view.my_vote = data.my_vote;
}
}
}
-export function editPostFindRes(data: PostResponse, posts: Post[]) {
- let found = posts.find(c => c.id == data.post.id);
+export function editPostFindRes(data: PostView, posts: PostView[]) {
+ let found = posts.find(p => p.post.id == data.post.id);
if (found) {
editPostRes(data, found);
}
}
-export function editPostRes(data: PostResponse, post: Post) {
+export function editPostRes(data: PostView, post: PostView) {
if (post) {
- post.url = data.post.url;
- post.name = data.post.name;
- post.nsfw = data.post.nsfw;
- post.deleted = data.post.deleted;
- post.removed = data.post.removed;
- post.stickied = data.post.stickied;
- post.body = data.post.body;
- post.locked = data.post.locked;
- post.saved = data.post.saved;
+ post.post.url = data.post.url;
+ post.post.name = data.post.name;
+ post.post.nsfw = data.post.nsfw;
+ post.post.deleted = data.post.deleted;
+ post.post.removed = data.post.removed;
+ post.post.stickied = data.post.stickied;
+ post.post.body = data.post.body;
+ post.post.locked = data.post.locked;
+ post.saved = data.saved;
}
}
-export function commentsToFlatNodes(comments: Comment[]): CommentNodeI[] {
+export function commentsToFlatNodes(comments: CommentView[]): CommentNodeI[] {
let nodes: CommentNodeI[] = [];
for (let comment of comments) {
- nodes.push({ comment: comment });
+ nodes.push({ comment_view: comment });
}
return nodes;
}
if (sort == CommentSortType.Top) {
tree.sort(
(a, b) =>
- +a.comment.removed - +b.comment.removed ||
- +a.comment.deleted - +b.comment.deleted ||
- b.comment.score - a.comment.score
+ +a.comment_view.comment.removed - +b.comment_view.comment.removed ||
+ +a.comment_view.comment.deleted - +b.comment_view.comment.deleted ||
+ b.comment_view.counts.score - a.comment_view.counts.score
);
} else if (sort == CommentSortType.New) {
tree.sort(
(a, b) =>
- +a.comment.removed - +b.comment.removed ||
- +a.comment.deleted - +b.comment.deleted ||
- b.comment.published.localeCompare(a.comment.published)
+ +a.comment_view.comment.removed - +b.comment_view.comment.removed ||
+ +a.comment_view.comment.deleted - +b.comment_view.comment.deleted ||
+ b.comment_view.comment.published.localeCompare(
+ a.comment_view.comment.published
+ )
);
} else if (sort == CommentSortType.Old) {
tree.sort(
(a, b) =>
- +a.comment.removed - +b.comment.removed ||
- +a.comment.deleted - +b.comment.deleted ||
- a.comment.published.localeCompare(b.comment.published)
+ +a.comment_view.comment.removed - +b.comment_view.comment.removed ||
+ +a.comment_view.comment.deleted - +b.comment_view.comment.deleted ||
+ a.comment_view.comment.published.localeCompare(
+ b.comment_view.comment.published
+ )
);
} else if (sort == CommentSortType.Hot) {
tree.sort(
(a, b) =>
- +a.comment.removed - +b.comment.removed ||
- +a.comment.deleted - +b.comment.deleted ||
- hotRankComment(b.comment) - hotRankComment(a.comment)
+ +a.comment_view.comment.removed - +b.comment_view.comment.removed ||
+ +a.comment_view.comment.deleted - +b.comment_view.comment.deleted ||
+ hotRankComment(b.comment_view) - hotRankComment(a.comment_view)
);
}
}
export function postSort(
- posts: Post[],
+ posts: PostView[],
sort: SortType,
communityType: boolean
) {
) {
posts.sort(
(a, b) =>
- +a.removed - +b.removed ||
- +a.deleted - +b.deleted ||
- (communityType && +b.stickied - +a.stickied) ||
- b.score - a.score
+ +a.post.removed - +b.post.removed ||
+ +a.post.deleted - +b.post.deleted ||
+ (communityType && +b.post.stickied - +a.post.stickied) ||
+ b.counts.score - a.counts.score
);
} else if (sort == SortType.New) {
posts.sort(
(a, b) =>
- +a.removed - +b.removed ||
- +a.deleted - +b.deleted ||
- (communityType && +b.stickied - +a.stickied) ||
- b.published.localeCompare(a.published)
+ +a.post.removed - +b.post.removed ||
+ +a.post.deleted - +b.post.deleted ||
+ (communityType && +b.post.stickied - +a.post.stickied) ||
+ b.post.published.localeCompare(a.post.published)
);
} else if (sort == SortType.Hot) {
posts.sort(
(a, b) =>
- +a.removed - +b.removed ||
- +a.deleted - +b.deleted ||
- (communityType && +b.stickied - +a.stickied) ||
- b.hot_rank - a.hot_rank
+ +a.post.removed - +b.post.removed ||
+ +a.post.deleted - +b.post.deleted ||
+ (communityType && +b.post.stickied - +a.post.stickied) ||
+ hotRankPost(b) - hotRankPost(a)
);
} else if (sort == SortType.Active) {
posts.sort(
(a, b) =>
- +a.removed - +b.removed ||
- +a.deleted - +b.deleted ||
- (communityType && +b.stickied - +a.stickied) ||
- b.hot_rank_active - a.hot_rank_active
+ +a.post.removed - +b.post.removed ||
+ +a.post.deleted - +b.post.deleted ||
+ (communityType && +b.post.stickied - +a.post.stickied) ||
+ hotRankActivePost(b) - hotRankActivePost(a)
);
}
}
return typeof window !== 'undefined';
}
-export function setAuth(obj: any, auth: string) {
- if (auth) {
- obj.auth = auth;
- }
-}
-
export function setIsoData(context: any): IsoData {
let isoData: IsoData = isBrowser()
? window.isoData
dependencies:
invert-kv "^1.0.0"
-lemmy-js-client@^1.0.16:
- version "1.0.16"
- resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-1.0.16.tgz#84bf094c246d987f2f192bfac75340430821fee9"
- integrity sha512-WvEEGrYNA2dzfzlufWB9LhUcll0O06WaUjSfBn5lYY/SFFsvBW5ImD42P/QwvN8Sgj6xVQiboe+Z8T++iAjKVw==
+lemmy-js-client@1.0.17-beta5:
+ version "1.0.17-beta5"
+ resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-1.0.17-beta5.tgz#b8d128ef3a6a17bc3ac4eea8e30618b68ea4f2df"
+ integrity sha512-Z/8HV8tG9aB75GjDX1U2b3pFZnysGIymeVO+oepOkYfhHRB8SKmLS9ATuIw9OW1NjJduxbpGGgDH+bkf0Sx7dA==
leven@^3.1.0:
version "3.1.0"