Project import generated by Copybara.
GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/static_src/elements/framework/mr-star/mr-issue-star.js b/static_src/elements/framework/mr-star/mr-issue-star.js
new file mode 100644
index 0000000..5255820
--- /dev/null
+++ b/static_src/elements/framework/mr-star/mr-issue-star.js
@@ -0,0 +1,110 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+import {connectStore, store} from 'reducers/base.js';
+import * as users from 'reducers/users.js';
+import * as issueV0 from 'reducers/issueV0.js';
+import {issueRefToString} from 'shared/convertersV0.js';
+import {MrStar} from './mr-star.js';
+
+
+/**
+ * `<mr-issue-star>`
+ *
+ * A button for starring an issue.
+ *
+ */
+export class MrIssueStar extends connectStore(MrStar) {
+ /** @override */
+ static get properties() {
+ return {
+ /**
+ * A reference to the issue that the star button interacts with.
+ */
+ issueRef: {type: Object},
+ /**
+ * Whether the issue is starred (used for accessing easily).
+ */
+ _starredIssues: {type: Set},
+ /**
+ * Whether the issue's star state is being fetched. This is taken from
+ * the component's parent, which is expected to handle fetching initial
+ * star state for an issue.
+ */
+ _fetchingIsStarred: {type: Boolean},
+ /**
+ * A Map of all issues currently being starred.
+ */
+ _starringIssues: {type: Object},
+ /**
+ * The currently logged in user. Required to determine if the user can
+ * star.
+ */
+ _currentUserName: {type: String},
+ };
+ }
+
+ /** @override */
+ constructor() {
+ super();
+
+ /**
+ * @type {IssueRef}
+ */
+ this.issueRef = {};
+ }
+
+ /** @override */
+ stateChanged(state) {
+ this._currentUserName = users.currentUserName(state);
+
+ // TODO(crbug.com/monorail/7374): Remove references to issueV0 in
+ // <mr-star>.
+ this._starringIssues = issueV0.starringIssues(state);
+ this._starredIssues = issueV0.starredIssues(state);
+ this._fetchingIsStarred = issueV0.requests(state).fetchIsStarred.requesting;
+ }
+
+ /** @override */
+ get type() {
+ return 'issue';
+ }
+
+ /**
+ * @return {boolean} Whether there's an in-flight star request.
+ */
+ get _isStarring() {
+ const requestKey = issueRefToString(this.issueRef);
+ if (this._starringIssues.has(requestKey)) {
+ return this._starringIssues.get(requestKey).requesting;
+ }
+ return false;
+ }
+
+ /** @override */
+ get isLoggedIn() {
+ return !!this._currentUserName;
+ }
+
+ /** @override */
+ get requesting() {
+ return this._fetchingIsStarred || this._isStarring;
+ }
+
+ /** @override */
+ get isStarred() {
+ return this._starredIssues.has(issueRefToString(this.issueRef));
+ }
+
+ /** @override */
+ star() {
+ store.dispatch(issueV0.star(this.issueRef, true));
+ }
+
+ /** @override */
+ unstar() {
+ store.dispatch(issueV0.star(this.issueRef, false));
+ }
+}
+
+customElements.define('mr-issue-star', MrIssueStar);