diff options
Diffstat (limited to 'ui/src/components')
-rw-r--r-- | ui/src/components/comment-node.tsx | 18 | ||||
-rw-r--r-- | ui/src/components/main.tsx | 14 | ||||
-rw-r--r-- | ui/src/components/navbar.tsx | 16 | ||||
-rw-r--r-- | ui/src/components/post-listing.tsx | 11 | ||||
-rw-r--r-- | ui/src/components/search.tsx | 15 | ||||
-rw-r--r-- | ui/src/components/sidebar.tsx | 12 | ||||
-rw-r--r-- | ui/src/components/user.tsx | 82 |
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); |