blob: 52558204848b6e2ac7fcfcb9351229f4fa3d3042 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4import {connectStore, store} from 'reducers/base.js';
5import * as users from 'reducers/users.js';
6import * as issueV0 from 'reducers/issueV0.js';
7import {issueRefToString} from 'shared/convertersV0.js';
8import {MrStar} from './mr-star.js';
9
10
11/**
12 * `<mr-issue-star>`
13 *
14 * A button for starring an issue.
15 *
16 */
17export class MrIssueStar extends connectStore(MrStar) {
18 /** @override */
19 static get properties() {
20 return {
21 /**
22 * A reference to the issue that the star button interacts with.
23 */
24 issueRef: {type: Object},
25 /**
26 * Whether the issue is starred (used for accessing easily).
27 */
28 _starredIssues: {type: Set},
29 /**
30 * Whether the issue's star state is being fetched. This is taken from
31 * the component's parent, which is expected to handle fetching initial
32 * star state for an issue.
33 */
34 _fetchingIsStarred: {type: Boolean},
35 /**
36 * A Map of all issues currently being starred.
37 */
38 _starringIssues: {type: Object},
39 /**
40 * The currently logged in user. Required to determine if the user can
41 * star.
42 */
43 _currentUserName: {type: String},
44 };
45 }
46
47 /** @override */
48 constructor() {
49 super();
50
51 /**
52 * @type {IssueRef}
53 */
54 this.issueRef = {};
55 }
56
57 /** @override */
58 stateChanged(state) {
59 this._currentUserName = users.currentUserName(state);
60
61 // TODO(crbug.com/monorail/7374): Remove references to issueV0 in
62 // <mr-star>.
63 this._starringIssues = issueV0.starringIssues(state);
64 this._starredIssues = issueV0.starredIssues(state);
65 this._fetchingIsStarred = issueV0.requests(state).fetchIsStarred.requesting;
66 }
67
68 /** @override */
69 get type() {
70 return 'issue';
71 }
72
73 /**
74 * @return {boolean} Whether there's an in-flight star request.
75 */
76 get _isStarring() {
77 const requestKey = issueRefToString(this.issueRef);
78 if (this._starringIssues.has(requestKey)) {
79 return this._starringIssues.get(requestKey).requesting;
80 }
81 return false;
82 }
83
84 /** @override */
85 get isLoggedIn() {
86 return !!this._currentUserName;
87 }
88
89 /** @override */
90 get requesting() {
91 return this._fetchingIsStarred || this._isStarring;
92 }
93
94 /** @override */
95 get isStarred() {
96 return this._starredIssues.has(issueRefToString(this.issueRef));
97 }
98
99 /** @override */
100 star() {
101 store.dispatch(issueV0.star(this.issueRef, true));
102 }
103
104 /** @override */
105 unstar() {
106 store.dispatch(issueV0.star(this.issueRef, false));
107 }
108}
109
110customElements.define('mr-issue-star', MrIssueStar);