1package libkb
2
3import (
4	"github.com/keybase/client/go/protocol/keybase1"
5)
6
7type card struct {
8	Status        AppStatus `json:"status"`
9	FollowSummary struct {
10		UnverifiedNumFollowing int `json:"following"`
11		UnverifiedNumFollowers int `json:"followers"`
12	} `json:"follow_summary"`
13	Profile struct {
14		FullName string `json:"full_name"`
15		Location string `json:"location"`
16		Bio      string `json:"bio"`
17		Website  string `json:"website"`
18		Twitter  string `json:"twitter"`
19	} `json:"profile"`
20	TeamShowcase         []keybase1.UserTeamShowcase `json:"team_showcase"`
21	RegisteredForAirdrop bool                        `json:"airdrop_registered"`
22	StellarHidden        bool                        `json:"stellar_hidden"`
23	Blocked              bool                        `json:"blocked"`
24	UserBlocks           struct {
25		Chat   bool `json:"chat"`
26		Follow bool `json:"follow"`
27	} `json:"user_blocks"`
28}
29
30func (c *card) GetAppStatus() *AppStatus {
31	return &c.Status
32}
33
34func UserCard(m MetaContext, uid keybase1.UID, useSession bool) (ret *keybase1.UserCard, err error) {
35	defer m.Trace("UserCard", &err)()
36
37	cached, err := m.G().CardCache().Get(uid, useSession)
38	if err != nil {
39		m.Debug("CardCache.Get error: %s", err)
40	} else if cached != nil {
41		m.Debug("CardCache.Get hit for %s", uid)
42		return cached, nil
43	}
44	m.Debug("CardCache.Get miss for %s", uid)
45
46	sessionType := APISessionTypeNONE
47	if useSession {
48		sessionType = APISessionTypeREQUIRED
49	}
50	arg := APIArg{
51		Endpoint:    "user/card",
52		SessionType: sessionType,
53		Args:        HTTPArgs{"uid": S{Val: uid.String()}},
54	}
55
56	var card card
57
58	if err = m.G().API.GetDecode(m, arg, &card); err != nil {
59		m.Warning("error getting user/card for %s: %s\n", uid, err)
60		return nil, err
61	}
62
63	ret = &keybase1.UserCard{
64		UnverifiedNumFollowing: card.FollowSummary.UnverifiedNumFollowing,
65		UnverifiedNumFollowers: card.FollowSummary.UnverifiedNumFollowers,
66		Uid:                    uid,
67		FullName:               card.Profile.FullName,
68		Location:               card.Profile.Location,
69		Bio:                    card.Profile.Bio,
70		Website:                card.Profile.Website,
71		Twitter:                card.Profile.Twitter,
72		TeamShowcase:           card.TeamShowcase,
73		RegisteredForAirdrop:   card.RegisteredForAirdrop,
74		StellarHidden:          card.StellarHidden,
75		Blocked:                card.UserBlocks.Chat,
76		HidFromFollowers:       card.UserBlocks.Follow,
77	}
78
79	if err := m.G().CardCache().Set(ret, useSession); err != nil {
80		m.Debug("CardCache.Set error: %s", err)
81	}
82
83	return ret, nil
84}
85
86func displayUserCard(m MetaContext, uid keybase1.UID, useSession bool) error {
87	card, err := UserCard(m, uid, useSession)
88	if err != nil {
89		return err
90	}
91	if card == nil {
92		return nil
93	}
94
95	return m.UIs().IdentifyUI.DisplayUserCard(m, *card)
96}
97
98func DisplayUserCardAsync(m MetaContext, uid keybase1.UID, useSession bool) <-chan error {
99	ch := make(chan error)
100	go func() {
101		ch <- displayUserCard(m, uid, useSession)
102	}()
103	return ch
104}
105
106func GetFullName(m MetaContext, uid keybase1.UID) (string, error) {
107	card, err := UserCard(m, uid, false)
108	if err != nil {
109		return "", err
110	}
111	if card == nil {
112		return "", nil
113	}
114	return card.FullName, nil
115}
116