Skip to content

Commit

Permalink
/issues/5009 - Refactored share extension and started using the share…
Browse files Browse the repository at this point in the history
…d code directly in the main application.
  • Loading branch information
stefanceriu committed Oct 14, 2021
1 parent 93e7089 commit ad1f412
Show file tree
Hide file tree
Showing 25 changed files with 615 additions and 598 deletions.
1 change: 1 addition & 0 deletions Riot/Assets/en.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ Tap the + to start adding people.";
"room_event_action_redact" = "Remove";
"room_event_action_more" = "More";
"room_event_action_share" = "Share";
"room_event_action_forward" = "Forward";
"room_event_action_permalink" = "Permalink";
"room_event_action_view_source" = "View Source";
"room_event_action_view_decrypted_source" = "View Decrypted Source";
Expand Down
15 changes: 14 additions & 1 deletion Riot/Generated/Images.swift
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ internal struct ImageAsset {
internal typealias Image = UIImage
#endif

@available(iOS 8.0, tvOS 9.0, watchOS 2.0, macOS 10.7, *)
internal var image: Image {
let bundle = BundleToken.bundle
#if os(iOS) || os(tvOS)
Expand All @@ -236,13 +237,25 @@ internal struct ImageAsset {
let image = Image(named: name)
#endif
guard let result = image else {
fatalError("Unable to load image named \(name).")
fatalError("Unable to load image asset named \(name).")
}
return result
}

#if os(iOS) || os(tvOS)
@available(iOS 8.0, tvOS 9.0, *)
internal func image(compatibleWith traitCollection: UITraitCollection) -> Image {
let bundle = BundleToken.bundle
guard let result = Image(named: name, in: bundle, compatibleWith: traitCollection) else {
fatalError("Unable to load image asset named \(name).")
}
return result
}
#endif
}

internal extension ImageAsset.Image {
@available(iOS 8.0, tvOS 9.0, watchOS 2.0, *)
@available(macOS, deprecated,
message: "This initializer is unsafe on macOS, please use the ImageAsset.image property")
convenience init!(asset: ImageAsset) {
Expand Down
4 changes: 4 additions & 0 deletions Riot/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2887,6 +2887,10 @@ public class VectorL10n: NSObject {
public static var roomEventActionEdit: String {
return VectorL10n.tr("Vector", "room_event_action_edit")
}
/// Forward
public static var roomEventActionForward: String {
return VectorL10n.tr("Vector", "room_event_action_forward")
}
/// Reason for kicking this user
public static var roomEventActionKickPromptReason: String {
return VectorL10n.tr("Vector", "room_event_action_kick_prompt_reason")
Expand Down
4 changes: 4 additions & 0 deletions Riot/Managers/AppInfo/BuildInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@

#import "BuildInfo.h"

#ifdef IS_SHARE_EXTENSION
#import "RiotShareExtension-Swift.h"
#else
#import "Riot-Swift.h"
#endif

#define MAKE_STRING(x) #x
#define MAKE_NS_STRING(x) @MAKE_STRING(x)
Expand Down
69 changes: 66 additions & 3 deletions Riot/Modules/Room/RoomViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
limitations under the License.
*/

@import MobileCoreServices;

#import "RoomViewController.h"

#import "RoomDataSource.h"
Expand Down Expand Up @@ -106,6 +108,7 @@
#import "AvatarGenerator.h"
#import "Tools.h"
#import "WidgetManager.h"
#import "ShareExtensionManager.h"

#import "GBDeviceInfo_iOS.h"

Expand Down Expand Up @@ -249,6 +252,8 @@ @interface RoomViewController () <UISearchBarDelegate, UIGestureRecognizerDelega
@property (nonatomic, strong) VoiceMessageController *voiceMessageController;
@property (nonatomic, strong) SpaceDetailPresenter *spaceDetailPresenter;

@property (nonatomic, strong) ShareExtensionManager *shareExtensionManager;

@end

@implementation RoomViewController
Expand Down Expand Up @@ -3159,6 +3164,25 @@ - (void)showAdditionalActionsMenuForEvent:(MXEvent*)selectedEvent inCell:(id<MXK
}]];
}

[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
NSExtensionItem *item = [[NSExtensionItem alloc] init];
item.attachments = @[[[NSItemProvider alloc] initWithItem:selectedComponent.textMessage typeIdentifier:(__bridge NSString *)kUTTypeText]];

self.shareExtensionManager = [[ShareExtensionManager alloc] initWithShareExtensionContext:nil
extensionItems:@[item]];

MXWeakify(self);
[self.shareExtensionManager setCompletionCallback:^(ShareExtensionManagerResult result) {
MXStrongifyAndReturnIfNil(self);
[attachment onShareEnded];
[self dismissViewControllerAnimated:YES completion:nil];
}];

[self presentViewController:self.shareExtensionManager.mainViewController animated:YES completion:nil];
}]];

