aboutsummaryrefslogtreecommitdiff
path: root/vnext/src/ui/UserInfo.js
blob: 9a663829f61f880001935831c7c906d761dee644 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { memo, useState, useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';

import { info, fetchUserUri, update } from '../api';

import Avatar from './Avatar';
import Icon from './Icon';
import SearchBox from './SearchBox';
// @ts-ignore
import defaultAvatar from '../assets/av-96.png';

import './UserInfo.css';

let isMounted;

/**
 * User info component
 * @param {{uname: string, onUpdate?: function, children?: React.ReactElement}} props
 */
export default function UserInfo({ uname, onUpdate, children }) {
    const [user, setUser] = useState({
        uname: uname,
        uid: 0
    });
    useEffect(() => {
        isMounted = true;
        info(uname).then(response => {
            if (isMounted) {
                onUpdate && onUpdate(response.data);
                setUser(response.data);
            }
        });
        return () => {
            isMounted = false;
        };
    }, [onUpdate, uname]);
    return (
        <>
            <div className="userinfo">
                <Avatar user={user}>
                    <div className="msg-ts">Was online recently</div>
                </Avatar>
            </div>
            <UserSummary user={user} />
            <div className="l">
                {
                    user.uid > 0 &&
                    <>
                        <Link to={`/pm/${user.uname}`}>
                            <Icon name="ei-envelope" size="s" />
                            <span className="desktop">PM</span>
                        </Link>
                        <Link to={`/${user.uname}/?show=recomm`} rel="nofollow">
                            <Icon name="ei-heart" size="s" />
                            <span className="desktop">Recommendations</span>
                        </Link>
                        <Link to={`/${user.uname}/?media=1`} rel="nofollow">
                            <Icon name="ei-camera" size="s" />
                            <span className="desktop">Photos</span>
                        </Link>
                    </>
                }
            </div>
            {children}
        </>
    );
}

/**
 * User summary component
 * @param {{user: import('../api').User}} props
 */
function Summary({ user }) {
    const readUrl = `/${user.uname}/friends`;
    const readersUrl = `/${user.uname}/readers`;
    const blUrl = `/${user.uname}/bl`;
    let read = user.read && <Link key={readUrl} to={readUrl}>I read: {user.read.length}</Link>;
    let readers = user.readers && <Link key={readersUrl} to={readersUrl}>My readers: {user.readers.length}</Link>;
    let mybl = user.statsMyBL && <Link key={blUrl} to={blUrl}>My blacklist: {user.statsMyBL}</Link>;
    let presentItems = [read, readers, mybl].filter(Boolean);
    return (
        <div className="msg-summary">
            {presentItems.length > 0 && presentItems.reduce((prev, curr) =>
                // @ts-ignore
                [prev, ' ', curr])}
        </div>
    );
}

const UserSummary = memo(Summary);


/**
 * Link to user
 * @param {{ user: import('../api').User}} props
 */
export function UserLink(props) {
    const [user, setUser] = useState(props.user);
    const userRef = useRef(user);
    useEffect(() => {
        isMounted = true;
        if (userRef.current.uri) {
            fetchUserUri(userRef.current.uri).then(remote_user => {
                if (isMounted) {
                    setUser({
                        uid: 0,
                        uname: remote_user.data.preferredUsername,
                        avatar: remote_user.data.icon && remote_user.data.icon.url,
                        uri: userRef.current.uri
                    });
                }
            }).catch(reason => {
                // TODO: debug logging
            });
        }
        return () => {
            isMounted = false;
        };
    }, [props.user]);
    return (
        user.uid ?
            <Link key={user.uid} to={`/${user.uname}/`} className="info-avatar">
                <img src={user.avatar} />{user.uname}
            </Link>
            : <a href={user.uri} className="info-avatar">
                <img src={user.avatar || defaultAvatar} />{user.uname}
            </a>
    );
}