summaryrefslogtreecommitdiffstats
path: root/ui/src/components
diff options
context:
space:
mode:
authorDessalines <tyhou13@gmx.com>2020-01-31 20:02:20 -0500
committerDessalines <tyhou13@gmx.com>2020-01-31 20:02:20 -0500
commit8036474ddad2f20c27a2fb023395306d6b9e577d (patch)
tree28f3546c9086931f33d9ee6d910c9aa43a5a1f77 /ui/src/components
parent5188bddd4ddb1d4f4bc4add24db210789054c2a5 (diff)
Starting to work on user message scope.
Diffstat (limited to 'ui/src/components')
-rw-r--r--ui/src/components/community.tsx55
-rw-r--r--ui/src/components/inbox.tsx1
-rw-r--r--ui/src/components/main.tsx105
-rw-r--r--ui/src/components/navbar.tsx53
-rw-r--r--ui/src/components/post.tsx11
-rw-r--r--ui/src/components/sidebar.tsx17
6 files changed, 160 insertions, 82 deletions
diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx
index 3c5f6890..a88ec952 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;
@@ -67,6 +65,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),
@@ -158,6 +157,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 +240,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 +263,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 +282,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..5585d84f 100644
--- a/ui/src/components/inbox.tsx
+++ b/ui/src/components/inbox.tsx
@@ -422,6 +422,7 @@ export class Inbox extends Component<any, InboxState> {
this.setState(this.state);
} else if (res.op == UserOperation.CreateComment) {
// let res: CommentResponse = msg;
+ // TODO gotta remove this
toast(i18n.t('reply_sent'));
// this.state.replies.unshift(res.comment); // TODO do this right
// this.setState(this.state);
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 1828fce9..d433ad1f 100644
--- a/ui/src/components/navbar.tsx
+++ b/ui/src/components/navbar.tsx
@@ -14,6 +14,7 @@ import {
SortType,
GetSiteResponse,
Comment,
+ CommentResponse,
PrivateMessage,
WebSocketJsonResponse,
} from '../interfaces';
@@ -58,7 +59,7 @@ export class Navbar extends Component<any, NavbarState> {
super(props, context);
this.state = this.emptyState;
- this.keepFetchingUnreads();
+ this.fetchUnreads();
// Subscribe to user changes
this.userSub = UserService.Instance.sub.subscribe(user => {
@@ -211,13 +212,6 @@ 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.setState(this.state);
@@ -225,13 +219,6 @@ export class Navbar extends Component<any, NavbarState> {
} 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.setState(this.state);
@@ -239,17 +226,19 @@ export class Navbar extends Component<any, NavbarState> {
} 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.setState(this.state);
this.sendUnreadCount();
+ } else if (res.op == UserOperation.CreateComment) {
+ // TODO do private messages too
+ let data = res.data as CommentResponse;
+
+ if (UserService.Instance.user) {
+ if (data.recipient_ids.includes(UserService.Instance.user.id)) {
+ this.notify(data.comment);
+ }
+ }
} else if (res.op == UserOperation.GetSite) {
let data = res.data as GetSiteResponse;
@@ -261,11 +250,6 @@ export class Navbar extends Component<any, NavbarState> {
}
}
- keepFetchingUnreads() {
- this.fetchUnreads();
- setInterval(() => this.fetchUnreads(), 15000);
- }
-
fetchUnreads() {
if (this.state.isLoggedIn) {
let repliesForm: GetRepliesForm = {
@@ -330,24 +314,23 @@ 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')}`,
+ `${this.state.unreadCount} ${i18n.t('unread_messages')}`,
{
- icon: recentReply.creator_avatar
- ? recentReply.creator_avatar
+ icon: reply.creator_avatar
+ ? reply.creator_avatar
: `${window.location.protocol}//${window.location.host}/static/assets/apple-touch-icon.png`,
- body: `${recentReply.creator_name}: ${recentReply.content}`,
+ body: `${reply.creator_name}: ${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}`}