if (!isJitsiCallEvent)
{
[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionQuote]
Expand Down Expand Up @@ -3309,7 +3333,10 @@ - (void)showAdditionalActionsMenuForEvent:(MXEvent*)selectedEvent inCell:(id<MXK

[self cancelEventSelection];

[self startActivityIndicator];

[attachment prepareShare:^(NSURL *fileURL) {
[self stopActivityIndicator];

__strong __typeof(weakSelf)self = weakSelf;
self->documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
Expand All @@ -3324,10 +3351,8 @@ - (void)showAdditionalActionsMenuForEvent:(MXEvent*)selectedEvent inCell:(id<MXK
}

} failure:^(NSError *error) {

//Alert user
[self showError:error];

[self stopActivityIndicator];
}];

// Start animation in case of download during attachment preparing
Expand All @@ -3337,6 +3362,44 @@ - (void)showAdditionalActionsMenuForEvent:(MXEvent*)selectedEvent inCell:(id<MXK
}]];
}
}

if (attachment.type == MXKAttachmentTypeFile ||
attachment.type == MXKAttachmentTypeImage ||
attachment.type == MXKAttachmentTypeVideo) {

[currentAlert addAction:[UIAlertAction actionWithTitle:[VectorL10n roomEventActionForward]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {

NSDictionary *attachmentTypeToIdentifier = @{@(MXKAttachmentTypeFile): (__bridge NSString *)kUTTypeFileURL,
@(MXKAttachmentTypeImage): (__bridge NSString *)kUTTypeImage,
@(MXKAttachmentTypeVideo): (__bridge NSString *)kUTTypeVideo};

[self startActivityIndicator];

[attachment prepareShare:^(NSURL *fileURL) {
[self stopActivityIndicator];

NSExtensionItem *item = [[NSExtensionItem alloc] init];
item.attachments = @[[[NSItemProvider alloc] initWithItem:fileURL typeIdentifier:attachmentTypeToIdentifier[@(attachment.type)]]];

self.shareExtensionManager = [[ShareExtensionManager alloc] initWithShareExtensionContext:nil
extensionItems:@[item]];

MXWeakify(self);
[self.shareExtensionManager setCompletionCallback:^(ShareExtensionManagerResult result) {
MXStrongifyAndReturnIfNil(self);
[attachment onShareEnded];
[self dismissViewControllerAnimated:YES completion:nil];
}];

[self presentViewController:self.shareExtensionManager.mainViewController animated:YES completion:nil];
} failure:^(NSError *error) {
[self showError:error];
[self stopActivityIndicator];
}];
}]];
}
}

// Check status of the selected event
Expand Down
1 change: 1 addition & 0 deletions Riot/SupportingFiles/Riot-Bridging-Header.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@
#import "RoomViewController.h"
#import "ContactDetailsViewController.h"
#import "GroupDetailsViewController.h"
#import "ShareExtensionRootViewController.h"
2 changes: 2 additions & 0 deletions Riot/target.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ targets:
excludes:
- "Modules/Room/EmojiPicker/Data/EmojiMart/EmojiJSONStore.swift"
- "**/*.strings" # Exclude all strings files
- path: ../RiotShareExtension/Managers
- path: ../RiotShareExtension/Modules

