diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/src/components/community.tsx | 57 | ||||
-rw-r--r-- | ui/src/components/inbox.tsx | 23 | ||||
-rw-r--r-- | ui/src/components/login.tsx | 2 | ||||
-rw-r--r-- | ui/src/components/main.tsx | 105 | ||||
-rw-r--r-- | ui/src/components/navbar.tsx | 88 | ||||
-rw-r--r-- | ui/src/components/post.tsx | 11 | ||||
-rw-r--r-- | ui/src/components/sidebar.tsx | 17 | ||||
-rw-r--r-- | ui/src/env.ts | 8 | ||||
-rw-r--r-- | ui/src/interfaces.ts | 12 | ||||
-rw-r--r-- | ui/src/services/WebSocketService.ts | 10 | ||||
-rw-r--r-- | ui/src/translations/de.ts | 8 | ||||
-rw-r--r-- | ui/src/translations/es.ts | 21 | ||||
-rw-r--r-- | ui/src/translations/fi.ts | 49 | ||||
-rw-r--r-- | ui/yarn.lock | 503 |
14 files changed, 635 insertions, 279 deletions
diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx index 3c5f6890..866b9eec 100644 --- a/ui/src/components/community.tsx +++ b/ui/src/components/community.tsx @@ -14,20 +14,17 @@ import { GetCommunityForm, ListingType, GetPostsResponse, + PostResponse, CreatePostLikeResponse, + AddModToCommunityResponse, + BanFromCommunityResponse, WebSocketJsonResponse, } from '../interfaces'; import { WebSocketService, UserService } from '../services'; import { PostListings } from './post-listings'; import { SortSelect } from './sort-select'; import { Sidebar } from './sidebar'; -import { - wsJsonToRes, - routeSortTypeToEnum, - fetchLimit, - postRefetchSeconds, - toast, -} from '../utils'; +import { wsJsonToRes, routeSortTypeToEnum, fetchLimit, toast } from '../utils'; import { T } from 'inferno-i18next'; import { i18n } from '../i18next'; @@ -37,6 +34,7 @@ interface State { communityName: string; moderators: Array<CommunityUser>; admins: Array<UserView>; + online: number; loading: boolean; posts: Array<Post>; sort: SortType; @@ -45,7 +43,6 @@ interface State { export class Community extends Component<any, State> { private subscription: Subscription; - private postFetcher: any; private emptyState: State = { community: { id: null, @@ -67,6 +64,7 @@ export class Community extends Component<any, State> { admins: [], communityId: Number(this.props.match.params.id), communityName: this.props.match.params.name, + online: null, loading: true, posts: [], sort: this.getSortTypeFromProps(this.props), @@ -108,7 +106,6 @@ export class Community extends Component<any, State> { componentWillUnmount() { this.subscription.unsubscribe(); - clearInterval(this.postFetcher); } // Necessary for back button for some reason @@ -158,6 +155,7 @@ export class Community extends Component<any, State> { community={this.state.community} moderators={this.state.moderators} admins={this.state.admins} + online={this.state.online} /> </div> </div> @@ -240,11 +238,6 @@ export class Community extends Component<any, State> { ); } - keepFetchingPosts() { - this.fetchPosts(); - this.postFetcher = setInterval(() => this.fetchPosts(), postRefetchSeconds); - } - fetchPosts() { let getPostsForm: GetPostsForm = { page: this.state.page, @@ -268,9 +261,10 @@ export class Community extends Component<any, State> { this.state.community = data.community; this.state.moderators = data.moderators; this.state.admins = data.admins; + this.state.online = data.online; document.title = `/c/${this.state.community.name} - ${WebSocketService.Instance.site.name}`; this.setState(this.state); - this.keepFetchingPosts(); + this.fetchPosts(); } else if (res.op == UserOperation.EditCommunity) { let data = res.data as CommunityResponse; this.state.community = data.community; @@ -286,13 +280,44 @@ export class Community extends Component<any, State> { this.state.posts = data.posts; this.state.loading = false; this.setState(this.state); + } else if (res.op == UserOperation.EditPost) { + let data = res.data as PostResponse; + let found = this.state.posts.find(c => c.id == data.post.id); + + found.url = data.post.url; + found.name = data.post.name; + found.nsfw = data.post.nsfw; + + this.setState(this.state); + } else if (res.op == UserOperation.CreatePost) { + let data = res.data as PostResponse; + this.state.posts.unshift(data.post); + this.setState(this.state); } else if (res.op == UserOperation.CreatePostLike) { let data = res.data as CreatePostLikeResponse; let found = this.state.posts.find(c => c.id == data.post.id); - found.my_vote = data.post.my_vote; + found.score = data.post.score; found.upvotes = data.post.upvotes; found.downvotes = data.post.downvotes; + if (data.post.my_vote !== null) { + found.my_vote = data.post.my_vote; + found.upvoteLoading = false; + found.downvoteLoading = false; + } + + this.setState(this.state); + } else if (res.op == UserOperation.AddModToCommunity) { + let data = res.data as AddModToCommunityResponse; + this.state.moderators = data.moderators; + this.setState(this.state); + } else if (res.op == UserOperation.BanFromCommunity) { + let data = res.data as BanFromCommunityResponse; + + this.state.posts + .filter(p => p.creator_id == data.user.id) + .forEach(p => (p.banned = data.banned)); + this.setState(this.state); } } diff --git a/ui/src/components/inbox.tsx b/ui/src/components/inbox.tsx index 41c1ce60..5fd9dbdc 100644 --- a/ui/src/components/inbox.tsx +++ b/ui/src/components/inbox.tsx @@ -421,10 +421,25 @@ export class Inbox extends Component<any, InboxState> { this.sendUnreadCount(); this.setState(this.state); } else if (res.op == UserOperation.CreateComment) { - // let res: CommentResponse = msg; - toast(i18n.t('reply_sent')); - // this.state.replies.unshift(res.comment); // TODO do this right - // this.setState(this.state); + let data = res.data as CommentResponse; + + if (data.recipient_ids.includes(UserService.Instance.user.id)) { + this.state.replies.unshift(data.comment); + this.setState(this.state); + } else if (data.comment.creator_id == UserService.Instance.user.id) { + toast(i18n.t('reply_sent')); + } + this.setState(this.state); + } 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); + this.setState(this.state); + } else if (data.message.creator_id == UserService.Instance.user.id) { + toast(i18n.t('message_sent')); + } + this.setState(this.state); } else if (res.op == UserOperation.SaveComment) { let data = res.data as CommentResponse; let found = this.state.replies.find(c => c.id == data.comment.id); diff --git a/ui/src/components/login.tsx b/ui/src/components/login.tsx index 64687a3d..b65b7a83 100644 --- a/ui/src/components/login.tsx +++ b/ui/src/components/login.tsx @@ -306,6 +306,7 @@ export class Login extends Component<any, State> { this.state = this.emptyState; this.setState(this.state); UserService.Instance.login(data); + WebSocketService.Instance.userJoin(); toast(i18n.t('logged_in')); this.props.history.push('/'); } else if (res.op == UserOperation.Register) { @@ -313,6 +314,7 @@ export class Login extends Component<any, State> { this.state = this.emptyState; this.setState(this.state); UserService.Instance.login(data); + WebSocketService.Instance.userJoin(); this.props.history.push('/communities'); } else if (res.op == UserOperation.PasswordReset) { toast(i18n.t('reset_password_mail_sent')); diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx index 6bf4164f..9ff6af44 100644 --- a/ui/src/components/main.tsx +++ b/ui/src/components/main.tsx @@ -15,8 +15,11 @@ import { SiteResponse, GetPostsResponse, CreatePostLikeResponse, + PostResponse, Post, GetPostsForm, + AddAdminResponse, + BanUserResponse, WebSocketJsonResponse, } from '../interfaces'; import { WebSocketService, UserService } from '../services'; @@ -31,7 +34,6 @@ import { fetchLimit, routeSortTypeToEnum, routeListingTypeToEnum, - postRefetchSeconds, pictshareAvatarThumbnail, showAvatars, toast, @@ -42,7 +44,7 @@ import { T } from 'inferno-i18next'; interface MainState { subscribedCommunities: Array<CommunityUser>; trendingCommunities: Array<Community>; - site: GetSiteResponse; + siteRes: GetSiteResponse; showEditSite: boolean; loading: boolean; posts: Array<Post>; @@ -53,11 +55,10 @@ interface MainState { export class Main extends Component<any, MainState> { private subscription: Subscription; - private postFetcher: any; private emptyState: MainState = { subscribedCommunities: [], trendingCommunities: [], - site: { + siteRes: { site: { id: null, name: null, @@ -133,12 +134,11 @@ export class Main extends Component<any, MainState> { WebSocketService.Instance.listCommunities(listCommunitiesForm); - this.keepFetchingPosts(); + this.fetchPosts(); } componentWillUnmount() { this.subscription.unsubscribe(); - clearInterval(this.postFetcher); } // Necessary for back button for some reason @@ -241,7 +241,7 @@ export class Main extends Component<any, MainState> { this.siteInfo() ) : ( <SiteForm - site={this.state.site.site} + site={this.state.siteRes.site} onCancel={this.handleEditCancel} /> )} @@ -262,7 +262,7 @@ export class Main extends Component<any, MainState> { <div> <div class="card border-secondary mb-3"> <div class="card-body"> - <h5 class="mb-0">{`${this.state.site.site.name}`}</h5> + <h5 class="mb-0">{`${this.state.siteRes.site.name}`}</h5> {this.canAdmin && ( <ul class="list-inline mb-1 text-muted small font-weight-bold"> <li className="list-inline-item"> @@ -279,7 +279,7 @@ export class Main extends Component<any, MainState> { <li className="list-inline-item badge badge-secondary"> <T i18nKey="number_online" - interpolation={{ count: this.state.site.online }} + interpolation={{ count: this.state.siteRes.online }} > # </T> @@ -288,7 +288,7 @@ export class Main extends Component<any, MainState> { <T i18nKey="number_of_users" interpolation={{ - count: this.state.site.site.number_of_users, + count: this.state.siteRes.site.number_of_users, }} > # @@ -298,7 +298,7 @@ export class Main extends Component<any, MainState> { <T i18nKey="number_of_communities" interpolation={{ - count: this.state.site.site.number_of_communities, + count: this.state.siteRes.site.number_of_communities, }} > # @@ -308,7 +308,7 @@ export class Main extends Component<any, MainState> { <T i18nKey="number_of_posts" interpolation={{ - count: this.state.site.site.number_of_posts, + count: this.state.siteRes.site.number_of_posts, }} > # @@ -318,7 +318,7 @@ export class Main extends Component<any, MainState> { <T i18nKey="number_of_comments" interpolation={{ - count: this.state.site.site.number_of_comments, + count: this.state.siteRes.site.number_of_comments, }} > # @@ -337,7 +337,7 @@ export class Main extends Component<any, MainState> { </T> : </li> - {this.state.site.admins.map(admin => ( + {this.state.siteRes.admins.map(admin => ( <li class="list-inline-item"> <Link class="text-info" to={`/u/${admin.name}`}> {admin.avatar && showAvatars() && ( @@ -355,13 +355,13 @@ export class Main extends Component<any, MainState> { </ul> </div> </div> - {this.state.site.site.description && ( + {this.state.siteRes.site.description && ( <div class="card border-secondary mb-3"> <div class="card-body"> <div className="md-div" dangerouslySetInnerHTML={mdToHtml( - this.state.site.site.description + this.state.siteRes.site.description )} /> </div> @@ -494,7 +494,7 @@ export class Main extends Component<any, MainState> { get canAdmin(): boolean { return ( UserService.Instance.user && - this.state.site.admins + this.state.siteRes.admins .map(a => a.id) .includes(UserService.Instance.user.id) ); @@ -548,11 +548,6 @@ export class Main extends Component<any, MainState> { window.scrollTo(0, 0); } - keepFetchingPosts() { - this.fetchPosts(); - this.postFetcher = setInterval(() => this.fetchPosts(), postRefetchSeconds); - } - fetchPosts() { let getPostsForm: GetPostsForm = { page: this.state.page, @@ -584,15 +579,15 @@ export class Main extends Component<any, MainState> { if (!data.site) { this.context.router.history.push('/setup'); } - this.state.site.admins = data.admins; - this.state.site.site = data.site; - this.state.site.banned = data.banned; - this.state.site.online = data.online; + this.state.siteRes.admins = data.admins; + this.state.siteRes.site = data.site; + this.state.siteRes.banned = data.banned; + this.state.siteRes.online = data.online; this.setState(this.state); document.title = `${WebSocketService.Instance.site.name}`; } else if (res.op == UserOperation.EditSite) { let data = res.data as SiteResponse; - this.state.site.site = data.site; + this.state.siteRes.site = data.site; this.state.showEditSite = false; this.setState(this.state); } else if (res.op == UserOperation.GetPosts) { @@ -600,13 +595,67 @@ export class Main extends Component<any, MainState> { this.state.posts = data.posts; this.state.loading = false; this.setState(this.state); + } else if (res.op == UserOperation.CreatePost) { + let data = res.data as PostResponse; + + // If you're on subscribed, only push it if you're subscribed. + if (this.state.type_ == ListingType.Subscribed) { + if ( + this.state.subscribedCommunities + .map(c => c.community_id) + .includes(data.post.community_id) + ) { + this.state.posts.unshift(data.post); + } + } else { + this.state.posts.unshift(data.post); + } + + this.setState(this.state); + } else if (res.op == UserOperation.EditPost) { + let data = res.data as PostResponse; + let found = this.state.posts.find(c => c.id == data.post.id); + + found.url = data.post.url; + found.name = data.post.name; + found.nsfw = data.post.nsfw; + + this.setState(this.state); } else if (res.op == UserOperation.CreatePostLike) { let data = res.data as CreatePostLikeResponse; let found = this.state.posts.find(c => c.id == data.post.id); - found.my_vote = data.post.my_vote; + found.score = data.post.score; found.upvotes = data.post.upvotes; found.downvotes = data.post.downvotes; + if (data.post.my_vote !== null) { + found.my_vote = data.post.my_vote; + found.upvoteLoading = false; + found.downvoteLoading = false; + } + + this.setState(this.state); + } else if (res.op == UserOperation.AddAdmin) { + let data = res.data as AddAdminResponse; + 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)); + + // 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 + ); + } else { + this.state.siteRes.banned.push(data.user); + } + + this.state.posts + .filter(p => p.creator_id == data.user.id) + .forEach(p => (p.banned = data.banned)); + this.setState(this.state); } } diff --git a/ui/src/components/navbar.tsx b/ui/src/components/navbar.tsx index eccc8116..c03dcd87 100644 --- a/ui/src/components/navbar.tsx +++ b/ui/src/components/navbar.tsx @@ -14,7 +14,9 @@ import { SortType, GetSiteResponse, Comment, + CommentResponse, PrivateMessage, + PrivateMessageResponse, WebSocketJsonResponse, } from '../interfaces'; import { @@ -35,7 +37,6 @@ interface NavbarState { replies: Array<Comment>; mentions: Array<Comment>; messages: Array<PrivateMessage>; - fetchCount: number; unreadCount: number; siteName: string; } @@ -46,7 +47,6 @@ export class Navbar extends Component<any, NavbarState> { emptyState: NavbarState = { isLoggedIn: UserService.Instance.user !== undefined, unreadCount: 0, - fetchCount: 0, replies: [], mentions: [], messages: [], @@ -58,8 +58,6 @@ export class Navbar extends Component<any, NavbarState> { super(props, context); this.state = this.emptyState; - this.keepFetchingUnreads(); - // Subscribe to user changes this.userSub = UserService.Instance.sub.subscribe(user => { this.state.isLoggedIn = user.user !== undefined; @@ -78,6 +76,8 @@ export class Navbar extends Component<any, NavbarState> { if (this.state.isLoggedIn) { this.requestNotificationPermission(); + // TODO couldn't get re-logging in to re-fetch unreads + this.fetchUnreads(); } WebSocketService.Instance.getSite(); @@ -211,45 +211,51 @@ export class Navbar extends Component<any, NavbarState> { } else if (res.op == UserOperation.GetReplies) { let data = res.data as GetRepliesResponse; let unreadReplies = data.replies.filter(r => !r.read); - if ( - unreadReplies.length > 0 && - this.state.fetchCount > 1 && - JSON.stringify(this.state.replies) !== JSON.stringify(unreadReplies) - ) { - this.notify(unreadReplies); - } 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); - if ( - unreadMentions.length > 0 && - this.state.fetchCount > 1 && - JSON.stringify(this.state.mentions) !== JSON.stringify(unreadMentions) - ) { - this.notify(unreadMentions); - } 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); - if ( - unreadMessages.length > 0 && - this.state.fetchCount > 1 && - JSON.stringify(this.state.messages) !== JSON.stringify(unreadMessages) - ) { - this.notify(unreadMessages); - } this.state.messages = unreadMessages; + this.state.unreadCount = this.calculateUnreadCount(); this.setState(this.state); this.sendUnreadCount(); + } else if (res.op == UserOperation.CreateComment) { + let data = res.data as CommentResponse; + + if (this.state.isLoggedIn) { + if (data.recipient_ids.includes(UserService.Instance.user.id)) { + this.state.replies.push(data.comment); + this.state.unreadCount++; + this.setState(this.state); + this.sendUnreadCount(); + this.notify(data.comment); + } + } + } else if (res.op == UserOperation.CreatePrivateMessage) { + let data = res.data as PrivateMessageResponse; + + if (this.state.isLoggedIn) { + if (data.message.recipient_id == UserService.Instance.user.id) { + this.state.messages.push(data.message); + this.state.unreadCount++; + this.setState(this.state); + this.sendUnreadCount(); + this.notify(data.message); + } + } } else if (res.op == UserOperation.GetSite) { let data = res.data as GetSiteResponse; @@ -261,11 +267,6 @@ export class Navbar extends Component<any, NavbarState> { } } - keepFetchingUnreads() { - this.fetchUnreads(); - setInterval(() => this.fetchUnreads(), 15000); - } - fetchUnreads() { if (this.state.isLoggedIn) { let repliesForm: GetRepliesForm = { @@ -292,7 +293,6 @@ export class Navbar extends Component<any, NavbarState> { WebSocketService.Instance.getReplies(repliesForm); WebSocketService.Instance.getUserMentions(userMentionsForm); WebSocketService.Instance.getPrivateMessages(privateMessagesForm); - this.state.fetchCount++; } } } @@ -304,11 +304,11 @@ export class Navbar extends Component<any, NavbarState> { sendUnreadCount() { UserService.Instance.sub.next({ user: UserService.Instance.user, - unreadCount: this.unreadCount, + unreadCount: this.state.unreadCount, }); } - get unreadCount() { + calculateUnreadCount(): number { return ( this.state.replies.filter(r => !r.read).length + this.state.mentions.filter(r => !r.read).length + @@ -330,24 +330,20 @@ export class Navbar extends Component<any, NavbarState> { } } - notify(replies: Array<Comment | PrivateMessage>) { - let recentReply = replies[0]; + notify(reply: Comment | PrivateMessage) { if (Notification.permission !== 'granted') Notification.requestPermission(); else { - var notification = new Notification( - `${replies.length} ${i18n.t('unread_messages')}`, - { - icon: recentReply.creator_avatar - ? recentReply.creator_avatar - : `${window.location.protocol}//${window.location.host}/static/assets/apple-touch-icon.png`, - body: `${recentReply.creator_name}: ${recentReply.content}`, - } - ); + var notification = new Notification(reply.creator_name, { + icon: reply.creator_avatar + ? reply.creator_avatar + : `${window.location.protocol}//${window.location.host}/static/assets/apple-touch-icon.png`, + body: `${reply.content}`, + }); notification.onclick = () => { this.context.router.history.push( - isCommentType(recentReply) - ? `/post/${recentReply.post_id}/comment/${recentReply.id}` + isCommentType(reply) + ? `/post/${reply.post_id}/comment/${reply.id}` : `/inbox` ); }; diff --git a/ui/src/components/post.tsx b/ui/src/components/post.tsx index 36621248..99a20b46 100644 --- a/ui/src/components/post.tsx +++ b/ui/src/components/post.tsx @@ -47,6 +47,7 @@ interface PostState { community: Community; moderators: Array<CommunityUser>; admins: Array<UserView>; + online: number; scrolled?: boolean; scrolled_comment_id?: number; loading: boolean; @@ -62,6 +63,7 @@ export class Post extends Component<any, PostState> { community: null, moderators: [], admins: [], + online: null, scrolled: false, loading: true, crossPosts: [], @@ -280,6 +282,7 @@ export class Post extends Component<any, PostState> { community={this.state.community} moderators={this.state.moderators} admins={this.state.admins} + online={this.state.online} /> </div> ); @@ -378,6 +381,7 @@ export class Post extends Component<any, PostState> { this.state.community = data.community; this.state.moderators = data.moderators; this.state.admins = data.admins; + this.state.online = data.online; this.state.loading = false; document.title = `${this.state.post.name} - ${WebSocketService.Instance.site.name}`; @@ -432,10 +436,15 @@ export class Post extends Component<any, PostState> { this.setState(this.state); } else if (res.op == UserOperation.CreatePostLike) { let data = res.data as CreatePostLikeResponse; - this.state.post.my_vote = data.post.my_vote; this.state.post.score = data.post.score; this.state.post.upvotes = data.post.upvotes; this.state.post.downvotes = data.post.downvotes; + if (data.post.my_vote !== null) { + this.state.post.my_vote = data.post.my_vote; + this.state.post.upvoteLoading = false; + this.state.post.downvoteLoading = false; + } + this.setState(this.state); } else if (res.op == UserOperation.EditPost) { let data = res.data as PostResponse; diff --git a/ui/src/components/sidebar.tsx b/ui/src/components/sidebar.tsx index 089dd558..0e6b68e6 100644 --- a/ui/src/components/sidebar.tsx +++ b/ui/src/components/sidebar.tsx @@ -22,6 +22,7 @@ interface SidebarProps { community: Community; moderators: Array<CommunityUser>; admins: Array<UserView>; + online: number; } interface SidebarState { @@ -156,10 +157,13 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { </form> )} <ul class="my-1 list-inline"> - <li className="list-inline-item"> - <Link className="badge badge-secondary" to="/communities"> - {community.category_name} - </Link> + <li className="list-inline-item badge badge-secondary"> + <T + i18nKey="number_online" + interpolation={{ count: this.props.online }} + > + # + </T> </li> <li className="list-inline-item badge badge-secondary"> <T @@ -186,6 +190,11 @@ export class Sidebar extends Component<SidebarProps, SidebarState> { </T> </li> <li className="list-inline-item"> + <Link className="badge badge-secondary" to="/communities"> + {community.category_name} + </Link> + </li> + <li className="list-inline-item"> <Link className="badge badge-secondary" to={`/modlog/community/${this.props.community.id}`} diff --git a/ui/src/env.ts b/ui/src/env.ts index af9aad5d..5003986b 100644 --- a/ui/src/env.ts +++ b/ui/src/env.ts @@ -1,5 +1,9 @@ const host = `${window.location.hostname}`; -const port = `${window.location.port == '4444' ? '8536' : window.location.port}`; +const port = `${ + window.location.port == '4444' ? '8536' : window.location.port +}`; const endpoint = `${host}:${port}`; -export const wsUri = `${window.location.protocol == 'https:' ? 'wss://' : 'ws://'}${endpoint}/api/v1/ws`; +export const wsUri = `${ + window.location.protocol == 'https:' ? 'wss://' : 'ws://' +}${endpoint}/api/v1/ws`; diff --git a/ui/src/interfaces.ts b/ui/src/interfaces.ts index f83595d7..4036f7e6 100644 --- a/ui/src/interfaces.ts +++ b/ui/src/interfaces.ts @@ -41,6 +41,7 @@ export enum UserOperation { CreatePrivateMessage, EditPrivateMessage, GetPrivateMessages, + UserJoin, } export enum CommentSortType { @@ -538,6 +539,7 @@ export interface GetCommunityResponse { community: Community; moderators: Array<CommunityUser>; admins: Array<UserView>; + online: number; } export interface CommunityResponse { @@ -594,6 +596,7 @@ export interface GetPostResponse { community: Community; moderators: Array<CommunityUser>; admins: Array<UserView>; + online: number; } export interface SavePostForm { @@ -627,6 +630,7 @@ export interface SaveCommentForm { export interface CommentResponse { comment: Comment; + recipient_ids: Array<number>; } export interface CommentLikeForm { @@ -775,6 +779,14 @@ export interface PrivateMessageResponse { message: PrivateMessage; } +export interface UserJoinForm { + auth: string; +} + +export interface UserJoinResponse { + user_id: number; +} + export type MessageType = | EditPrivateMessageForm | LoginForm diff --git a/ui/src/services/WebSocketService.ts b/ui/src/services/WebSocketService.ts index a7e9b7e0..f1a6d156 100644 --- a/ui/src/services/WebSocketService.ts +++ b/ui/src/services/WebSocketService.ts @@ -38,6 +38,7 @@ import { PrivateMessageForm, EditPrivateMessageForm, GetPrivateMessagesForm, + UserJoinForm, MessageType, } from '../interfaces'; import { webSocket } from 'rxjs/webSocket'; @@ -71,12 +72,21 @@ export class WebSocketService { .subscribe(); console.log(`Connected to ${wsUri}`); + + if (UserService.Instance.user) { + this.userJoin(); + } } public static get Instance() { return this._instance || (this._instance = new this()); } + public userJoin() { + let form: UserJoinForm = { auth: UserService.Instance.auth }; + this.subject.next(this.wsSendWrapper(UserOperation.UserJoin, form)); + } + public login(loginForm: LoginForm) { this.subject.next(this.wsSendWrapper(UserOperation.Login, loginForm)); } diff --git a/ui/src/translations/de.ts b/ui/src/translations/de.ts index fafec579..7a1b0f5d 100644 --- a/ui/src/translations/de.ts +++ b/ui/src/translations/de.ts @@ -116,10 +116,11 @@ export const de = { password: 'Passwort', verify_password: 'Passwort überprüfen', forgot_password: 'Passwort vergessen', - reset_password_mail_sent: 'Eine E-Mail wurde geschickt, um dein Passwort zurückzusetzen.', + reset_password_mail_sent: + 'Eine E-Mail wurde geschickt, um dein Passwort zurückzusetzen.', password_change: 'Passwort geändert', new_password: 'neues Passwort', - no_email_setup: "Dieser Server hat E-Mails nicht korrekt eingerichtet.", + no_email_setup: 'Dieser Server hat E-Mails nicht korrekt eingerichtet.', login: 'Einloggen', sign_up: 'Registrieren', email: 'E-Mail', @@ -182,7 +183,8 @@ export const de = { community_already_exists: 'Gemeinschaft existiert bereits.', community_moderator_already_exists: 'Gemeinschaft Moderator existiert bereits.', - community_follower_already_exists: 'Gemeinschaft Follower existiert bereits.', + community_follower_already_exists: + 'Gemeinschaft Follower existiert bereits.', community_user_already_banned: 'Gemeinschaft Nutzer schon gebannt.', couldnt_create_post: 'Konnte Beitrag nicht anlegen.', couldnt_like_post: 'Konnte Beitrag nicht liken.', diff --git a/ui/src/translations/es.ts b/ui/src/translations/es.ts index 6fb49482..d61ebfb8 100644 --- a/ui/src/translations/es.ts +++ b/ui/src/translations/es.ts @@ -132,7 +132,7 @@ export const es = { reset_password_mail_sent: 'Enviar correo para reestablecer la contraseña.', password_change: 'Cambio de Contraseña', new_password: 'Nueva Contraseña', - no_email_setup: "Este servidor no ha activado correctamente el correo.", + no_email_setup: 'Este servidor no ha activado correctamente el correo.', email: 'Correo electrónico', matrix_user_id: 'Usuario Matricial', private_message_disclaimer: @@ -204,9 +204,12 @@ export const es = { couldnt_find_community: 'No se pudo encontrar la comunidad.', couldnt_update_community: 'No se pudo actualizar la comunidad.', community_already_exists: 'Esta comunidad ya existe.', - community_moderator_already_exists: 'Este moderador de la comunidad ya existe.', |