summaryrefslogtreecommitdiffstats
path: root/ui/src/components
diff options
context:
space:
mode:
authorDessalines <tyhou13@gmx.com>2019-12-29 15:39:48 -0500
committerDessalines <tyhou13@gmx.com>2019-12-29 15:39:48 -0500
commita4428528e30b18eb85596edf9c26bc8b6b7d11ee (patch)
tree450f5662ada20a7f66f809033d57fbc12dcc963d /ui/src/components
parent106aaf4f28ef34d68848f48e5673f955a04b6deb (diff)
Adding user avatars / icons. Requires pictshare.
- Fixes #188
Diffstat (limited to 'ui/src/components')
-rw-r--r--ui/src/components/comment-node.tsx18
-rw-r--r--ui/src/components/main.tsx14
-rw-r--r--ui/src/components/navbar.tsx16
-rw-r--r--ui/src/components/post-listing.tsx11
-rw-r--r--ui/src/components/search.tsx15
-rw-r--r--ui/src/components/sidebar.tsx12
-rw-r--r--ui/src/components/user.tsx82
7 files changed, 158 insertions, 10 deletions
diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx
index f408ef27..34ec0dfb 100644
--- a/ui/src/components/comment-node.tsx
+++ b/ui/src/components/comment-node.tsx
@@ -17,7 +17,13 @@ import {
BanType,
} from '../interfaces';
import { WebSocketService, UserService } from '../services';
-import { mdToHtml, getUnixTime, canMod, isMod } from '../utils';
+import {
+ mdToHtml,
+ getUnixTime,
+ canMod,
+ isMod,
+ pictshareAvatarThumbnail,
+} from '../utils';
import * as moment from 'moment';
import { MomentTime } from './moment-time';
import { CommentForm } from './comment-form';
@@ -128,7 +134,15 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="text-info"
to={`/u/${node.comment.creator_name}`}
>
- {node.comment.creator_name}
+ {node.comment.creator_avatar && (
+ <img
+ height="32"
+ width="32"
+ src={pictshareAvatarThumbnail(node.comment.creator_avatar)}
+ class="rounded-circle mr-1"
+ />
+ )}
+ <span>{node.comment.creator_name}</span>
</Link>
</li>
{this.isMod && (
diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx
index 0d6be91d..d1042f38 100644
--- a/ui/src/components/main.tsx
+++ b/ui/src/components/main.tsx
@@ -31,6 +31,7 @@ import {
routeSortTypeToEnum,
routeListingTypeToEnum,
postRefetchSeconds,
+ pictshareAvatarThumbnail,
} from '../utils';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
@@ -65,6 +66,9 @@ export class Main extends Component<any, MainState> {
number_of_posts: null,
number_of_comments: null,
number_of_communities: null,
+ enable_downvotes: null,
+ open_registration: null,
+ enable_nsfw: null,
},
admins: [],
banned: [],
@@ -341,7 +345,15 @@ export class Main extends Component<any, MainState> {
{this.state.site.admins.map(admin => (
<li class="list-inline-item">
<Link class="text-info" to={`/u/${admin.name}`}>
- {admin.name}
+ {admin.avatar && (
+ <img
+ height="32"
+ width="32"
+ src={pictshareAvatarThumbnail(admin.avatar)}
+ class="rounded-circle mr-1"
+ />
+ )}
+ <span>{admin.name}</span>
</Link>
</li>
))}
diff --git a/ui/src/components/navbar.tsx b/ui/src/components/navbar.tsx
index 306dc74f..f1a98941 100644
--- a/ui/src/components/navbar.tsx
+++ b/ui/src/components/navbar.tsx
@@ -13,7 +13,7 @@ import {
GetSiteResponse,
Comment,
} from '../interfaces';
-import { msgOp } from '../utils';
+import { msgOp, pictshareAvatarThumbnail } from '../utils';
import { version } from '../version';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
@@ -151,7 +151,19 @@ export class Navbar extends Component<any, NavbarState> {
class="nav-link"
to={`/u/${UserService.Instance.user.username}`}
>
- {UserService.Instance.user.username}
+ <span>
+ {UserService.Instance.user.avatar && (
+ <img
+ src={pictshareAvatarThumbnail(
+ UserService.Instance.user.avatar
+ )}
+ height="32"
+ width="32"
+ class="rounded-circle mr-2"
+ />
+ )}
+ {UserService.Instance.user.username}
+ </span>
</Link>
</li>
</>
diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx
index 61a4c865..1f3a74ac 100644
--- a/ui/src/components/post-listing.tsx
+++ b/ui/src/components/post-listing.tsx
@@ -25,6 +25,7 @@ import {
isImage,
isVideo,
getUnixTime,
+ pictshareAvatarThumbnail,
} from '../utils';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
@@ -248,7 +249,15 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
<li className="list-inline-item">
<span>{i18n.t('by')} </span>
<Link className="text-info" to={`/u/${post.creator_name}`}>
- {post.creator_name}
+ {post.creator_avatar && (
+ <img
+ height="32"
+ width="32"
+ src={pictshareAvatarThumbnail(post.creator_avatar)}
+ class="rounded-circle mr-1"
+ />
+ )}
+ <span>{post.creator_name}</span>
</Link>
{this.isMod && (
<span className="mx-1 badge badge-light">
diff --git a/ui/src/components/search.tsx b/ui/src/components/search.tsx
index bba7c5ad..d92c06e1 100644
--- a/ui/src/components/search.tsx
+++ b/ui/src/components/search.tsx
@@ -19,6 +19,7 @@ import {
fetchLimit,
routeSearchTypeToEnum,
routeSortTypeToEnum,
+ pictshareAvatarThumbnail,
} from '../utils';
import { PostListing } from './post-listing';
import { SortSelect } from './sort-select';
@@ -286,7 +287,19 @@ export class Search extends Component<any, SearchState> {
<Link
className="text-info"
to={`/u/${(i.data as UserView).name}`}
- >{`/u/${(i.data as UserView).name}`}</Link>
+ >
+ {(i.data as UserView).avatar && (
+ <img
+ height="32"
+ width="32"
+ src={pictshareAvatarThumbnail(
+ (i.data as UserView).avatar
+ )}
+ class="rounded-circle mr-1"
+ />
+ )}
+ <span>{`/u/${(i.data as UserView).name}`}</span>
+ </Link>
</span>
<span>{` - ${
(i.data as UserView).comment_score
diff --git a/ui/src/components/sidebar.tsx b/ui/src/components/sidebar.tsx
index 85f81a30..0e95666f 100644
--- a/ui/src/components/sidebar.tsx
+++ b/ui/src/components/sidebar.tsx
@@ -8,7 +8,7 @@ import {
UserView,
} from '../interfaces';
import { WebSocketService, UserService } from '../services';
-import { mdToHtml, getUnixTime } from '../utils';
+import { mdToHtml, getUnixTime, pictshareAvatarThumbnail } from '../utils';
import { CommunityForm } from './community-form';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
@@ -194,7 +194,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
{this.props.moderators.map(mod => (
<li class="list-inline-item">
<Link class="text-info" to={`/u/${mod.user_name}`}>
- {mod.user_name}
+ {mod.avatar && (
+ <img
+ height="32"
+ width="32"
+ src={pictshareAvatarThumbnail(mod.avatar)}
+ class="rounded-circle mr-1"
+ />
+ )}
+ <span>{mod.user_name}</span>
</Link>
</li>
))}
diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx
index 6d6a2e0c..e97b26f9 100644
--- a/ui/src/components/user.tsx
+++ b/ui/src/components/user.tsx
@@ -58,6 +58,7 @@ interface UserState {
sort: SortType;
page: number;
loading: boolean;
+ avatarLoading: boolean;
userSettingsForm: UserSettingsForm;
userSettingsLoading: boolean;
deleteAccountLoading: boolean;
@@ -78,6 +79,7 @@ export class User extends Component<any, UserState> {
number_of_comments: null,
comment_score: null,
banned: null,
+ avatar: null,
},
user_id: null,
username: null,
@@ -87,6 +89,7 @@ export class User extends Component<any, UserState> {
posts: [],
admins: [],
loading: true,
+ avatarLoading: false,
view: this.getViewFromProps(this.props),
sort: this.getSortTypeFromProps(this.props),
page: this.getPageFromProps(this.props),
@@ -96,6 +99,7 @@ export class User extends Component<any, UserState> {
default_sort_type: null,
default_listing_type: null,
lang: null,
+ avatar: null,
auth: null,
},
userSettingsLoading: null,
@@ -203,7 +207,17 @@ export class User extends Component<any, UserState> {
) : (
<div class="row">
<div class="col-12 col-md-8">
- <h5>/u/{this.state.user.name}</h5>
+ <h5>
+ {this.state.user.avatar && (
+ <img
+ height="80"
+ width="80"
+ src={this.state.user.avatar}
+ class="rounded-circle mr-2"
+ />
+ )}
+ <span>/u/{this.state.user.name}</span>
+ </h5>
{this.selects()}
{this.state.view == View.Overview && this.overview()}
{this.state.view == View.Comments && this.comments()}
@@ -425,6 +439,39 @@ export class User extends Component<any, UserState> {
<div class="form-group">
<div class="col-12">
<label>
+ <T i18nKey="avatar">#</T>
+ </label>
+ <form class="d-inline">
+ <label
+ htmlFor="file-upload"
+ class="pointer ml-4 text-muted small font-weight-bold"
+ >
+ <img
+ height="80"
+ width="80"
+ src={
+ this.state.userSettingsForm.avatar
+ ? this.state.userSettingsForm.avatar
+ : 'https://via.placeholder.com/300/000?text=Avatar'
+ }
+ class="rounded-circle"
+ />
+ </label>
+ <input
+ id="file-upload"
+ type="file"
+ accept="image/*,video/*"
+ name="file"
+ class="d-none"
+ disabled={!UserService.Instance.user}
+ onChange={linkEvent(this, this.handleImageUpload)}
+ />
+ </form>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="col-12">
+ <label>
<T i18nKey="language">#</T>
</label>
<select
@@ -739,6 +786,38 @@ export class User extends Component<any, UserState> {
this.setState(this.state);
}
+ handleImageUpload(i: User, event: any) {
+ event.preventDefault();
+ let file = event.target.files[0];
+ const imageUploadUrl = `/pictshare/api/upload.php`;
+ const formData = new FormData();
+ formData.append('file', file);
+
+ i.state.avatarLoading = true;
+ i.setState(i.state);
+
+ fetch(imageUploadUrl, {
+ method: 'POST',
+ body: formData,
+ })
+ .then(res => res.json())
+ .then(res => {
+ let url = `${window.location.origin}/pictshare/${res.url}`;
+ if (res.filetype == 'mp4') {
+ url += '/raw';
+ }
+ i.state.userSettingsForm.avatar = url;
+ console.log(url);
+ i.state.avatarLoading = false;
+ i.setState(i.state);
+ })
+ .catch(error => {
+ i.state.avatarLoading = false;
+ i.setState(i.state);
+ alert(error);
+ });
+ }
+
handleUserSettingsSubmit(i: User, event: any) {
event.preventDefault();
i.state.userSettingsLoading = true;
@@ -802,6 +881,7 @@ export class User extends Component<any, UserState> {
this.state.userSettingsForm.default_listing_type =
UserService.Instance.user.default_listing_type;
this.state.userSettingsForm.lang = UserService.Instance.user.lang;
+ this.state.userSettingsForm.avatar = UserService.Instance.user.avatar;
}
document.title = `/u/${this.state.user.name} - ${WebSocketService.Instance.site.name}`;
window.scrollTo(0, 0);