diff --git a/.drone.yml b/.drone.yml index 61525604..64871add 100644 --- a/.drone.yml +++ b/.drone.yml @@ -78,6 +78,9 @@ steps: - apk add git - git submodule init - git submodule update --recursive --remote + when: + ref: + - refs/tags/* - name: make release build and push to docker hub image: plugins/docker diff --git a/generate_translations.js b/generate_translations.js index 0cab8e36..594f574c 100644 --- a/generate_translations.js +++ b/generate_translations.js @@ -1,27 +1,68 @@ -fs = require('fs'); +const fs = require("fs"); -let translationDir = 'lemmy-translations/translations/'; -let outDir = 'src/shared/translations/'; +const translationDir = "lemmy-translations/translations/"; +const outDir = "src/shared/translations/"; fs.mkdirSync(outDir, { recursive: true }); fs.readdir(translationDir, (_err, files) => { files.forEach(filename => { - const lang = filename.split('.')[0]; + const lang = filename.split(".")[0]; try { const json = JSON.parse( - fs.readFileSync(translationDir + filename, 'utf8') + fs.readFileSync(translationDir + filename, "utf8") ); - var data = `export const ${lang} = {\n translation: {`; - for (var key in json) { + let data = `export const ${lang} = {\n translation: {`; + for (const key in json) { if (key in json) { const value = json[key].replace(/"/g, '\\"'); - data = `${data}\n ${key}: "${value}",`; + data += `\n ${key}: "${value}",`; } } - data += '\n },\n};'; - const target = outDir + lang + '.ts'; + data += "\n },\n};"; + const target = outDir + lang + ".ts"; fs.writeFileSync(target, data); } catch (err) { console.error(err); } }); }); + +// generate types for i18n keys +const baseLanguage = "en"; + +fs.readFile(`${translationDir}${baseLanguage}.json`, "utf8", (_, fileStr) => { + const keys = Object.keys(JSON.parse(fileStr)); + + const data = `import { i18n } from "i18next"; + +declare module "i18next" { + export type I18nKeys = +${keys.map(key => ` | "${key}"`).join("\n")}; + + export interface TFunctionTyped { + // basic usage + < + TResult extends TFunctionResult = string, + TInterpolationMap extends Record = StringMap + >( + key: I18nKeys | I18nKeys[], + options?: TOptions | string + ): TResult; + // overloaded usage + < + TResult extends TFunctionResult = string, + TInterpolationMap extends Record = StringMap + >( + key: I18nKeys | I18nKeys[], + defaultValue?: string, + options?: TOptions | string + ): TResult; + } + + export interface i18nTyped extends i18n { + t: TFunctionTyped; + } +} +`; + + fs.writeFileSync(`${outDir}i18next.d.ts`, data); +}); diff --git a/lemmy-translations b/lemmy-translations index 6171d85e..ebb1c594 160000 --- a/lemmy-translations +++ b/lemmy-translations @@ -1 +1 @@ -Subproject commit 6171d85e4cc9249356f75739aebf319d49ec3889 +Subproject commit ebb1c594cd6ae91fa65c7f305c61f318eb10125f diff --git a/package.json b/package.json index e427117a..3047b610 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,8 @@ "eslint": "^7.20.0", "eslint-plugin-prettier": "^3.3.1", "husky": "^5.1.0", - "lemmy-js-client": "0.9.9", + "iso-639-1": "^2.1.9", + "lemmy-js-client": "0.10.0-rc.10", "lint-staged": "^10.5.4", "mini-css-extract-plugin": "^1.3.8", "node-fetch": "^2.6.1", diff --git a/src/assets/css/main.css b/src/assets/css/main.css index 36f022b8..5f67199e 100644 --- a/src/assets/css/main.css +++ b/src/assets/css/main.css @@ -228,17 +228,20 @@ hr { height: 1.5em; width: 1.5em; background: rgba(0, 0, 0, 0.4); + background-color: rgba(0, 0, 0, 0.4); border-bottom-left-radius: 0.25rem !important; border-top-right-radius: 0.25rem !important; } .link-overlay:hover { transition: 0.1s; + -webkit-transition: 0.1s; opacity: 1; } .link-overlay { transition: opacity 0.1s ease-in-out; + -webkit-transition: opacity 0.1s ease-in-out; position: absolute; opacity: 0; left: 0; @@ -246,6 +249,7 @@ hr { width: 100%; padding: 10px; background: rgba(0, 0, 0, 0.6); + background-color: rgba(0, 0, 0, 0.6); } .placeholder { @@ -285,6 +289,7 @@ pre { } .hide-input { background: transparent !important; + background-color: transparent !important; width: 0px !important; padding: 0 !important; } diff --git a/src/server/index.tsx b/src/server/index.tsx index bb0ac3ad..0dcd164a 100644 --- a/src/server/index.tsx +++ b/src/server/index.tsx @@ -12,7 +12,7 @@ import { } from "../shared/interfaces"; import { routes } from "../shared/routes"; import IsomorphicCookie from "isomorphic-cookie"; -import { GetSite, LemmyHttp } from "lemmy-js-client"; +import { GetSite, GetSiteResponse, LemmyHttp } from "lemmy-js-client"; import process from "process"; import { Helmet } from "inferno-helmet"; import { initializeSite } from "../shared/initialize"; @@ -48,7 +48,18 @@ server.get("/*", async (req, res) => { }; // Get site data first - let site = await initialFetchReq.client.getSite(getSiteForm); + // This bypasses errors, so that the client can hit the error on its own, + // in order to remove the jwt on the browser. Necessary for wrong jwts + let try_site: any = await initialFetchReq.client.getSite(getSiteForm); + if (try_site.error == "not_logged_in") { + console.error( + "Incorrect JWT token, skipping auth so frontend can remove jwt cookie" + ); + delete getSiteForm.auth; + delete initialFetchReq.auth; + try_site = await initialFetchReq.client.getSite(getSiteForm); + } + let site: GetSiteResponse = try_site; initializeSite(site); if (activeRoute.fetchInitialData) { @@ -67,7 +78,7 @@ server.get("/*", async (req, res) => { ? req.headers["accept-language"].split(",")[0] : "en"; let lang = site.my_user - ? site.my_user.lang == "browser" + ? site.my_user.local_user.lang == "browser" ? acceptLang : "en" : acceptLang; diff --git a/src/shared/components/admin-settings.tsx b/src/shared/components/admin-settings.tsx index accefe13..0836a16d 100644 --- a/src/shared/components/admin-settings.tsx +++ b/src/shared/components/admin-settings.tsx @@ -23,7 +23,7 @@ import { } from "../utils"; import autosize from "autosize"; import { SiteForm } from "./site-form"; -import { UserListing } from "./user-listing"; +import { PersonListing } from "./person-listing"; import { HtmlTags } from "./html-tags"; import { Spinner } from "./icon"; import { i18n } from "../i18next"; @@ -135,7 +135,7 @@ export class AdminSettings extends Component {
    {this.state.siteRes.admins.map(admin => (
  • - +
  • ))}
@@ -150,7 +150,7 @@ export class AdminSettings extends Component {
    {this.state.siteRes.banned.map(banned => (
  • - +
  • ))}
diff --git a/src/shared/components/app.tsx b/src/shared/components/app.tsx index 6f49e2cd..262e4b54 100644 --- a/src/shared/components/app.tsx +++ b/src/shared/components/app.tsx @@ -26,7 +26,7 @@ export class App extends Component { <>
- + {siteRes && siteRes.site_view && this.props.siteRes.site_view.site.icon && ( diff --git a/src/shared/components/comment-form.tsx b/src/shared/components/comment-form.tsx index 5c21b2dc..26775943 100644 --- a/src/shared/components/comment-form.tsx +++ b/src/shared/components/comment-form.tsx @@ -68,7 +68,7 @@ export class CommentForm extends Component { render() { return (
- {UserService.Instance.user ? ( + {UserService.Instance.localUserView ? ( { let op = wsUserOp(msg); // Only do the showing and hiding if logged in - if (UserService.Instance.user) { + if (UserService.Instance.localUserView) { if ( op == UserOperation.CreateComment || op == UserOperation.EditComment diff --git a/src/shared/components/comment-node.tsx b/src/shared/components/comment-node.tsx index 6b5fc0e2..c6ba1a5d 100644 --- a/src/shared/components/comment-node.tsx +++ b/src/shared/components/comment-node.tsx @@ -5,18 +5,18 @@ import { DeleteComment, RemoveComment, MarkCommentAsRead, - MarkUserMentionAsRead, + MarkPersonMentionAsRead, SaveComment, BanFromCommunity, - BanUser, + BanPerson, CommunityModeratorView, - UserViewSafe, + PersonViewSafe, AddModToCommunity, AddAdmin, TransferCommunity, TransferSite, CommentView, - UserMentionView, + PersonMentionView, } from "lemmy-js-client"; import { CommentNode as CommentNodeI, BanType } from "../interfaces"; import { WebSocketService, UserService } from "../services"; @@ -34,7 +34,7 @@ import moment from "moment"; import { MomentTime } from "./moment-time"; import { CommentForm } from "./comment-form"; import { CommentNodes } from "./comment-nodes"; -import { UserListing } from "./user-listing"; +import { PersonListing } from "./person-listing"; import { CommunityLink } from "./community-link"; import { Icon, Spinner } from "./icon"; import { i18n } from "../i18next"; @@ -74,7 +74,7 @@ interface CommentNodeProps { markable?: boolean; showContext?: boolean; moderators: CommunityModeratorView[]; - admins: UserViewSafe[]; + admins: PersonViewSafe[]; // TODO is this necessary, can't I get it from the node itself? postCreatorId?: number; showCommunity?: boolean; @@ -156,7 +156,7 @@ export class CommentNode extends Component { >
- + {this.isMod && ( @@ -270,7 +270,7 @@ export class CommentNode extends Component { )} )} - {UserService.Instance.user && !this.props.viewOnly && ( + {UserService.Instance.localUserView && !this.props.viewOnly && ( <>
-
- -
- -
-
{this.props.enableNsfw && (
@@ -304,11 +283,6 @@ export class CommunityForm extends Component< this.setState(this.state); } - handleCommunityCategoryChange(i: CommunityForm, event: any) { - i.state.communityForm.category_id = Number(event.target.value); - i.setState(i.state); - } - handleCommunityNsfwChange(i: CommunityForm, event: any) { i.state.communityForm.nsfw = event.target.checked; i.setState(i.state); diff --git a/src/shared/components/community.tsx b/src/shared/components/community.tsx index ef5c7833..bd603800 100644 --- a/src/shared/components/community.tsx +++ b/src/shared/components/community.tsx @@ -19,8 +19,6 @@ import { GetCommentsResponse, CommentResponse, GetSiteResponse, - Category, - ListCategoriesResponse, } from "lemmy-js-client"; import { UserService, WebSocketService } from "../services"; import { PostListings } from "./post-listings"; @@ -72,7 +70,6 @@ interface State { dataType: DataType; sort: SortType; page: number; - categories: Category[]; } interface CommunityProps { @@ -103,7 +100,6 @@ export class Community extends Component { sort: getSortTypeFromProps(this.props), page: getPageFromProps(this.props), siteRes: this.isoData.site_res, - categories: [], }; constructor(props: any, context: any) { @@ -124,14 +120,12 @@ export class Community extends Component { } else { this.state.comments = this.isoData.routeData[1].comments; } - this.state.categories = this.isoData.routeData[2].categories; this.state.communityLoading = false; this.state.postsLoading = false; this.state.commentsLoading = false; } else { this.fetchCommunity(); this.fetchData(); - WebSocketService.Instance.send(wsClient.listCategories()); } setupTippy(); } @@ -183,8 +177,10 @@ export class Community extends Component { let sort: SortType = pathSplit[6] ? SortType[pathSplit[6]] - : UserService.Instance.user - ? Object.values(SortType)[UserService.Instance.user.default_sort_type] + : UserService.Instance.localUserView + ? Object.values(SortType)[ + UserService.Instance.localUserView.local_user.default_sort_type + ] : SortType.Active; let page = pathSplit[8] ? Number(pathSplit[8]) : 1; @@ -195,6 +191,7 @@ export class Community extends Component { limit: fetchLimit, sort, type_: ListingType.Community, + saved_only: false, }; setOptionalAuth(getPostsForm, req.auth); this.setIdOrName(getPostsForm, id, name_); @@ -205,14 +202,13 @@ export class Community extends Component { limit: fetchLimit, sort, type_: ListingType.Community, + saved_only: false, }; setOptionalAuth(getCommentsForm, req.auth); this.setIdOrName(getCommentsForm, id, name_); promises.push(req.client.getComments(getCommentsForm)); } - promises.push(req.client.listCategories()); - return promises; } @@ -268,7 +264,6 @@ export class Community extends Component { admins={this.state.siteRes.admins} online={this.state.communityRes.online} enableNsfw={this.state.siteRes.site_view.site.enable_nsfw} - categories={this.state.categories} />
@@ -416,6 +411,7 @@ export class Community extends Component { type_: ListingType.Community, community_id: this.state.communityId, community_name: this.state.communityName, + saved_only: false, auth: authField(false), }; WebSocketService.Instance.send(wsClient.getPosts(form)); @@ -427,6 +423,7 @@ export class Community extends Component { type_: ListingType.Community, community_id: this.state.communityId, community_name: this.state.communityName, + saved_only: false, auth: authField(false), }; WebSocketService.Instance.send(wsClient.getComments(form)); @@ -508,7 +505,7 @@ export class Community extends Component { // TODO this might be incorrect this.state.posts - .filter(p => p.creator.id == data.user_view.user.id) + .filter(p => p.creator.id == data.person_view.person.id) .forEach(p => (p.creator_banned_from_community = data.banned)); this.setState(this.state); @@ -541,10 +538,6 @@ export class Community extends Component { let data = wsJsonToRes(msg).data; createCommentLikeRes(data.comment_view, this.state.comments); this.setState(this.state); - } else if (op == UserOperation.ListCategories) { - let data = wsJsonToRes(msg).data; - this.state.categories = data.categories; - this.setState(this.state); } } } diff --git a/src/shared/components/create-community.tsx b/src/shared/components/create-community.tsx index da449978..52c28330 100644 --- a/src/shared/components/create-community.tsx +++ b/src/shared/components/create-community.tsx @@ -3,29 +3,13 @@ import { Subscription } from "rxjs"; import { CommunityForm } from "./community-form"; import { HtmlTags } from "./html-tags"; import { Spinner } from "./icon"; -import { - CommunityView, - UserOperation, - SiteView, - ListCategoriesResponse, - Category, -} from "lemmy-js-client"; -import { - setIsoData, - toast, - wsJsonToRes, - wsSubscribe, - isBrowser, - wsUserOp, - wsClient, -} from "../utils"; -import { WebSocketService, UserService } from "../services"; +import { CommunityView, SiteView } from "lemmy-js-client"; +import { setIsoData, toast, wsSubscribe, isBrowser } from "../utils"; +import { UserService } from "../services"; import { i18n } from "../i18next"; -import { InitialFetchRequest } from "shared/interfaces"; interface CreateCommunityState { site_view: SiteView; - categories: Category[]; loading: boolean; } @@ -34,8 +18,7 @@ export class CreateCommunity extends Component { private subscription: Subscription; private emptyState: CreateCommunityState = { site_view: this.isoData.site_res.site_view, - categories: [], - loading: true, + loading: false, }; constructor(props: any, context: any) { super(props, context); @@ -45,18 +28,10 @@ export class CreateCommunity extends Component { this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); - if (!UserService.Instance.user && isBrowser()) { + if (!UserService.Instance.localUserView && isBrowser()) { toast(i18n.t("not_logged_in"), "danger"); this.context.router.history.push(`/login`); } - - // Only fetch the data if coming from another route - if (this.isoData.path == this.context.router.route.match.url) { - this.state.categories = this.isoData.routeData[0].categories; - this.state.loading = false; - } else { - WebSocketService.Instance.send(wsClient.listCategories()); - } } componentWillUnmount() { @@ -85,7 +60,6 @@ export class CreateCommunity extends Component {
{i18n.t("create_community")}
@@ -100,20 +74,10 @@ export class CreateCommunity extends Component { this.props.history.push(`/c/${cv.community.name}`); } - static fetchInitialData(req: InitialFetchRequest): Promise[] { - return [req.client.listCategories()]; - } - parseMessage(msg: any) { - let op = wsUserOp(msg); if (msg.error) { // Toast errors are already handled by community-form return; - } else if (op == UserOperation.ListCategories) { - let data = wsJsonToRes(msg).data; - this.state.categories = data.categories; - this.state.loading = false; - this.setState(this.state); } } } diff --git a/src/shared/components/create-post.tsx b/src/shared/components/create-post.tsx index 05295c6a..00221d6d 100644 --- a/src/shared/components/create-post.tsx +++ b/src/shared/components/create-post.tsx @@ -48,7 +48,7 @@ export class CreatePost extends Component { this.handlePostCreate = this.handlePostCreate.bind(this); this.state = this.emptyState; - if (!UserService.Instance.user && isBrowser()) { + if (!UserService.Instance.localUserView && isBrowser()) { toast(i18n.t("not_logged_in"), "danger"); this.context.router.history.push(`/login`); } diff --git a/src/shared/components/create-private-message.tsx b/src/shared/components/create-private-message.tsx index adbfdf78..3771da62 100644 --- a/src/shared/components/create-private-message.tsx +++ b/src/shared/components/create-private-message.tsx @@ -7,10 +7,10 @@ import { UserService, WebSocketService } from "../services"; import { SiteView, UserOperation, - GetUserDetailsResponse, - UserViewSafe, + GetPersonDetailsResponse, + PersonViewSafe, SortType, - GetUserDetails, + GetPersonDetails, } from "lemmy-js-client"; import { authField, @@ -28,7 +28,7 @@ import { InitialFetchRequest } from "shared/interfaces"; interface CreatePrivateMessageState { site_view: SiteView; - recipient: UserViewSafe; + recipient: PersonViewSafe; recipient_id: number; loading: boolean; } @@ -55,7 +55,7 @@ export class CreatePrivateMessage extends Component< this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); - if (!UserService.Instance.user) { + if (!UserService.Instance.localUserView) { toast(i18n.t("not_logged_in"), "danger"); this.context.router.history.push(`/login`); } @@ -65,29 +65,29 @@ export class CreatePrivateMessage extends Component< this.state.recipient = this.isoData.routeData[0].user; this.state.loading = false; } else { - this.fetchUserDetails(); + this.fetchPersonDetails(); } } - fetchUserDetails() { - let form: GetUserDetails = { - user_id: this.state.recipient_id, + fetchPersonDetails() { + let form: GetPersonDetails = { + person_id: this.state.recipient_id, sort: SortType.New, saved_only: false, auth: authField(false), }; - WebSocketService.Instance.send(wsClient.getUserDetails(form)); + WebSocketService.Instance.send(wsClient.getPersonDetails(form)); } static fetchInitialData(req: InitialFetchRequest): Promise[] { - let user_id = Number(req.path.split("/").pop()); - let form: GetUserDetails = { - user_id, + let person_id = Number(req.path.split("/").pop()); + let form: GetPersonDetails = { + person_id, sort: SortType.New, saved_only: false, auth: req.auth, }; - return [req.client.getUserDetails(form)]; + return [req.client.getPersonDetails(form)]; } get documentTitle(): string { @@ -119,7 +119,7 @@ export class CreatePrivateMessage extends Component<
{i18n.t("create_private_message")}
@@ -142,9 +142,9 @@ export class CreatePrivateMessage extends Component< this.state.loading = false; this.setState(this.state); return; - } else if (op == UserOperation.GetUserDetails) { - let data = wsJsonToRes(msg).data; - this.state.recipient = data.user_view; + } else if (op == UserOperation.GetPersonDetails) { + let data = wsJsonToRes(msg).data; + this.state.recipient = data.person_view; this.state.loading = false; this.setState(this.state); } diff --git a/src/shared/components/icon.tsx b/src/shared/components/icon.tsx index b3ddab9c..e3bd74aa 100644 --- a/src/shared/components/icon.tsx +++ b/src/shared/components/icon.tsx @@ -13,7 +13,9 @@ export class Icon extends Component { render() { return ( - {this.props.icon} +
+ {this.props.icon} +
); diff --git a/src/shared/components/image-upload-form.tsx b/src/shared/components/image-upload-form.tsx index fb9c9ca1..b8b94c22 100644 --- a/src/shared/components/image-upload-form.tsx +++ b/src/shared/components/image-upload-form.tsx @@ -65,7 +65,7 @@ export class ImageUploadForm extends Component< accept="image/*,video/*" name={this.id} class="d-none" - disabled={!UserService.Instance.user} + disabled={!UserService.Instance.localUserView} onChange={linkEvent(this, this.handleImageUpload)} /> diff --git a/src/shared/components/inbox.tsx b/src/shared/components/inbox.tsx index 5c7f7989..677d9051 100644 --- a/src/shared/components/inbox.tsx +++ b/src/shared/components/inbox.tsx @@ -6,16 +6,16 @@ import { SortType, GetReplies, GetRepliesResponse, - GetUserMentions, - GetUserMentionsResponse, - UserMentionResponse, + GetPersonMentions, + GetPersonMentionsResponse, + PersonMentionResponse, CommentResponse, PrivateMessageView, GetPrivateMessages, PrivateMessagesResponse, PrivateMessageResponse, SiteView, - UserMentionView, + PersonMentionView, } from "lemmy-js-client"; import { WebSocketService, UserService } from "../services"; import { @@ -62,7 +62,7 @@ enum ReplyEnum { type ReplyType = { id: number; type_: ReplyEnum; - view: CommentView | PrivateMessageView | UserMentionView; + view: CommentView | PrivateMessageView | PersonMentionView; published: string; }; @@ -70,7 +70,7 @@ interface InboxState { unreadOrAll: UnreadOrAll; messageType: MessageType; replies: CommentView[]; - mentions: UserMentionView[]; + mentions: PersonMentionView[]; messages: PrivateMessageView[]; combined: ReplyType[]; sort: SortType; @@ -101,7 +101,7 @@ export class Inbox extends Component { this.state = this.emptyState; this.handleSortChange = this.handleSortChange.bind(this); - if (!UserService.Instance.user && isBrowser()) { + if (!UserService.Instance.localUserView && isBrowser()) { toast(i18n.t("not_logged_in"), "danger"); this.context.router.history.push(`/login`); } @@ -128,9 +128,9 @@ export class Inbox extends Component { } get documentTitle(): string { - return `@${UserService.Instance.user.name} ${i18n.t("inbox")} - ${ - this.state.site_view.site.name - }`; + return `@${UserService.Instance.localUserView.person.name} ${i18n.t( + "inbox" + )} - ${this.state.site_view.site.name}`; } render() { @@ -307,9 +307,9 @@ export class Inbox extends Component { }; } - mentionToReplyType(r: UserMentionView): ReplyType { + mentionToReplyType(r: PersonMentionView): ReplyType { return { - id: r.user_mention.id, + id: r.person_mention.id, type_: ReplyEnum.Mention, view: r, published: r.comment.published, @@ -359,7 +359,7 @@ export class Inbox extends Component { return ( {
{this.state.mentions.map(umv => ( { }; promises.push(req.client.getReplies(repliesForm)); - let userMentionsForm: GetUserMentions = { + let personMentionsForm: GetPersonMentions = { sort: SortType.New, unread_only: true, page: 1, limit: fetchLimit, auth: req.auth, }; - promises.push(req.client.getUserMentions(userMentionsForm)); + promises.push(req.client.getPersonMentions(personMentionsForm)); let privateMessagesForm: GetPrivateMessages = { unread_only: true, @@ -521,14 +521,16 @@ export class Inbox extends Component { }; WebSocketService.Instance.send(wsClient.getReplies(repliesForm)); - let userMentionsForm: GetUserMentions = { + let personMentionsForm: GetPersonMentions = { sort: this.state.sort, unread_only: this.state.unreadOrAll == UnreadOrAll.Unread, page: this.state.page, limit: fetchLimit, auth: authField(), }; - WebSocketService.Instance.send(wsClient.getUserMentions(userMentionsForm)); + WebSocketService.Instance.send( + wsClient.getPersonMentions(personMentionsForm) + ); let privateMessagesForm: GetPrivateMessages = { unread_only: this.state.unreadOrAll == UnreadOrAll.Unread, @@ -579,8 +581,8 @@ export class Inbox extends Component { window.scrollTo(0, 0); this.setState(this.state); setupTippy(); - } else if (op == UserOperation.GetUserMentions) { - let data = wsJsonToRes(msg).data; + } else if (op == UserOperation.GetPersonMentions) { + let data = wsJsonToRes(msg).data; this.state.mentions = data.mentions; this.state.combined = this.buildCombined(); this.sendUnreadCount(); @@ -698,48 +700,49 @@ export class Inbox extends Component { this.sendUnreadCount(); this.setState(this.state); setupTippy(); - } else if (op == UserOperation.MarkUserMentionAsRead) { - let data = wsJsonToRes(msg).data; + } else if (op == UserOperation.MarkPersonMentionAsRead) { + let data = wsJsonToRes(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 + c => c.person_mention.id == data.person_mention_view.person_mention.id ); if (found) { let combinedView = this.state.combined.find( - i => i.id == data.user_mention_view.user_mention.id - ).view as UserMentionView; + i => i.id == data.person_mention_view.person_mention.id + ).view as PersonMentionView; found.comment.content = combinedView.comment.content = - data.user_mention_view.comment.content; + data.person_mention_view.comment.content; found.comment.updated = combinedView.comment.updated = - data.user_mention_view.comment.updated; + data.person_mention_view.comment.updated; found.comment.removed = combinedView.comment.removed = - data.user_mention_view.comment.removed; + data.person_mention_view.comment.removed; found.comment.deleted = combinedView.comment.deleted = - data.user_mention_view.comment.deleted; + data.person_mention_view.comment.deleted; found.counts.upvotes = combinedView.counts.upvotes = - data.user_mention_view.counts.upvotes; + data.person_mention_view.counts.upvotes; found.counts.downvotes = combinedView.counts.downvotes = - data.user_mention_view.counts.downvotes; + data.person_mention_view.counts.downvotes; found.counts.score = combinedView.counts.score = - data.user_mention_view.counts.score; + data.person_mention_view.counts.score; // If youre in the unread view, just remove it from the list if ( this.state.unreadOrAll == UnreadOrAll.Unread && - data.user_mention_view.user_mention.read + data.person_mention_view.person_mention.read ) { this.state.mentions = this.state.mentions.filter( - r => r.user_mention.id !== data.user_mention_view.user_mention.id + r => + r.person_mention.id !== data.person_mention_view.person_mention.id ); this.state.combined = this.state.combined.filter( - r => r.id !== data.user_mention_view.user_mention.id + r => r.id !== data.person_mention_view.person_mention.id ); } else { // TODO test to make sure these mentions are getting marked as read - found.user_mention.read = combinedView.user_mention.read = - data.user_mention_view.user_mention.read; + found.person_mention.read = combinedView.person_mention.read = + data.person_mention_view.person_mention.read; } } this.sendUnreadCount(); @@ -747,18 +750,26 @@ export class Inbox extends Component { } else if (op == UserOperation.CreateComment) { let data = wsJsonToRes(msg).data; - if (data.recipient_ids.includes(UserService.Instance.user.id)) { + if ( + data.recipient_ids.includes( + UserService.Instance.localUserView.local_user.id + ) + ) { this.state.replies.unshift(data.comment_view); this.state.combined.unshift(this.replyToReplyType(data.comment_view)); this.setState(this.state); - } else if (data.comment_view.creator.id == UserService.Instance.user.id) { + } else if ( + data.comment_view.creator.id == + UserService.Instance.localUserView.person.id + ) { // TODO this seems wrong, you should be using form_id toast(i18n.t("reply_sent")); } } else if (op == UserOperation.CreatePrivateMessage) { let data = wsJsonToRes(msg).data; if ( - data.private_message_view.recipient.id == UserService.Instance.user.id + data.private_message_view.recipient.id == + UserService.Instance.localUserView.person.id ) { this.state.messages.unshift(data.private_message_view); this.state.combined.unshift( @@ -785,13 +796,13 @@ export class Inbox extends Component { unreadCount(): number { return ( this.state.replies.filter(r => !r.comment.read).length + - this.state.mentions.filter(r => !r.user_mention.read).length + + this.state.mentions.filter(r => !r.person_mention.read).length + this.state.messages.filter( r => - UserService.Instance.user && + UserService.Instance.localUserView && !r.private_message.read && - // TODO also seems very strang and wrong - r.creator.id !== UserService.Instance.user.id + // TODO also seems very strange and wrong + r.creator.id !== UserService.Instance.localUserView.person.id ).length ); } diff --git a/src/shared/components/listing-type-select.tsx b/src/shared/components/listing-type-select.tsx index c576e9b9..695211e4 100644 --- a/src/shared/components/listing-type-select.tsx +++ b/src/shared/components/listing-type-select.tsx @@ -42,7 +42,11 @@ export class ListingTypeSelect extends Component< diff --git a/src/shared/components/main.tsx b/src/shared/components/main.tsx index c6b20524..4fcc56a5 100644 --- a/src/shared/components/main.tsx +++ b/src/shared/components/main.tsx @@ -21,7 +21,7 @@ import { GetCommentsResponse, CommentResponse, AddAdminResponse, - BanUserResponse, + BanPersonResponse, } from "lemmy-js-client"; import { DataType, InitialFetchRequest } from "../interfaces"; import { WebSocketService, UserService } from "../services"; @@ -31,7 +31,7 @@ import { SortSelect } from "./sort-select"; import { ListingTypeSelect } from "./listing-type-select"; import { DataTypeSelect } from "./data-type-select"; import { SiteForm } from "./site-form"; -import { UserListing } from "./user-listing"; +import { PersonListing } from "./person-listing"; import { CommunityLink } from "./community-link"; import { BannerIconHeader } from "./banner-icon-header"; import { Icon, Spinner } from "./icon"; @@ -130,14 +130,14 @@ export class Main extends Component { this.state.comments = this.isoData.routeData[0].comments; } this.state.trendingCommunities = this.isoData.routeData[1].communities; - if (UserService.Instance.user) { + if (UserService.Instance.localUserView) { this.state.subscribedCommunities = this.isoData.routeData[2].communities; } this.state.loading = false; } else { this.fetchTrendingCommunities(); this.fetchData(); - if (UserService.Instance.user) { + if (UserService.Instance.localUserView) { WebSocketService.Instance.send( wsClient.getFollowedCommunities({ auth: authField(), @@ -194,15 +194,17 @@ export class Main extends Component { // TODO figure out auth default_listingType, default_sort_type let type_: ListingType = pathSplit[5] ? ListingType[pathSplit[5]] - : UserService.Instance.user + : UserService.Instance.localUserView ? Object.values(ListingType)[ - UserService.Instance.user.default_listing_type + UserService.Instance.localUserView.local_user.default_listing_type ] : ListingType.Local; let sort: SortType = pathSplit[7] ? SortType[pathSplit[7]] - : UserService.Instance.user - ? Object.values(SortType)[UserService.Instance.user.default_sort_type] + : UserService.Instance.localUserView + ? Object.values(SortType)[ + UserService.Instance.localUserView.local_user.default_sort_type + ] : SortType.Active; let page = pathSplit[9] ? Number(pathSplit[9]) : 1; @@ -215,6 +217,7 @@ export class Main extends Component { limit: fetchLimit, sort, type_, + saved_only: false, }; setOptionalAuth(getPostsForm, req.auth); promises.push(req.client.getPosts(getPostsForm)); @@ -224,6 +227,7 @@ export class Main extends Component { limit: fetchLimit, sort, type_, + saved_only: false, }; setOptionalAuth(getCommentsForm, req.auth); promises.push(req.client.getComments(getCommentsForm)); @@ -294,7 +298,7 @@ export class Main extends Component {
- {UserService.Instance.user && + {UserService.Instance.localUserView && this.state.subscribedCommunities.length > 0 && (
{this.subscribedCommunities()}
@@ -413,7 +417,7 @@ export class Main extends Component {
  • {i18n.t("admins")}:
  • {this.state.siteRes.admins.map(av => (
  • - +
  • ))} @@ -609,7 +613,7 @@ export class Main extends Component { )} - {UserService.Instance.user && + {UserService.Instance.localUserView && this.state.listingType == ListingType.Subscribed && ( { get canAdmin(): boolean { return ( - UserService.Instance.user && + UserService.Instance.localUserView && this.state.siteRes.admins - .map(a => a.user.id) - .includes(UserService.Instance.user.id) + .map(a => a.person.id) + .includes(UserService.Instance.localUserView.person.id) ); } @@ -701,6 +705,7 @@ export class Main extends Component { limit: fetchLimit, sort: this.state.sort, type_: this.state.listingType, + saved_only: false, auth: authField(false), }; WebSocketService.Instance.send(wsClient.getPosts(getPostsForm)); @@ -710,6 +715,7 @@ export class Main extends Component { limit: fetchLimit, sort: this.state.sort, type_: this.state.listingType, + saved_only: false, auth: authField(false), }; WebSocketService.Instance.send(wsClient.getComments(getCommentsForm)); @@ -755,8 +761,8 @@ export class Main extends Component { let nsfwCheck = !nsfw || (nsfw && - UserService.Instance.user && - UserService.Instance.user.show_nsfw); + UserService.Instance.localUserView && + UserService.Instance.localUserView.local_user.show_nsfw); // Only push these if you're on the first page, and you pass the nsfw check if (this.state.page == 1 && nsfwCheck) { @@ -801,23 +807,23 @@ export class Main extends Component { let data = wsJsonToRes(msg).data; this.state.siteRes.admins = data.admins; this.setState(this.state); - } else if (op == UserOperation.BanUser) { - let data = wsJsonToRes(msg).data; + } else if (op == UserOperation.BanPerson) { + let data = wsJsonToRes(msg).data; let found = this.state.siteRes.banned.find( - u => (u.user.id = data.user_view.user.id) + p => (p.person.id = data.person_view.person.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.user.id !== data.user_view.user.id + i => i.person.id !== data.person_view.person.id ); } else { - this.state.siteRes.banned.push(data.user_view); + this.state.siteRes.banned.push(data.person_view); } this.state.posts - .filter(p => p.creator.id == data.user_view.user.id) + .filter(p => p.creator.id == data.person_view.person.id) .forEach(p => (p.creator.banned = data.banned)); this.setState(this.state); diff --git a/src/shared/components/markdown-textarea.tsx b/src/shared/components/markdown-textarea.tsx index 1aaf4db1..0acfc4c5 100644 --- a/src/shared/components/markdown-textarea.tsx +++ b/src/shared/components/markdown-textarea.tsx @@ -206,7 +206,9 @@ export class MarkdownTextArea extends Component<
    @@ -332,7 +332,7 @@ export class Modlog extends Component { return [ {ma.mod_add.removed ? "Removed " : "Appointed "} , - + , as an admin , ]; @@ -353,7 +353,7 @@ export class Modlog extends Component { - + {this.renderModlogType(i)} diff --git a/src/shared/components/navbar.tsx b/src/shared/components/navbar.tsx index 9577a631..12a6ed27 100644 --- a/src/shared/components/navbar.tsx +++ b/src/shared/components/navbar.tsx @@ -6,8 +6,8 @@ import { UserOperation, GetReplies, GetRepliesResponse, - GetUserMentions, - GetUserMentionsResponse, + GetPersonMentions, + GetPersonMentionsResponse, GetPrivateMessages, PrivateMessagesResponse, SortType, @@ -174,7 +174,8 @@ export class Navbar extends Component { // TODO class active corresponding to current page navbar() { - let user = UserService.Instance.user || this.props.site_res.my_user; + let localUserView = + UserService.Instance.localUserView || this.props.site_res.my_user; return (