File: recent_activity_bubble_dialog_view.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (236 lines) | stat: -rw-r--r-- 8,577 bytes parent folder | download | duplicates (2)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_VIEWS_TABS_RECENT_ACTIVITY_BUBBLE_DIALOG_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_TABS_RECENT_ACTIVITY_BUBBLE_DIALOG_VIEW_H_

#include "base/scoped_observation.h"
#include "chrome/browser/ui/views/controls/hover_button.h"
#include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h"
#include "components/collaboration/public/messaging/activity_log.h"
#include "components/favicon_base/favicon_types.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/view_tracker.h"
#include "ui/views/widget/widget_observer.h"

namespace content {
class WebContents;
}  // namespace content

class Profile;

class RecentActivityRowView;
class RecentActivityRowImageView;

using collaboration::messaging::ActivityLogItem;

DECLARE_ELEMENT_IDENTIFIER_VALUE(kRecentActivityBubbleDialogId);

// The bubble dialog view housing the Shared Tab Group Recent Activity.
// Shows at most kMaxNumberRows of the activity_log parameter.
class RecentActivityBubbleDialogView : public LocationBarBubbleDelegateView,
                                       public ui::SimpleMenuModel::Delegate {
  METADATA_HEADER(RecentActivityBubbleDialogView, LocationBarBubbleDelegateView)

 public:
  enum OptionsMenuItem { SEE_ALL_ACTIVITY };

  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kCloseButtonId);
  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kSeeAllActivityId);

  RecentActivityBubbleDialogView(
      View* anchor_view,
      content::WebContents* web_contents,
      std::vector<ActivityLogItem> tab_activity_log,
      std::vector<ActivityLogItem> group_activity_log,
      Profile* profile);
  ~RecentActivityBubbleDialogView() override;

  // ui::SimpleMenuModel::Delegate:
  void ExecuteCommand(int command_id, int event_flags) override;

  // The maximum number of rows that can be displayed in this dialog.
  static constexpr int kMaxNumberRows = 5;

  // Creates a state indicating there is no activity to show.
  void CreateEmptyState();

  // Creates a view containing the single most recent tab activity.
  void CreateTabActivity();

  // Creates a view containing the most recent activity for the group.
  void CreateGroupActivity();

  // Returns the title view container including the title, the menu button, and
  // the close button.
  std::u16string GetTitleForTesting();

  // Returns the row's view at the given index. This will look in both
  // the tab activity container and the group activity container.
  RecentActivityRowView* GetRowForTesting(int n);

  views::View* tab_activity_container() const {
    return tab_activity_container_;
  }
  views::View* group_activity_container() const {
    return group_activity_container_;
  }

 private:
  // View IDs used for selecting views in tests.
  enum RecentActivityViewID {
    TITLE_VIEW_ID,
    TITLE_ID,
  };

  // Close this bubble.
  void Close();

  // Creates a button view for the close button.
  std::unique_ptr<views::Button> CreateCloseButton();

  // Creates a button view for the 3-dot menu button.
  std::unique_ptr<views::Button> CreateOptionsMenuButton();

  // Creates the top row of the dialog, including the title of the dialog, the
  // 3-dot menu button, and the close button.
  void CreateTitleView();

  // Displays a context menu anchored to |source|, allowing users to access
  // additional actions like "See All Activity".
  void ShowOptionsMenu(views::Button* source);

  std::unique_ptr<ui::SimpleMenuModel> options_menu_model_;
  std::unique_ptr<views::MenuRunner> options_menu_runner_;

  // Containers will always be non-null. Visibility is toggled based on
  // whether rows are added to each container.
  raw_ptr<views::View> tab_activity_container_ = nullptr;
  raw_ptr<views::View> group_activity_container_ = nullptr;

  std::vector<ActivityLogItem> tab_activity_log_;
  std::vector<ActivityLogItem> group_activity_log_;
  const raw_ptr<Profile> profile_;

  base::WeakPtrFactory<RecentActivityBubbleDialogView> weak_factory_{this};
};

// View containing a single ActivityLogItem. Each row shows activity
// text, metadata text, and an avatar/favicon view.
class RecentActivityRowView : public HoverButton {
  METADATA_HEADER(RecentActivityRowView, View)

 public:
  RecentActivityRowView(ActivityLogItem item,
                        Profile* profile,
                        base::OnceCallback<void()> close_callback);
  ~RecentActivityRowView() override;