# Add separately localizable files
# Once a language has enough translations (>80%), it must be declared here
Expand Down
105 changes: 9 additions & 96 deletions RiotShareExtension/Managers/ShareExtensionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,111 +14,24 @@
limitations under the License.
*/

#import <Foundation/Foundation.h>
#import <MatrixKit/MatrixKit.h>

@class ShareExtensionManager;
@class SharePresentingViewController;
@protocol Configurable;

/**
Posted when the matrix user account and his data has been checked and updated.
The notification object is the MXKAccount instance.
*/
extern NSString *const kShareExtensionManagerDidUpdateAccountDataNotification;


/**
The protocol for the manager's delegate
*/
@protocol ShareExtensionManagerDelegate <NSObject>

@required

/**
Called when an image is going to be shared to show a compression prompt
@param extensionManager the ShareExtensionManager object that called the method
@param compressionPrompt the prompt that was prepared for the image which is going to be shared
*/
- (void)shareExtensionManager:(ShareExtensionManager *)extensionManager showImageCompressionPrompt:(UIAlertController *)compressionPrompt;

@optional

/**
Called when the manager starts sending the content to a room
@param extensionManager the ShareExtensionManager object that called the method
@param room the room where content will be sent
*/
- (void)shareExtensionManager:(ShareExtensionManager *)extensionManager didStartSendingContentToRoom:(MXRoom *)room;

/**
Called when the progress of the uploading media changes
@param extensionManager the ShareExtensionManager object that called the method
@param progress the current progress
*/
- (void)shareExtensionManager:(ShareExtensionManager *)extensionManager mediaUploadProgress:(CGFloat)progress;

@end


/**
A class used to share content from the extension
*/
typedef NS_ENUM(NSUInteger, ShareExtensionManagerResult) {
ShareExtensionManagerResultFinished,
ShareExtensionManagerResultCancelled,
ShareExtensionManagerResultFailed
};

@interface ShareExtensionManager : NSObject

/**
The share extension context that represents a user's sharing request, also stores the content to be shared
*/
@property (nonatomic) NSExtensionContext *shareExtensionContext;

/**
The share app extension’s primary view controller.
*/
@property (nonatomic) SharePresentingViewController *primaryViewController;

/**
The current user account
*/
@property (nonatomic, readonly) MXKAccount *userAccount;

/**
The shared file store
*/
@property (nonatomic, readonly) MXFileStore *fileStore;

/**
A delegate used to notify about needed UI changes when sharing
*/
@property (nonatomic, weak) id<ShareExtensionManagerDelegate> delegate;

// Build Settings
@property (nonatomic, readonly) id<Configurable> configuration;

/**
The singleton instance
*/
+ (instancetype)sharedManager;
@property (nonatomic, copy) void (^completionCallback)(ShareExtensionManagerResult);

/**
Send the content that the user has chosen to a room
@param room the room to send the content to
@param failureBlock the code to be executed when sharing has failed for whatever reason
note: there is no "successBlock" parameter because when the sharing succeeds, the extension needs to close itself
*/
- (void)sendContentToRoom:(MXRoom *)room failureBlock:(void(^)(NSError *error))failureBlock;

/**
Checks if there is an image in the user chosen content
@return YES if there is, NO otherwise
*/
- (BOOL)hasImageTypeContent;
- (instancetype)initWithShareExtensionContext:(NSExtensionContext *)shareExtensionContext
extensionItems:(NSArray<NSExtensionItem *> *)extensionItems;

/**
Terminate the extension and return to the app that started it
@param canceled YES if the user chose to cancel the sharing, NO otherwise
*/
- (void)terminateExtensionCanceled:(BOOL)canceled;
- (UIViewController *)mainViewController;

@end

Expand Down
Loading

0 comments on commit ad1f412

Please sign in to comment.