// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_FOLLOW_MODEL_FOLLOW_BROWSER_AGENT_H_
#define IOS_CHROME_BROWSER_FOLLOW_MODEL_FOLLOW_BROWSER_AGENT_H_
#import <Foundation/Foundation.h>
#import "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "ios/chrome/browser/follow/model/follow_service.h"
#include "ios/chrome/browser/follow/model/follow_service_observer.h"
#include "ios/chrome/browser/shared/model/browser/browser_user_data.h"
@class FeedMetricsRecorder;
@protocol NewTabPageCommands;
@protocol SnackbarCommands;
@protocol FeedCommands;
// Manages the interaction with the FollowService for a Browser.
class FollowBrowserAgent final : public BrowserUserData<FollowBrowserAgent> {
public:
// FollowBrowserAgent uses the same observation API as FollowService.
using Observer = FollowServiceObserver;
FollowBrowserAgent(const FollowBrowserAgent&) = delete;
FollowBrowserAgent& operator=(const FollowBrowserAgent&) = delete;
~FollowBrowserAgent() final;
// Returns if a followed website corresponds to `web_page_urls`.
bool IsWebSiteFollowed(WebPageURLs* web_page_urls);
// If a recommended website corresponds to `web_page_urls`, returns
// the URL identifier for the website. Returns nil otherwise
NSURL* GetRecommendedSiteURL(WebPageURLs* web_page_urls);
// Returns a list of all followed websites.
NSArray<FollowedWebSite*>* GetFollowedWebSites();
// Loads all followed websites.
void LoadFollowedWebSites();
// Follows the website associated with `web_page_urls` and presents
// the UI (snackback, ...) when the operation completes. Nothing
// is presented if the web channel is already followed.
void FollowWebSite(WebPageURLs* web_page_urls, FollowSource source);
// Unfollows the website associated with `web_page_urls` and presents
// the UI (snackback, ...) when the operation completes. Nothing is
// presented if the web channel is not followed.
void UnfollowWebSite(WebPageURLs* web_page_urls, FollowSource source);
// Sets the UI providers.
void SetUIProviders(id<NewTabPageCommands> new_tab_page_commands,
id<SnackbarCommands> snack_bar_commands,
id<FeedCommands> feed_commands);
// Clears the UI providers.
void ClearUIProviders();
// Adds/Removes `observer`.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
private:
using MessageBlock = void (^)(void);
using CompletionBlock = void (^)(BOOL success);
friend class BrowserUserData<FollowBrowserAgent>;
base::WeakPtr<FollowBrowserAgent> AsWeakPtr();
explicit FollowBrowserAgent(Browser* browser);
// Show an overlay message at the bottom of the screen with action button.
// Invoked after a follow/unfollow request completes.
void ShowOverlayMessage(FollowSource source,
NSString* message,
NSString* button_text,
MessageBlock message_action,
CompletionBlock completion_action);
// Helper method that shows an overlay message at the bottom of the screen on
// invocation.
void ShowOverlayMessageHelper(NSString* message,
NSString* button_text,
MessageBlock message_action,
CompletionBlock completion_action);
// Invoked when a follow request completes.
void OnFollowResponse(WebPageURLs* web_page_urls,
FollowSource source,
FollowResult result,
FollowedWebSite* web_site);
// Invoked when an unfollow request completes.
void OnUnfollowResponse(WebPageURLs* web_page_urls,
FollowSource source,
FollowResult result,
FollowedWebSite* web_site);
// Helper methods to handle follow/unfollow successful/failed requests.
void OnFollowSuccess(WebPageURLs* web_page_urls,
FollowSource source,
FollowedWebSite* web_site);
void OnFollowFailure(WebPageURLs* web_page_urls,
FollowSource source,
FollowedWebSite* web_site);
void OnUnfollowSuccess(WebPageURLs* web_page_urls,
FollowSource source,
FollowedWebSite* web_site);
void OnUnfollowFailure(WebPageURLs* web_page_urls,
FollowSource source,
FollowedWebSite* web_site);
// Helper method to lazy initiate variables.
raw_ptr<FollowService> GetFollowService();
FeedMetricsRecorder* GetMetricsRecorder();
raw_ptr<Browser> browser_ = nullptr;
raw_ptr<FollowService> service_ = nullptr;
__weak id<NewTabPageCommands> new_tab_page_commands_;
__weak id<SnackbarCommands> snack_bar_commands_;
__weak id<FeedCommands> feed_commands_;
__weak FeedMetricsRecorder* metrics_recorder_;
base::WeakPtrFactory<FollowBrowserAgent> weak_ptr_factory_{this};
BROWSER_USER_DATA_KEY_DECL();
};
#endif // IOS_CHROME_BROWSER_FOLLOW_MODEL_FOLLOW_BROWSER_AGENT_H_