  // HoverButton
  void ButtonPressed();

  RecentActivityRowImageView* image_view() const { return image_view_; }

  // RecentActivityAction handlers.
  // Focuses the open tab in the tab strip.
  void FocusTab();
  // Reopens the tab at the end of the group.
  void ReopenTab();
  // Opens the Tab Group editor bubble for the group.
  void OpenTabGroupEditDialog();
  // Opens the Data Sharing management bubble for the group.
  void ManageSharing();

 private:
  raw_ptr<RecentActivityRowImageView> image_view_ = nullptr;
  ActivityLogItem item_;
  const raw_ptr<Profile> profile_ = nullptr;
  base::OnceCallback<void()> close_callback_;
};

// View containing the avatar image and, if the event refers to a tab, the
// favicon of the tab. This view performs both asynchronous image fetches.
class RecentActivityRowImageView : public views::View {
  METADATA_HEADER(RecentActivityRowImageView, View)

 public:
  RecentActivityRowImageView(ActivityLogItem item, Profile* profile);
  ~RecentActivityRowImageView() override;

  // Returns whether there is an avatar image to show.
  bool ShouldShowAvatar() const { return avatar_request_complete_; }

  // Returns whether there is a favicon image to show.
  bool ShouldShowFavicon() const { return !resized_favicon_image_.isNull(); }

 private:
  // views::View
  void OnPaint(gfx::Canvas* canvas) override;

  // Perform the avatar fetch, calling `SetAvatar` when complete.
  void FetchAvatar();
  void SetAvatar(const gfx::Image& avatar);

  // Perform the favicon fetch, calling `SetFavicon` when complete.
  void FetchFavicon();
  void SetFavicon(const favicon_base::FaviconImageResult& favicon);
  void PaintFavicon(gfx::Canvas* canvas, const gfx::Rect& avatar_bounds);
  void PaintPlaceholderBackground(gfx::Canvas* canvas, const gfx::Rect& bounds);
  void PaintFallbackIcon(gfx::Canvas* canvas, const gfx::Rect& bounds);

  // When the avatar request is complete (or there is no avatar to
  // request), this will be set to true. While the value is false, we
  // will paint the background color as a placeholder for the avatar.
  bool avatar_request_complete_ = false;

  base::CancelableTaskTracker favicon_fetching_task_tracker_;
  gfx::ImageSkia avatar_image_;
  gfx::ImageSkia resized_favicon_image_;
  ActivityLogItem item_;
  const raw_ptr<Profile> profile_ = nullptr;

  base::WeakPtrFactory<RecentActivityRowImageView> weak_factory_{this};
};

// The bubble coordinator for Shared Tab Group Recent Activity.
class RecentActivityBubbleCoordinator : public views::WidgetObserver {
 public:
  RecentActivityBubbleCoordinator();
  ~RecentActivityBubbleCoordinator() override;

  // WidgetObserver:
  void OnWidgetDestroying(views::Widget* widget) override;

  // The RecentActivity dialog is used in multiple places, anchoring to
  // different items. Two public method overloads are supplied here so
  // the correct arrow will be used.
  //
  // Calls ShowCommon with the default arrow.
  void Show(views::View* anchor_view,
            content::WebContents* web_contents,
            std::vector<ActivityLogItem> activity_log,
            Profile* profile);
  // Same as above, but provides a default arrow for anchoring to the
  // page action. The default for location bar bubbles is to have a
  // TOP_RIGHT arrow.
  void ShowForCurrentTab(views::View* anchor_view,
                         content::WebContents* web_contents,
                         std::vector<ActivityLogItem> tab_activity_log,
                         std::vector<ActivityLogItem> group_activity_log,
                         Profile* profile);
  void Hide();

  RecentActivityBubbleDialogView* GetBubble() const;
  bool IsShowing();

 private:
  // Show a bubble containing the given activity log.
  void ShowCommon(std::unique_ptr<RecentActivityBubbleDialogView> bubble);

  views::ViewTracker tracker_;
  base::ScopedObservation<views::Widget, views::WidgetObserver>
      bubble_widget_observation_{this};
};

#endif  // CHROME_BROWSER_UI_VIEWS_TABS_RECENT_ACTIVITY_BUBBLE_DIALOG_VIEW_H_