mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-22 01:22:46 +02:00
Merge MatrixKit develop with commit hash: b85b736313bec0592bd1cabc68035d97f5331137
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
@import Foundation;
|
||||
|
||||
#import "MXKErrorPresentation.h"
|
||||
|
||||
/**
|
||||
`MXKErrorAlertPresentation` is a concrete implementation of `MXKErrorPresentation` using UIAlertViewController. Display error alert from a view controller.
|
||||
*/
|
||||
@interface MXKErrorAlertPresentation : NSObject<MXKErrorPresentation>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKErrorAlertPresentation.h"
|
||||
|
||||
#import "MXKErrorPresentableBuilder.h"
|
||||
#import "NSBundle+MatrixKit.h"
|
||||
|
||||
#import "MXKSwiftHeader.h"
|
||||
|
||||
@interface MXKErrorAlertPresentation()
|
||||
|
||||
@property (nonatomic, strong) MXKErrorPresentableBuilder *errorPresentableBuidler;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - Implementation
|
||||
|
||||
@implementation MXKErrorAlertPresentation
|
||||
|
||||
#pragma mark - Setup & Teardown
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_errorPresentableBuidler = [[MXKErrorPresentableBuilder alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - MXKErrorPresentation
|
||||
|
||||
- (void)presentErrorFromViewController:(UIViewController*)viewController
|
||||
title:(NSString*)title
|
||||
message:(NSString*)message
|
||||
animated:(BOOL)animated
|
||||
handler:(void (^)(void))handler
|
||||
{
|
||||
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[alert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ok]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * _Nonnull action) {
|
||||
if (handler)
|
||||
{
|
||||
handler();
|
||||
}
|
||||
}]];
|
||||
|
||||
[viewController presentViewController:alert animated:animated completion:nil];
|
||||
}
|
||||
|
||||
- (void)presentErrorFromViewController:(UIViewController*)viewController
|
||||
forError:(NSError*)error
|
||||
animated:(BOOL)animated
|
||||
handler:(void (^)(void))handler
|
||||
{
|
||||
id <MXKErrorPresentable> errorPresentable = [self.errorPresentableBuidler errorPresentableFromError:error];
|
||||
|
||||
if (errorPresentable)
|
||||
{
|
||||
[self presentErrorFromViewController:viewController
|
||||
forErrorPresentable:errorPresentable
|
||||
animated:animated
|
||||
handler:handler];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)presentGenericErrorFromViewController:(UIViewController*)viewController
|
||||
animated:(BOOL)animated
|
||||
handler:(void (^)(void))handler
|
||||
{
|
||||
id <MXKErrorPresentable> errorPresentable = [self.errorPresentableBuidler commonErrorPresentable];
|
||||
|
||||
[self presentErrorFromViewController:viewController
|
||||
forErrorPresentable:errorPresentable
|
||||
animated:animated
|
||||
handler:handler];
|
||||
}
|
||||
|
||||
- (void)presentErrorFromViewController:(UIViewController*)viewController
|
||||
forErrorPresentable:(id<MXKErrorPresentable>)errorPresentable
|
||||
animated:(BOOL)animated
|
||||
handler:(void (^)(void))handler
|
||||
{
|
||||
[self presentErrorFromViewController:viewController
|
||||
title:errorPresentable.title
|
||||
message:errorPresentable.message
|
||||
animated:animated
|
||||
handler:handler];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
`MXKErrorPresentable` describe an error to display on screen.
|
||||
*/
|
||||
@protocol MXKErrorPresentable
|
||||
|
||||
@required
|
||||
|
||||
@property (strong, nonatomic, readonly) NSString *title;
|
||||
@property (strong, nonatomic, readonly) NSString *message;
|
||||
|
||||
- (id)initWithTitle:(NSString*)title message:(NSString*)message;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
@import Foundation;
|
||||
|
||||
#import "MXKErrorPresentable.h"
|
||||
|
||||
/**
|
||||
`MXKErrorPresentableBuilder` enable to create error to present on screen.
|
||||
*/
|
||||
@interface MXKErrorPresentableBuilder : NSObject
|
||||
|
||||
/**
|
||||
Build a displayable error from a NSError.
|
||||
|
||||
@param error an NSError.
|
||||
@return Return nil in case of network request cancellation error otherwise return a presentable error from NSError informations.
|
||||
*/
|
||||
- (id <MXKErrorPresentable>)errorPresentableFromError:(NSError*)error;
|
||||
|
||||
/**
|
||||
Build a common displayable error. Generic error message to present as fallback when error explanation can't be user friendly.
|
||||
|
||||
@return Common default error.
|
||||
*/
|
||||
- (id <MXKErrorPresentable>)commonErrorPresentable;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKErrorPresentableBuilder.h"
|
||||
|
||||
#import "NSBundle+MatrixKit.h"
|
||||
#import "MXKErrorViewModel.h"
|
||||
|
||||
#import "MXKSwiftHeader.h"
|
||||
|
||||
@implementation MXKErrorPresentableBuilder
|
||||
|
||||
- (id <MXKErrorPresentable>)errorPresentableFromError:(NSError*)error
|
||||
{
|
||||
// Ignore nil error or connection cancellation error
|
||||
if (!error || ([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled))
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString *title = [error.userInfo valueForKey:NSLocalizedFailureReasonErrorKey];
|
||||
NSString *message = [error.userInfo valueForKey:NSLocalizedDescriptionKey];
|
||||
|
||||
if (!title)
|
||||
{
|
||||
title = [MatrixKitL10n error];
|
||||
}
|
||||
|
||||
if (!message)
|
||||
{
|
||||
message = [MatrixKitL10n errorCommonMessage];
|
||||
}
|
||||
|
||||
return [[MXKErrorViewModel alloc] initWithTitle:title message:message];
|
||||
}
|
||||
|
||||
- (id <MXKErrorPresentable>)commonErrorPresentable
|
||||
{
|
||||
return [[MXKErrorViewModel alloc] initWithTitle:[MatrixKitL10n error]
|
||||
message:[MatrixKitL10n errorCommonMessage]];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
@import Foundation;
|
||||
@import UIKit;
|
||||
|
||||
#import "MXKErrorPresentable.h"
|
||||
|
||||
/**
|
||||
`MXKErrorPresentation` describe an error display handler for presenting error from a view controller.
|
||||
*/
|
||||
@protocol MXKErrorPresentation
|
||||
|
||||
- (void)presentErrorFromViewController:(UIViewController*)viewController
|
||||
title:(NSString*)title
|
||||
message:(NSString*)message
|
||||
animated:(BOOL)animated
|
||||
handler:(void (^)(void))handler;
|
||||
|
||||
- (void)presentErrorFromViewController:(UIViewController*)viewController
|
||||
forError:(NSError*)error
|
||||
animated:(BOOL)animated
|
||||
handler:(void (^)(void))handler;
|
||||
|
||||
- (void)presentGenericErrorFromViewController:(UIViewController*)viewController
|
||||
animated:(BOOL)animated
|
||||
handler:(void (^)(void))handler;
|
||||
|
||||
@required
|
||||
|
||||
- (void)presentErrorFromViewController:(UIViewController*)viewController
|
||||
forErrorPresentable:(id<MXKErrorPresentable>)errorPresentable
|
||||
animated:(BOOL)animated
|
||||
handler:(void (^)(void))handler;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
@import Foundation;
|
||||
|
||||
#import "MXKErrorPresentable.h"
|
||||
|
||||
/**
|
||||
`MXKErrorViewModel` is a concrete implementation of `MXKErrorPresentable`
|
||||
*/
|
||||
@interface MXKErrorViewModel : NSObject<MXKErrorPresentable>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKErrorViewModel.h"
|
||||
|
||||
@interface MXKErrorViewModel()
|
||||
|
||||
@property (strong, nonatomic) NSString *title;
|
||||
@property (strong, nonatomic) NSString *message;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MXKErrorViewModel
|
||||
|
||||
- (id)initWithTitle:(NSString*)title message:(NSString*)message
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self)
|
||||
{
|
||||
_title = title;
|
||||
_message = message;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
|
||||
#import "MXKAppSettings.h"
|
||||
|
||||
@protocol MarkdownToHTMLRendererProtocol;
|
||||
/**
|
||||
Formatting result codes.
|
||||
*/
|
||||
typedef enum : NSUInteger {
|
||||
|
||||
/**
|
||||
The formatting was successful.
|
||||
*/
|
||||
MXKEventFormatterErrorNone = 0,
|
||||
|
||||
/**
|
||||
The formatter knows the event type but it encountered data that it does not support.
|
||||
*/
|
||||
MXKEventFormatterErrorUnsupported,
|
||||
|
||||
/**
|
||||
The formatter encountered unexpected data in the event.
|
||||
*/
|
||||
MXKEventFormatterErrorUnexpected,
|
||||
|
||||
/**
|
||||
The formatter does not support the type of the passed event.
|
||||
*/
|
||||
MXKEventFormatterErrorUnknownEventType
|
||||
|
||||
} MXKEventFormatterError;
|
||||
|
||||
/**
|
||||
`MXKEventFormatter` is an utility class for formating Matrix events into strings which
|
||||
will be displayed to the end user.
|
||||
*/
|
||||
@interface MXKEventFormatter : NSObject <MXRoomSummaryUpdating>
|
||||
{
|
||||
@protected
|
||||
/**
|
||||
The matrix session. Used to get contextual data.
|
||||
*/
|
||||
MXSession *mxSession;
|
||||
|
||||
/**
|
||||
The date formatter used to build date string without time information.
|
||||
*/
|
||||
NSDateFormatter *dateFormatter;
|
||||
|
||||
/**
|
||||
The time formatter used to build time string without date information.
|
||||
*/
|
||||
NSDateFormatter *timeFormatter;
|
||||
|
||||
/**
|
||||
The default room summary updater from the MXSession.
|
||||
*/
|
||||
MXRoomSummaryUpdater *defaultRoomSummaryUpdater;
|
||||
}
|
||||
|
||||
/**
|
||||
The settings used to handle room events.
|
||||
|
||||
By default the shared application settings are considered.
|
||||
*/
|
||||
@property (nonatomic) MXKAppSettings *settings;
|
||||
|
||||
/**
|
||||
Flag indicating if the formatter must build strings that will be displayed as subtitle.
|
||||
Default is NO.
|
||||
*/
|
||||
@property (nonatomic) BOOL isForSubtitle;
|
||||
|
||||
/**
|
||||
Flags indicating if the formatter must create clickable links for Matrix user ids,
|
||||
room ids, room aliases or event ids.
|
||||
Default is NO.
|
||||
*/
|
||||
@property (nonatomic) BOOL treatMatrixUserIdAsLink;
|
||||
@property (nonatomic) BOOL treatMatrixRoomIdAsLink;
|
||||
@property (nonatomic) BOOL treatMatrixRoomAliasAsLink;
|
||||
@property (nonatomic) BOOL treatMatrixEventIdAsLink;
|
||||
@property (nonatomic) BOOL treatMatrixGroupIdAsLink;
|
||||
|
||||
/**
|
||||
Initialise the event formatter.
|
||||
|
||||
@param mxSession the Matrix to retrieve contextual data.
|
||||
@return the newly created instance.
|
||||
*/
|
||||
- (instancetype)initWithMatrixSession:(MXSession*)mxSession;
|
||||
|
||||
/**
|
||||
Initialise the date and time formatters.
|
||||
This formatter could require to be updated after updating the device settings.
|
||||
e.g the time format switches from 24H format to AM/PM.
|
||||
*/
|
||||
- (void)initDateTimeFormatters;
|
||||
|
||||
/**
|
||||
The types of events allowed to be displayed in the room history.
|
||||
No string will be returned by the formatter for the events whose the type doesn't belong to this array.
|
||||
|
||||
Default is nil. All messages types are displayed.
|
||||
*/
|
||||
@property (nonatomic) NSArray<NSString*> *eventTypesFilterForMessages;
|
||||
|
||||
@property (nonatomic, strong) id<MarkdownToHTMLRendererProtocol> markdownToHTMLRenderer;
|
||||
|
||||
/**
|
||||
Checks whether the event is related to an attachment and if it is supported.
|
||||
|
||||
@param event an event.
|
||||
@return YES if the provided event is related to a supported attachment type.
|
||||
*/
|
||||
- (BOOL)isSupportedAttachment:(MXEvent*)event;
|
||||
|
||||
#pragma mark - Events to strings conversion methods
|
||||
/**
|
||||
Compose the event sender display name according to the current room state.
|
||||
|
||||
@param event the event to format.
|
||||
@param roomState the room state right before the event.
|
||||
@return the sender display name
|
||||
*/
|
||||
- (NSString*)senderDisplayNameForEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState;
|
||||
|
||||
/**
|
||||
Compose the event target display name according to the current room state.
|
||||
|
||||
@discussion "target" refers to the room member who is the target of this event (if any), e.g.
|
||||
the invitee, the person being banned, etc.
|
||||
|
||||
@param event the event to format.
|
||||
@param roomState the room state right before the event.
|
||||
@return the target display name (if any)
|
||||
*/
|
||||
- (NSString*)targetDisplayNameForEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState;
|
||||
|
||||
/**
|
||||
Retrieve the avatar url of the event sender from the current room state.
|
||||
|
||||
@param event the event to format.
|
||||
@param roomState the room state right before the event.
|
||||
@return the sender avatar url
|
||||
*/
|
||||
- (NSString*)senderAvatarUrlForEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState;
|
||||
|
||||
/**
|
||||
Retrieve the avatar url of the event target from the current room state.
|
||||
|
||||
@discussion "target" refers to the room member who is the target of this event (if any), e.g.
|
||||
the invitee, the person being banned, etc.
|
||||
|
||||
@param event the event to format.
|
||||
@param roomState the room state right before the event.
|
||||
@return the target avatar url (if any)
|
||||
*/
|
||||
- (NSString*)targetAvatarUrlForEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState;
|
||||
|
||||
/**
|
||||
Generate a displayable string representating the event.
|
||||
|
||||
@param event the event to format.
|
||||
@param roomState the room state right before the event.
|
||||
@param error the error code. In case of formatting error, the formatter may return non nil string as a proposal.
|
||||
@return the display text for the event.
|
||||
*/
|
||||
- (NSString*)stringFromEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState error:(MXKEventFormatterError*)error;
|
||||
|
||||
/**
|
||||
Generate a displayable attributed string representating the event.
|
||||
|
||||
@param event the event to format.
|
||||
@param roomState the room state right before the event.
|
||||
@param error the error code. In case of formatting error, the formatter may return non nil string as a proposal.
|
||||
@return the attributed string for the event.
|
||||
*/
|
||||
- (NSAttributedString*)attributedStringFromEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState error:(MXKEventFormatterError*)error;
|
||||
|
||||
/**
|
||||
Generate a displayable attributed string representating a summary for the provided events.
|
||||
|
||||
@param events the series of events to format.
|
||||
@param roomState the room state right before the first event in the series.
|
||||
@param error the error code. In case of formatting error, the formatter may return non nil string as a proposal.
|
||||
@return the attributed string.
|
||||
*/
|
||||
- (NSAttributedString*)attributedStringFromEvents:(NSArray<MXEvent*>*)events withRoomState:(MXRoomState*)roomState error:(MXKEventFormatterError*)error;
|
||||
|
||||
/**
|
||||
Render a random string into an attributed string with the font and the text color
|
||||
that correspond to the passed event.
|
||||
|
||||
@param string the string to render.
|
||||
@param event the event associated to the string.
|
||||
@return an attributed string.
|
||||
*/
|
||||
- (NSAttributedString*)renderString:(NSString*)string forEvent:(MXEvent*)event;
|
||||
|
||||
/**
|
||||
Render a random html string into an attributed string with the font and the text color
|
||||
that correspond to the passed event.
|
||||
|
||||
@param htmlString the HTLM string to render.
|
||||
@param event the event associated to the string.
|
||||
@param roomState the room state right before the event.
|
||||
@return an attributed string.
|
||||
*/
|
||||
- (NSAttributedString*)renderHTMLString:(NSString*)htmlString forEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState;
|
||||
|
||||
/**
|
||||
Same as [self renderString:forEvent:] but add a prefix.
|
||||
The prefix will be rendered with 'prefixTextFont' and 'prefixTextColor'.
|
||||
|
||||
@param string the string to render.
|
||||
@param prefix the prefix to add.
|
||||
@param event the event associated to the string.
|
||||
@return an attributed string.
|
||||
*/
|
||||
- (NSAttributedString*)renderString:(NSString*)string withPrefix:(NSString*)prefix forEvent:(MXEvent*)event;
|
||||
|
||||
#pragma mark - Conversion tools
|
||||
|
||||
/**
|
||||
Convert a Markdown string to HTML.
|
||||
|
||||
@param markdownString the string to convert.
|
||||
@return an HTML formatted string.
|
||||
*/
|
||||
- (NSString*)htmlStringFromMarkdownString:(NSString*)markdownString;
|
||||
|
||||
#pragma mark - Timestamp formatting
|
||||
|
||||
/**
|
||||
Generate the date in string format corresponding to the date.
|
||||
|
||||
@param date The date.
|
||||
@param time The flag used to know if the returned string must include time information or not.
|
||||
@return the string representation of the date.
|
||||
*/
|
||||
- (NSString*)dateStringFromDate:(NSDate *)date withTime:(BOOL)time;
|
||||
|
||||
/**
|
||||
Generate the date in string format corresponding to the timestamp.
|
||||
The returned string is localised according to the current device settings.
|
||||
|
||||
@param timestamp The timestamp in milliseconds since Epoch.
|
||||
@param time The flag used to know if the returned string must include time information or not.
|
||||
@return the string representation of the date.
|
||||
*/
|
||||
- (NSString*)dateStringFromTimestamp:(uint64_t)timestamp withTime:(BOOL)time;
|
||||
|
||||
/**
|
||||
Generate the date in string format corresponding to the event.
|
||||
The returned string is localised according to the current device settings.
|
||||
|
||||
@param event The event to format.
|
||||
@param time The flag used to know if the returned string must include time information or not.
|
||||
@return the string representation of the event date.
|
||||
*/
|
||||
- (NSString*)dateStringFromEvent:(MXEvent*)event withTime:(BOOL)time;
|
||||
|
||||
/**
|
||||
Generate the time string of the provided date by considered the current system time formatting.
|
||||
|
||||
@param date The date.
|
||||
@return the string representation of the time component of the date.
|
||||
*/
|
||||
- (NSString*)timeStringFromDate:(NSDate *)date;
|
||||
|
||||
|
||||
# pragma mark - Customisation
|
||||
/**
|
||||
The list of allowed HTML tags in rendered attributed strings.
|
||||
*/
|
||||
@property (nonatomic) NSArray<NSString*> *allowedHTMLTags;
|
||||
|
||||
/**
|
||||
A block to run on HTML `img` tags when calling `renderHTMLString:forEvent:withRoomState:`.
|
||||
|
||||
This block provides the original URL for the image and can be used to download the image locally
|
||||
and return a local file URL for the image to attach to the rendered attributed string.
|
||||
*/
|
||||
@property (nonatomic, copy) NSURL* (^htmlImageHandler)(NSString *sourceURL, CGFloat width, CGFloat height);
|
||||
|
||||
/**
|
||||
The style sheet used by the 'renderHTMLString' method.
|
||||
*/
|
||||
@property (nonatomic) NSString *defaultCSS;
|
||||
|
||||
/**
|
||||
Default color used to display text content of event.
|
||||
Default is [UIColor blackColor].
|
||||
*/
|
||||
@property (nonatomic) UIColor *defaultTextColor;
|
||||
|
||||
/**
|
||||
Default color used to display text content of event when it is displayed as subtitle (related to 'isForSubtitle' property).
|
||||
Default is [UIColor blackColor].
|
||||
*/
|
||||
@property (nonatomic) UIColor *subTitleTextColor;
|
||||
|
||||
/**
|
||||
Color applied on the event description prefix used to display for example the message sender name.
|
||||
Default is [UIColor blackColor].
|
||||
*/
|
||||
@property (nonatomic) UIColor *prefixTextColor;
|
||||
|
||||
/**
|
||||
Color used when the event must be bing to the end user. This happens when the event
|
||||
matches the user's push rules.
|
||||
Default is [UIColor blueColor].
|
||||
*/
|
||||
@property (nonatomic) UIColor *bingTextColor;
|
||||
|
||||
/**
|
||||
Color used to display text content of an event being encrypted.
|
||||
Default is [UIColor lightGrayColor].
|
||||
*/
|
||||
@property (nonatomic) UIColor *encryptingTextColor;
|
||||
|
||||
/**
|
||||
Color used to display text content of an event being sent.
|
||||
Default is [UIColor lightGrayColor].
|
||||
*/
|
||||
@property (nonatomic) UIColor *sendingTextColor;
|
||||
|
||||
/**
|
||||
Color used to display error text.
|
||||
Default is red.
|
||||
*/
|
||||
@property (nonatomic) UIColor *errorTextColor;
|
||||
|
||||
/**
|
||||
Color used to display the side border of HTML blockquotes.
|
||||
Default is a grey.
|
||||
*/
|
||||
@property (nonatomic) UIColor *htmlBlockquoteBorderColor;
|
||||
|
||||
/**
|
||||
Default text font used to display text content of event.
|
||||
Default is SFUIText-Regular 14.
|
||||
*/
|
||||
@property (nonatomic) UIFont *defaultTextFont;
|
||||
|
||||
/**
|
||||
Font applied on the event description prefix used to display for example the message sender name.
|
||||
Default is SFUIText-Regular 14.
|
||||
*/
|
||||
@property (nonatomic) UIFont *prefixTextFont;
|
||||
|
||||
/**
|
||||
Text font used when the event must be bing to the end user. This happens when the event
|
||||
matches the user's push rules.
|
||||
Default is SFUIText-Regular 14.
|
||||
*/
|
||||
@property (nonatomic) UIFont *bingTextFont;
|
||||
|
||||
/**
|
||||
Text font used when the event is a state event.
|
||||
Default is italic SFUIText-Regular 14.
|
||||
*/
|
||||
@property (nonatomic) UIFont *stateEventTextFont;
|
||||
|
||||
/**
|
||||
Text font used to display call notices (invite, answer, hangup).
|
||||
Default is SFUIText-Regular 14.
|
||||
*/
|
||||
@property (nonatomic) UIFont *callNoticesTextFont;
|
||||
|
||||
/**
|
||||
Text font used to display encrypted messages.
|
||||
Default is SFUIText-Regular 14.
|
||||
*/
|
||||
@property (nonatomic) UIFont *encryptedMessagesTextFont;
|
||||
|
||||
/**
|
||||
Text font used to display message containing a single emoji.
|
||||
Default is nil (same font as self.emojiOnlyTextFont).
|
||||
*/
|
||||
@property (nonatomic) UIFont *singleEmojiTextFont;
|
||||
|
||||
/**
|
||||
Text font used to display message containing only emojis.
|
||||
Default is nil (same font as self.defaultTextFont).
|
||||
*/
|
||||
@property (nonatomic) UIFont *emojiOnlyTextFont;
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
@import Foundation;
|
||||
|
||||
#import <MatrixSDK/MXRoomNameStringLocalizerProtocol.h>
|
||||
|
||||
/**
|
||||
The `MXKRoomNameStringLocalizer` implements localization strings for `MXRoomNameStringLocalizerProtocol`.
|
||||
*/
|
||||
@interface MXKRoomNameStringLocalizer : NSObject <MXRoomNameStringLocalizerProtocol>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomNameStringLocalizer.h"
|
||||
#import "MXKSwiftHeader.h"
|
||||
|
||||
@implementation MXKRoomNameStringLocalizer
|
||||
|
||||
- (NSString *)emptyRoom
|
||||
{
|
||||
return [MatrixKitL10n roomDisplaynameEmptyRoom];
|
||||
}
|
||||
|
||||
- (NSString *)twoMembers:(NSString *)firstMember second:(NSString *)secondMember
|
||||
{
|
||||
return [MatrixKitL10n roomDisplaynameTwoMembers:firstMember :secondMember];
|
||||
}
|
||||
|
||||
- (NSString *)moreThanTwoMembers:(NSString *)firstMember count:(NSNumber *)memberCount
|
||||
{
|
||||
return [MatrixKitL10n roomDisplaynameMoreThanTwoMembers:firstMember :memberCount.stringValue];
|
||||
}
|
||||
|
||||
- (NSString *)allOtherMembersLeft:(NSString *)member
|
||||
{
|
||||
return [MatrixKitL10n roomDisplaynameAllOtherMembersLeft:member];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import Down
|
||||
import libcmark
|
||||
|
||||
@objc public protocol MarkdownToHTMLRendererProtocol: NSObjectProtocol {
|
||||
func renderToHTML(markdown: String) -> String?
|
||||
}
|
||||
|
||||
@objcMembers
|
||||
public class MarkdownToHTMLRenderer: NSObject {
|
||||
|
||||
fileprivate var options: DownOptions = []
|
||||
|
||||
// Do not expose an initializer with options, because `DownOptions` is not ObjC compatible.
|
||||
public override init() {
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
||||
extension MarkdownToHTMLRenderer: MarkdownToHTMLRendererProtocol {
|
||||
|
||||
public func renderToHTML(markdown: String) -> String? {
|
||||
return try? Down(markdownString: markdown).toHTML(options)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@objcMembers
|
||||
public class MarkdownToHTMLRendererHardBreaks: MarkdownToHTMLRenderer {
|
||||
|
||||
public override init() {
|
||||
super.init()
|
||||
options = .hardBreaks
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Copyright 2020 The Matrix.org Foundation C.I.C
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
typedef NSString *const MXKAnalyticsCategory NS_TYPED_EXTENSIBLE_ENUM;
|
||||
|
||||
/**
|
||||
The analytics category for local contacts.
|
||||
*/
|
||||
static MXKAnalyticsCategory const MXKAnalyticsCategoryContacts = @"localContacts";
|
||||
|
||||
|
||||
typedef NSString *const MXKAnalyticsName NS_TYPED_EXTENSIBLE_ENUM;
|
||||
|
||||
/**
|
||||
The analytics value for accept/decline of local contacts access.
|
||||
*/
|
||||
static MXKAnalyticsName const MXKAnalyticsNameContactsAccessGranted = @"accessGranted";
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#define MXK_DEPRECATED_ATTRIBUTE __attribute__((deprecated))
|
||||
#define MXK_DEPRECATED_ATTRIBUTE_WITH_MSG(msg) __attribute((deprecated((msg))))
|
||||
|
||||
/**
|
||||
The Matrix iOS Kit version.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const MatrixKitVersion;
|
||||
|
||||
/**
|
||||
Posted when an error is observed at Matrix Kit level.
|
||||
This notification may be used to inform user by showing the error as an alert.
|
||||
The notification object is the NSError instance.
|
||||
|
||||
The passed userInfo dictionary may contain:
|
||||
- `kMXKErrorUserIdKey` the matrix identifier of the account concerned by this error.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const kMXKErrorNotification;
|
||||
|
||||
/**
|
||||
The key in notification userInfo dictionary representating the account userId.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *const kMXKErrorUserIdKey;
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2018 New Vector Ltd
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKConstants.h"
|
||||
|
||||
NSString *const kMXKErrorNotification = @"kMXKErrorNotification";
|
||||
|
||||
NSString *const kMXKErrorUserIdKey = @"kMXKErrorUserIdKey";
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
import MobileCoreServices
|
||||
|
||||
@objc public protocol MXKDocumentPickerPresenterDelegate {
|
||||
func documentPickerPresenter(_ presenter: MXKDocumentPickerPresenter, didPickDocumentsAt url: URL)
|
||||
func documentPickerPresenterWasCancelled(_ presenter: MXKDocumentPickerPresenter)
|
||||
}
|
||||
|
||||
/// MXKDocumentPickerPresenter presents a controller that provides access to documents or destinations outside the app’s sandbox.
|
||||
/// Internally presents a UIDocumentPickerViewController in UIDocumentPickerMode.import.
|
||||
/// Note: You must turn on the iCloud Documents capabilities in Xcode (see https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/DocumentPickerProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40014451)
|
||||
@objcMembers
|
||||
public class MXKDocumentPickerPresenter: NSObject {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private weak var presentingViewController: UIViewController?
|
||||
|
||||
// MARK: Public
|
||||
|
||||
public weak var delegate: MXKDocumentPickerPresenterDelegate?
|
||||
|
||||
public var isPresenting: Bool {
|
||||
return self.presentingViewController?.parent != nil
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
/// Presents a document picker view controller modally.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - allowedUTIs: Allowed pickable file UTIs.
|
||||
/// - viewController: The view controller on which to present the document picker.
|
||||
/// - animated: Indicate true to animate.
|
||||
/// - completion: Animation completion.
|
||||
public func presentDocumentPicker(with allowedUTIs: [MXKUTI], from viewController: UIViewController, animated: Bool, completion: (() -> Void)?) {
|
||||
let documentTypes = allowedUTIs.map { return $0.rawValue }
|
||||
let documentPicker = UIDocumentPickerViewController(documentTypes: documentTypes, in: .import)
|
||||
documentPicker.delegate = self
|
||||
viewController.present(documentPicker, animated: animated, completion: completion)
|
||||
self.presentingViewController = viewController
|
||||
}
|
||||
}
|
||||
|
||||
// MARK - UIDocumentPickerDelegate
|
||||
extension MXKDocumentPickerPresenter: UIDocumentPickerDelegate {
|
||||
|
||||
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
|
||||
guard let url = urls.first else {
|
||||
return
|
||||
}
|
||||
self.delegate?.documentPickerPresenter(self, didPickDocumentsAt: url)
|
||||
}
|
||||
|
||||
public func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
|
||||
self.delegate?.documentPickerPresenterWasCancelled(self)
|
||||
}
|
||||
|
||||
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
|
||||
self.delegate?.documentPickerPresenter(self, didPickDocumentsAt: url)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
`MXKResponderRageShaking` defines a protocol an object must conform to handle rage shake
|
||||
on view controllers or other kinds of `UIResponder`.
|
||||
*/
|
||||
@protocol MXKResponderRageShaking <NSObject>
|
||||
|
||||
/**
|
||||
Tells the receiver that a motion event has begun.
|
||||
|
||||
@param responder the view controller (or another kind of `UIResponder`) which observed the motion.
|
||||
*/
|
||||
- (void)startShaking:(UIResponder*)responder;
|
||||
|
||||
/**
|
||||
Tells the receiver that a motion event has ended.
|
||||
|
||||
@param responder the view controller (or another kind of `UIResponder`) which observed the motion.
|
||||
*/
|
||||
- (void)stopShaking:(UIResponder*)responder;
|
||||
|
||||
/**
|
||||
Ignore pending rage shake related to the provided responder.
|
||||
|
||||
@param responder a view controller (or another kind of `UIResponder`).
|
||||
*/
|
||||
- (void)cancel:(UIResponder*)responder;
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MXKSoundPlayer : NSObject
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
+ (instancetype)init NS_UNAVAILABLE;
|
||||
+ (instancetype)new NS_UNAVAILABLE;
|
||||
|
||||
- (void)playSoundAt:(NSURL *)url repeat:(BOOL)repeat vibrate:(BOOL)vibrate routeToBuiltInReceiver:(BOOL)useBuiltInReceiver;
|
||||
- (void)stopPlayingWithAudioSessionDeactivation:(BOOL)deactivateAudioSession;
|
||||
|
||||
- (void)vibrateWithRepeat:(BOOL)repeat;
|
||||
- (void)stopVibrating;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKSoundPlayer.h"
|
||||
|
||||
#import <AVFoundation/AVFAudio.h>
|
||||
#import <AudioToolbox/AudioServices.h>
|
||||
|
||||
static const NSTimeInterval kVibrationInterval = 1.24875;
|
||||
|
||||
@interface MXKSoundPlayer () <AVAudioPlayerDelegate>
|
||||
|
||||
@property (nonatomic, nullable) AVAudioPlayer *audioPlayer;
|
||||
|
||||
@property (nonatomic, getter=isVibrating) BOOL vibrating;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MXKSoundPlayer
|
||||
|
||||
+ (instancetype)sharedInstance
|
||||
{
|
||||
static MXKSoundPlayer *soundPlayer;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
soundPlayer = [MXKSoundPlayer alloc];
|
||||
});
|
||||
return soundPlayer;
|
||||
}
|
||||
|
||||
- (void)playSoundAt:(NSURL *)url repeat:(BOOL)repeat vibrate:(BOOL)vibrate routeToBuiltInReceiver:(BOOL)useBuiltInReceiver
|
||||
{
|
||||
if (self.audioPlayer)
|
||||
{
|
||||
[self stopPlayingWithAudioSessionDeactivation:NO];
|
||||
}
|
||||
|
||||
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
|
||||
|
||||
if (!self.audioPlayer)
|
||||
return;
|
||||
|
||||
self.audioPlayer.delegate = self;
|
||||
self.audioPlayer.numberOfLoops = repeat ? -1 : 0;
|
||||
[self.audioPlayer prepareToPlay];
|
||||
|
||||
// Setup AVAudioSession
|
||||
// We use SoloAmbient instead of Playback category to respect silent mode
|
||||
NSString *audioSessionCategory = useBuiltInReceiver ? AVAudioSessionCategoryPlayAndRecord : AVAudioSessionCategorySoloAmbient;
|
||||
[[AVAudioSession sharedInstance] setCategory:audioSessionCategory error:nil];
|
||||
|
||||
if (vibrate)
|
||||
[self vibrateWithRepeat:repeat];
|
||||
|
||||
[self.audioPlayer play];
|
||||
}
|
||||
|
||||
- (void)stopPlayingWithAudioSessionDeactivation:(BOOL)deactivateAudioSession;
|
||||
{
|
||||
if (self.audioPlayer)
|
||||
{
|
||||
[self.audioPlayer stop];
|
||||
self.audioPlayer = nil;
|
||||
|
||||
if (deactivateAudioSession)
|
||||
{
|
||||
// Release the audio session to allow resuming of background music app
|
||||
[[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
|
||||
}
|
||||
}
|
||||
|
||||
if (self.isVibrating)
|
||||
{
|
||||
[self stopVibrating];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)vibrateWithRepeat:(BOOL)repeat
|
||||
{
|
||||
self.vibrating = YES;
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kVibrationInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
|
||||
|
||||
NSNumber *objRepeat = @(repeat);
|
||||
AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate,
|
||||
NULL,
|
||||
kCFRunLoopCommonModes,
|
||||
vibrationCompleted,
|
||||
(__bridge_retained void * _Nullable)(objRepeat));
|
||||
});
|
||||
}
|
||||
|
||||
- (void)stopVibrating
|
||||
{
|
||||
self.vibrating = NO;
|
||||
AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);
|
||||
}
|
||||
|
||||
void vibrationCompleted(SystemSoundID ssID, void* __nullable clientData)
|
||||
{
|
||||
NSNumber *objRepeat = (__bridge NSNumber *)clientData;
|
||||
BOOL repeat = [objRepeat boolValue];
|
||||
CFRelease(clientData);
|
||||
|
||||
MXKSoundPlayer *soundPlayer = [MXKSoundPlayer sharedInstance];
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kVibrationInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
if (repeat && soundPlayer.isVibrating)
|
||||
{
|
||||
[soundPlayer vibrateWithRepeat:repeat];
|
||||
}
|
||||
else
|
||||
{
|
||||
[soundPlayer stopVibrating];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - AVAudioPlayerDelegate
|
||||
|
||||
// This method is called only when the end of the player's track is reached.
|
||||
// If you call `stop` or `pause` on player this method won't be called
|
||||
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
|
||||
{
|
||||
self.audioPlayer = nil;
|
||||
|
||||
// Release the audio session to allow resuming of background music app
|
||||
[[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,426 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
#define MXKTOOLS_LARGE_IMAGE_SIZE 1024
|
||||
#define MXKTOOLS_MEDIUM_IMAGE_SIZE 768
|
||||
#define MXKTOOLS_SMALL_IMAGE_SIZE 512
|
||||
|
||||
#define MXKTOOLS_USER_IDENTIFIER_BITWISE 0x01
|
||||
#define MXKTOOLS_ROOM_IDENTIFIER_BITWISE 0x02
|
||||
#define MXKTOOLS_ROOM_ALIAS_BITWISE 0x04
|
||||
#define MXKTOOLS_EVENT_IDENTIFIER_BITWISE 0x08
|
||||
#define MXKTOOLS_GROUP_IDENTIFIER_BITWISE 0x10
|
||||
|
||||
// Attribute in an NSAttributeString that marks a blockquote block that was in the original HTML string.
|
||||
extern NSString *const kMXKToolsBlockquoteMarkAttribute;
|
||||
|
||||
/**
|
||||
Structure representing an the size of an image and its file size.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
CGSize imageSize;
|
||||
NSUInteger fileSize;
|
||||
|
||||
} MXKImageCompressionSize;
|
||||
|
||||
/**
|
||||
Structure representing the sizes of image (image size and file size) according to
|
||||
different level of compression.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MXKImageCompressionSize small;
|
||||
MXKImageCompressionSize medium;
|
||||
MXKImageCompressionSize large;
|
||||
MXKImageCompressionSize original;
|
||||
|
||||
CGFloat actualLargeSize;
|
||||
|
||||
} MXKImageCompressionSizes;
|
||||
|
||||
@interface MXKTools : NSObject
|
||||
|
||||
#pragma mark - Strings
|
||||
|
||||
/**
|
||||
Determine if a string contains one emoji and only one.
|
||||
|
||||
@param string the string to check.
|
||||
@return YES if YES.
|
||||
*/
|
||||
+ (BOOL)isSingleEmojiString:(NSString*)string;
|
||||
|
||||
/**
|
||||
Determine if a string contains only emojis.
|
||||
|
||||
@param string the string to check.
|
||||
@return YES if YES.
|
||||
*/
|
||||
+ (BOOL)isEmojiOnlyString:(NSString*)string;
|
||||
|
||||
#pragma mark - Time
|
||||
|
||||
/**
|
||||
Format time interval.
|
||||
ex: "5m 31s".
|
||||
|
||||
@param secondsInterval time interval in seconds.
|
||||
@return formatted string
|
||||
*/
|
||||
+ (NSString*)formatSecondsInterval:(CGFloat)secondsInterval;
|
||||
|
||||
/**
|
||||
Format time interval but rounded to the nearest time unit below.
|
||||
ex: "5s", "1m", "2h" or "3d".
|
||||
|
||||
@param secondsInterval time interval in seconds.
|
||||
@return formatted string
|
||||
*/
|
||||
+ (NSString*)formatSecondsIntervalFloored:(CGFloat)secondsInterval;
|
||||
|
||||
#pragma mark - Phone number
|
||||
|
||||
/**
|
||||
Return the number used to identify a mobile phone number internationally.
|
||||
|
||||
The provided country code is ignored when the phone number is already internationalized, or when it
|
||||
is a valid msisdn.
|
||||
|
||||
@param phoneNumber the phone number.
|
||||
@param countryCode the ISO 3166-1 country code representation (required when the phone number is in national format).
|
||||
|
||||
@return a valid msisdn or nil if the provided phone number is invalid.
|
||||
*/
|
||||
+ (NSString*)msisdnWithPhoneNumber:(NSString *)phoneNumber andCountryCode:(NSString *)countryCode;
|
||||
|
||||
/**
|
||||
Format an MSISDN to a human readable international phone number.
|
||||
|
||||
@param msisdn The MSISDN to format.
|
||||
|
||||
@return Human readable international phone number.
|
||||
*/
|
||||
+ (NSString*)readableMSISDN:(NSString*)msisdn;
|
||||
|
||||
#pragma mark - Hex color to UIColor conversion
|
||||
|
||||
/**
|
||||
Build a UIColor from an hexadecimal color value
|
||||
|
||||
@param rgbValue the color expressed in hexa (0xRRGGBB)
|
||||
@return the UIColor
|
||||
*/
|
||||
+ (UIColor*)colorWithRGBValue:(NSUInteger)rgbValue;
|
||||
|
||||
/**
|
||||
Build a UIColor from an hexadecimal color value with transparency
|
||||
|
||||
@param argbValue the color expressed in hexa (0xAARRGGBB)
|
||||
@return the UIColor
|
||||
*/
|
||||
+ (UIColor*)colorWithARGBValue:(NSUInteger)argbValue;
|
||||
|
||||
/**
|
||||
Return an hexadecimal color value from UIColor
|
||||
|
||||
@param color the UIColor
|
||||
@return rgbValue the color expressed in hexa (0xRRGGBB)
|
||||
*/
|
||||
+ (NSUInteger)rgbValueWithColor:(UIColor*)color;
|
||||
|
||||
/**
|
||||
Return an hexadecimal color value with transparency from UIColor
|
||||
|
||||
@param color the UIColor
|
||||
@return argbValue the color expressed in hexa (0xAARRGGBB)
|
||||
*/
|
||||
+ (NSUInteger)argbValueWithColor:(UIColor*)color;
|
||||
|
||||
#pragma mark - Image processing
|
||||
|
||||
/**
|
||||
Force image orientation to up
|
||||
|
||||
@param imageSrc the original image.
|
||||
@return image with `UIImageOrientationUp` orientation.
|
||||
*/
|
||||
+ (UIImage*)forceImageOrientationUp:(UIImage*)imageSrc;
|
||||
|
||||
/**
|
||||
Return struct MXKImageCompressionSizes representing the available compression sizes for the image
|
||||
|
||||
@param image the image to get available sizes for
|
||||
@param originalFileSize the size in bytes of the original image file or the image data (0 if this value is unknown).
|
||||
*/
|
||||
+ (MXKImageCompressionSizes)availableCompressionSizesForImage:(UIImage*)image originalFileSize:(NSUInteger)originalFileSize;
|
||||
|
||||
/**
|
||||
Compute image size to fit in specific box size (in aspect fit mode)
|
||||
|
||||
@param originalSize the original size
|
||||
@param maxSize the box size
|
||||
@param canExpand tell whether the image can be expand or not
|
||||
@return the resized size.
|
||||
*/
|
||||
+ (CGSize)resizeImageSize:(CGSize)originalSize toFitInSize:(CGSize)maxSize canExpand:(BOOL)canExpand;
|
||||
|
||||
/**
|
||||
Compute image size to fill specific box size (in aspect fill mode)
|
||||
|
||||
@param originalSize the original size
|
||||
@param maxSize the box size
|
||||
@param canExpand tell whether the image can be expand or not
|
||||
@return the resized size.
|
||||
*/
|
||||
+ (CGSize)resizeImageSize:(CGSize)originalSize toFillWithSize:(CGSize)maxSize canExpand:(BOOL)canExpand;
|
||||
|
||||
/**
|
||||
Reduce image to fit in the provided size.
|
||||
The aspect ratio is kept.
|
||||
If the image is smaller than the provided size, the image is not recomputed.
|
||||
|
||||
@discussion This method call `+ [reduceImage:toFitInSize:useMainScreenScale:]` with `useMainScreenScale` value to `NO`.
|
||||
|
||||
@param image the image to modify.
|
||||
@param size to fit in.
|
||||
@return resized image.
|
||||
|
||||
@see reduceImage:toFitInSize:useMainScreenScale:
|
||||
*/
|
||||
+ (UIImage *)reduceImage:(UIImage *)image toFitInSize:(CGSize)size;
|
||||
|
||||
/**
|
||||
Reduce image to fit in the provided size.
|
||||
The aspect ratio is kept.
|
||||
If the image is smaller than the provided size, the image is not recomputed.
|
||||
|
||||
@param image the image to modify.
|
||||
@param size to fit in.
|
||||
@param useMainScreenScale Indicate true to use main screen scale.
|
||||
@return resized image.
|
||||
*/
|
||||
+ (UIImage *)reduceImage:(UIImage *)image toFitInSize:(CGSize)size useMainScreenScale:(BOOL)useMainScreenScale;
|
||||
|
||||
/**
|
||||
Reduce image to fit in the provided size.
|
||||
The aspect ratio is kept.
|
||||
|
||||
@discussion This method use less memory than `+ [reduceImage:toFitInSize:useMainScreenScale:]`.
|
||||
|
||||
@param imageData The image data.
|
||||
@param size Size to fit in.
|
||||
@return Resized image or nil if the data is not interpreted.
|
||||
*/
|
||||
+ (UIImage*)resizeImageWithData:(NSData*)imageData toFitInSize:(CGSize)size;
|
||||
|
||||
/**
|
||||
Resize image to a provided size.
|
||||
|
||||
@param image the image to modify.
|
||||
@param size the new size.
|
||||
@return resized image.
|
||||
*/
|
||||
+ (UIImage*)resizeImage:(UIImage *)image toSize:(CGSize)size;
|
||||
|
||||
/**
|
||||
Resize image with rounded corners to a provided size.
|
||||
|
||||
@param image the image to modify.
|
||||
@param size the new size.
|
||||
@return resized image.
|
||||
*/
|
||||
+ (UIImage*)resizeImageWithRoundedCorners:(UIImage *)image toSize:(CGSize)size;
|
||||
|
||||
/**
|
||||
Paint an image with a color.
|
||||
|
||||
@discussion
|
||||
All non fully transparent (alpha = 0) will be painted with the provided color.
|
||||
|
||||
@param image the image to paint.
|
||||
@param color the color to use.
|
||||
@result a new UIImage object.
|
||||
*/
|
||||
+ (UIImage*)paintImage:(UIImage*)image withColor:(UIColor*)color;
|
||||
|
||||
/**
|
||||
Convert a rotation angle to the most suitable image orientation.
|
||||
|
||||
@param angle rotation angle in degree.
|
||||
@return image orientation.
|
||||
*/
|
||||
+ (UIImageOrientation)imageOrientationForRotationAngleInDegree:(NSInteger)angle;
|
||||
|
||||
/**
|
||||
Draw the image resource in a view and transforms it to a pattern color.
|
||||
The view size is defined by patternSize and will have a "backgroundColor" backgroundColor.
|
||||
The resource image is drawn with the resourceSize size and is centered into its parent view.
|
||||
|
||||
@param reourceName the image resource name.
|
||||
@param backgroundColor the pattern background color.
|
||||
@param patternSize the pattern size.
|
||||
@param resourceSize the resource size in the pattern.
|
||||
@return the pattern color which can be used to define the background color of a view in order to display the provided image as its background.
|
||||
*/
|
||||
+ (UIColor*)convertImageToPatternColor:(NSString*)reourceName backgroundColor:(UIColor*)backgroundColor patternSize:(CGSize)patternSize resourceSize:(CGSize)resourceSize;
|
||||
|
||||
#pragma mark - Video conversion
|
||||
/**
|
||||
Creates a `UIAlertController` with appropriate `AVAssetExportPreset` choices for the video passed in.
|
||||
@param videoAsset The video to generate the choices for.
|
||||
@param completion The block called when a preset has been chosen. `presetName` will contain the preset name or `nil` if cancelled.
|
||||
*/
|
||||
+ (UIAlertController*)videoConversionPromptForVideoAsset:(AVAsset *)videoAsset
|
||||
withCompletion:(void (^)(NSString * _Nullable presetName))completion;
|
||||
|
||||
#pragma mark - App permissions
|
||||
|
||||
/**
|
||||
Check permission to access a media.
|
||||
|
||||
@discussion
|
||||
If the access was not yet granted, a dialog will be shown to the user.
|
||||
If it is the first attempt to access the media, the dialog is the classic iOS one.
|
||||
Else, the dialog will ask the user to manually change the permission in the app settings.
|
||||
|
||||
@param mediaType the media type, either AVMediaTypeVideo or AVMediaTypeAudio.
|
||||
@param manualChangeMessage the message to display if the end user must change the app settings manually.
|
||||
@param viewController the view controller to attach the dialog displaying manualChangeMessage.
|
||||
@param handler the block called with the result of requesting access
|
||||
*/
|
||||
+ (void)checkAccessForMediaType:(NSString *)mediaType
|
||||
manualChangeMessage:(NSString*)manualChangeMessage
|
||||
showPopUpInViewController:(UIViewController*)viewController
|
||||
completionHandler:(void (^)(BOOL granted))handler;
|
||||
|
||||
/**
|
||||
Check required permission for the provided call.
|
||||
|
||||
@param isVideoCall flag set to YES in case of video call.
|
||||
@param manualChangeMessageForAudio the message to display if the end user must change the app settings manually for audio.
|
||||
@param manualChangeMessageForVideo the message to display if the end user must change the app settings manually for video
|
||||
@param viewController the view controller to attach the dialog displaying manualChangeMessage.
|
||||
@param handler the block called with the result of requesting access
|
||||
*/
|
||||
+ (void)checkAccessForCall:(BOOL)isVideoCall
|
||||
manualChangeMessageForAudio:(NSString*)manualChangeMessageForAudio
|
||||
manualChangeMessageForVideo:(NSString*)manualChangeMessageForVideo
|
||||
showPopUpInViewController:(UIViewController*)viewController
|
||||
completionHandler:(void (^)(BOOL granted))handler;
|
||||
|
||||
/**
|
||||
Check permission to access Contacts.
|
||||
|
||||
@discussion
|
||||
If the access was not yet granted, a dialog will be shown to the user.
|
||||
If it is the first attempt to access the media, the dialog is the classic iOS one.
|
||||
Else, the dialog will ask the user to manually change the permission in the app settings.
|
||||
|
||||
@param manualChangeMessage the message to display if the end user must change the app settings manually.
|
||||
If nil, the dialog for displaying manualChangeMessage will not be shown.
|
||||
@param viewController the view controller to attach the dialog displaying manualChangeMessage.
|
||||
@param handler the block called with the result of requesting access
|
||||
*/
|
||||
+ (void)checkAccessForContacts:(NSString*)manualChangeMessage
|
||||
showPopUpInViewController:(UIViewController*)viewController
|
||||
completionHandler:(void (^)(BOOL granted))handler;
|
||||
|
||||
/**
|
||||
Check permission to access Contacts.
|
||||
|
||||
@discussion
|
||||
If the access was not yet granted, a dialog will be shown to the user.
|
||||
If it is the first attempt to access the media, the dialog is the classic iOS one.
|
||||
Else, the dialog will ask the user to manually change the permission in the app settings.
|
||||
|
||||
@param manualChangeTitle the title to display if the end user must change the app settings manually.
|
||||
@param manualChangeMessage the message to display if the end user must change the app settings manually.
|
||||
If nil, the dialog for displaying manualChangeMessage will not be shown.
|
||||
@param viewController the view controller to attach the dialog displaying manualChangeMessage.
|
||||
@param handler the block called with the result of requesting access
|
||||
*/
|
||||
+ (void)checkAccessForContacts:(NSString *)manualChangeTitle
|
||||
withManualChangeMessage:(NSString *)manualChangeMessage
|
||||
showPopUpInViewController:(UIViewController *)viewController
|
||||
completionHandler:(void (^)(BOOL granted))handler;
|
||||
|
||||
#pragma mark - HTML processing
|
||||
|
||||
/**
|
||||
Removing DTCoreText artifacts:
|
||||
- Trim trailing whitespace and newlines in the string content.
|
||||
- Replace DTImageTextAttachments with a simple NSTextAttachment subclass.
|
||||
|
||||
@param attributedString an attributed string.
|
||||
@return the resulting string.
|
||||
*/
|
||||
+ (NSAttributedString*)removeDTCoreTextArtifacts:(NSAttributedString*)attributedString;
|
||||
|
||||
/**
|
||||
Make some matrix identifiers clickable in the string content.
|
||||
|
||||
@param attributedString an attributed string.
|
||||
@param enabledMatrixIdsBitMask the bitmask used to list the types of matrix id to process (see MXKTOOLS_XXX__BITWISE).
|
||||
@return the resulting string.
|
||||
*/
|
||||
+ (NSAttributedString*)createLinksInAttributedString:(NSAttributedString*)attributedString forEnabledMatrixIds:(NSInteger)enabledMatrixIdsBitMask;
|
||||
|
||||
#pragma mark - HTML processing - blockquote display handling
|
||||
|
||||
/**
|
||||
Return a CSS to make DTCoreText mark blockquote blocks in the `NSAttributedString` output.
|
||||
|
||||
These blocks output will have a `DTTextBlocksAttribute` attribute in the `NSAttributedString`
|
||||
that can be used for later computation (in `removeMarkedBlockquotesArtifacts`).
|
||||
|
||||
@return a CSS string.
|
||||
*/
|
||||
+ (NSString*)cssToMarkBlockquotes;
|
||||
|
||||
/**
|
||||
Removing DTCoreText artifacts used to mark blockquote blocks.
|
||||
|
||||
@param attributedString an attributed string.
|
||||
@return the resulting string.
|
||||
*/
|
||||
+ (NSAttributedString*)removeMarkedBlockquotesArtifacts:(NSAttributedString*)attributedString;
|
||||
|
||||
/**
|
||||
Enumerate all sections of the attributed string that refer to an HTML blockquote block.
|
||||
|
||||
Must be used with `cssToMarkBlockquotes` and `removeMarkedBlockquotesArtifacts`.
|
||||
|
||||
@param attributedString the attributed string.
|
||||
@param block a block called for each HTML blockquote blocks.
|
||||
*/
|
||||
+ (void)enumerateMarkedBlockquotesInAttributedString:(NSAttributedString*)attributedString usingBlock:(void (^)(NSRange range, BOOL *stop))block;
|
||||
|
||||
#pragma mark - Push
|
||||
|
||||
/**
|
||||
Trim push token in order to log it.
|
||||
|
||||
@param pushToken the token to trim.
|
||||
@return a trimmed description.
|
||||
*/
|
||||
+ (NSString*)logForPushToken:(NSData*)pushToken;
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import ImageIO
|
||||
import MobileCoreServices
|
||||
|
||||
// We do not use the SwiftUTI pod anymore
|
||||
// The library is embedded in MatrixKit. See Libs/SwiftUTI/README.md for more details
|
||||
//import SwiftUTI
|
||||
|
||||
/// MXKUTI represents a Universal Type Identifier (e.g. kUTTypePNG).
|
||||
/// See https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html#//apple_ref/doc/uid/TP40001319-CH202-SW5 for more information.
|
||||
/// MXKUTI wraps UTI class from SwiftUTI library (https://github.com/mkeiser/SwiftUTI) to make it available for Objective-C.
|
||||
@objcMembers
|
||||
open class MXKUTI: NSObject, RawRepresentable {
|
||||
|
||||
public typealias RawValue = String
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let utiWrapper: UTI
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/// UTI string
|
||||
public var rawValue: String {
|
||||
return utiWrapper.rawValue
|
||||
}
|
||||
|
||||
/// Return associated prefered file extension (e.g. "png").
|
||||
public var fileExtension: String? {
|
||||
return utiWrapper.fileExtension
|
||||
}
|
||||
|
||||
/// Return associated prefered mime-type (e.g. "image/png").
|
||||
public var mimeType: String? {
|
||||
return utiWrapper.mimeType
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private init(utiWrapper: UTI) {
|
||||
self.utiWrapper = utiWrapper
|
||||
super.init()
|
||||
}
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/// Initialize with UTI String.
|
||||
/// Note: Although this initializer is marked as failable, due to RawRepresentable conformity, it cannot fail.
|
||||
///
|
||||
/// - Parameter rawValue: UTI String (e.g. "public.png").
|
||||
public required init?(rawValue: String) {
|
||||
let utiWrapper = UTI(rawValue: rawValue)
|
||||
self.utiWrapper = utiWrapper
|
||||
super.init()
|
||||
}
|
||||
|
||||
/// Initialize with UTI CFString.
|
||||
///
|
||||
/// - Parameter cfRawValue: UTI CFString (e.g. kUTTypePNG).
|
||||
public convenience init?(cfRawValue: CFString) {
|
||||
self.init(rawValue: cfRawValue as String)
|
||||
}
|
||||
|
||||
/// Initialize with file extension.
|
||||
///
|
||||
/// - Parameter fileExtension: A file extesion (e.g. "png").
|
||||
public convenience init(fileExtension: String) {
|
||||
let utiWrapper = UTI(withExtension: fileExtension)
|
||||
self.init(utiWrapper: utiWrapper)
|
||||
}
|
||||
|
||||
/// Initialize with MIME type.
|
||||
///
|
||||
/// - Parameter mimeType: A MIME type (e.g. "image/png").
|
||||
public convenience init?(mimeType: String) {
|
||||
let utiWrapper = UTI(withMimeType: mimeType)
|
||||
self.init(utiWrapper: utiWrapper)
|
||||
}
|
||||
|
||||
/// Check current UTI conformance with another UTI.
|
||||
///
|
||||
/// - Parameter otherUTI: UTI which to conform with.
|
||||
/// - Returns: true if self conforms to other UTI.
|
||||
public func conforms(to otherUTI: MXKUTI) -> Bool {
|
||||
return self.utiWrapper.conforms(to: otherUTI.utiWrapper)
|
||||
}
|
||||
|
||||
/// Check whether the current UTI conforms to any UTIs within an array.
|
||||
///
|
||||
/// - Parameter otherUTIs: UTI which to conform with.
|
||||
/// - Returns: true if self conforms to any of the other UTIs.
|
||||
public func conformsToAny(of otherUTIs: [MXKUTI]) -> Bool {
|
||||
for uti in otherUTIs {
|
||||
if conforms(to: uti) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Other convenients initializers
|
||||
extension MXKUTI {
|
||||
|
||||
/// Initialize with image data.
|
||||
///
|
||||
/// - Parameter imageData: Image data.
|
||||
convenience init?(imageData: Data) {
|
||||
guard let imageSource = CGImageSourceCreateWithData(imageData as CFData, nil),
|
||||
let uti = CGImageSourceGetType(imageSource) else {
|
||||
return nil
|
||||
}
|
||||
self.init(rawValue: uti as String)
|
||||
}
|
||||
|
||||
/// Initialize with local file URL.
|
||||
/// This method is currently applicable only to URLs for file system resources.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - localFileURL: Local file URL.
|
||||
/// - loadResourceValues: Indicate true to prefetch `typeIdentifierKey` URLResourceKey
|
||||
convenience init?(localFileURL: URL, loadResourceValues: Bool = true) {
|
||||
if loadResourceValues,
|
||||
let _ = try? FileManager.default.contentsOfDirectory(at: localFileURL.deletingLastPathComponent(), includingPropertiesForKeys: [.typeIdentifierKey], options: []),
|
||||
let uti = try? localFileURL.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier {
|
||||
self.init(rawValue: uti)
|
||||
} else if localFileURL.pathExtension.isEmpty == false {
|
||||
let fileExtension = localFileURL.pathExtension
|
||||
self.init(fileExtension: fileExtension)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public convenience init?(localFileURL: URL) {
|
||||
self.init(localFileURL: localFileURL, loadResourceValues: true)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Convenients conformance UTIs methods
|
||||
extension MXKUTI {
|
||||
public var isImage: Bool {
|
||||
return self.conforms(to: MXKUTI.image)
|
||||
}
|
||||
|
||||
public var isVideo: Bool {
|
||||
return self.conforms(to: MXKUTI.movie)
|
||||
}
|
||||
|
||||
public var isFile: Bool {
|
||||
return self.conforms(to: MXKUTI.data)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Some system defined UTIs
|
||||
extension MXKUTI {
|
||||
public static let data = MXKUTI(cfRawValue: kUTTypeData)!
|
||||
public static let text = MXKUTI(cfRawValue: kUTTypeText)!
|
||||
public static let audio = MXKUTI(cfRawValue: kUTTypeAudio)!
|
||||
public static let video = MXKUTI(cfRawValue: kUTTypeVideo)!
|
||||
public static let movie = MXKUTI(cfRawValue: kUTTypeMovie)!
|
||||
public static let image = MXKUTI(cfRawValue: kUTTypeImage)!
|
||||
public static let png = MXKUTI(cfRawValue: kUTTypePNG)!
|
||||
public static let jpeg = MXKUTI(cfRawValue: kUTTypeJPEG)!
|
||||
public static let svg = MXKUTI(cfRawValue: kUTTypeScalableVectorGraphics)!
|
||||
public static let url = MXKUTI(cfRawValue: kUTTypeURL)!
|
||||
public static let fileUrl = MXKUTI(cfRawValue: kUTTypeFileURL)!
|
||||
public static let html = MXKUTI(cfRawValue: kUTTypeHTML)!
|
||||
public static let xml = MXKUTI(cfRawValue: kUTTypeXML)!
|
||||
}
|
||||
|
||||
// MARK: - Convenience static methods
|
||||
extension MXKUTI {
|
||||
|
||||
public static func mimeType(from fileExtension: String) -> String? {
|
||||
return MXKUTI(fileExtension: fileExtension).mimeType
|
||||
}
|
||||
|
||||
public static func fileExtension(from mimeType: String) -> String? {
|
||||
return MXKUTI(mimeType: mimeType)?.fileExtension
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
import AVFoundation
|
||||
|
||||
/// MXKVideoThumbnailGenerator is a utility class to generate a thumbnail image from a video file.
|
||||
@objcMembers
|
||||
public class MXKVideoThumbnailGenerator: NSObject {
|
||||
|
||||
public static let shared = MXKVideoThumbnailGenerator()
|
||||
|
||||
// MARK - Public
|
||||
|
||||
/// Generate thumbnail image from a video URL.
|
||||
/// Note: Do not make `maximumSize` optional with default nil value for Objective-C compatibility.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - url: Video URL.
|
||||
/// - maximumSize: Maximum dimension for generated thumbnail image.
|
||||
/// - Returns: Thumbnail image or nil.
|
||||
public func generateThumbnail(from url: URL, with maximumSize: CGSize) -> UIImage? {
|
||||
let finalSize: CGSize? = maximumSize != .zero ? maximumSize : nil
|
||||
return self.generateThumbnail(from: url, with: finalSize)
|
||||
}
|
||||
|
||||
/// Generate thumbnail image from a video URL.
|
||||
///
|
||||
/// - Parameter url: Video URL.
|
||||
/// - Returns: Thumbnail image or nil.
|
||||
public func generateThumbnail(from url: URL) -> UIImage? {
|
||||
return generateThumbnail(from: url, with: nil)
|
||||
}
|
||||
|
||||
// MARK - Private
|
||||
|
||||
/// Generate thumbnail image from a video URL.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - url: Video URL.
|
||||
/// - maximumSize: Maximum dimension for generated thumbnail image or nil to keep video dimension.
|
||||
/// - Returns: Thumbnail image or nil.
|
||||
private func generateThumbnail(from url: URL, with maximumSize: CGSize?) -> UIImage? {
|
||||
let thumbnailImage: UIImage?
|
||||
|
||||
let asset = AVAsset(url: url)
|
||||
let assetImageGenerator = AVAssetImageGenerator(asset: asset)
|
||||
assetImageGenerator.appliesPreferredTrackTransform = true
|
||||
if let maximumSize = maximumSize {
|
||||
assetImageGenerator.maximumSize = maximumSize
|
||||
}
|
||||
do {
|
||||
// Generate thumbnail from first video image
|
||||
let image = try assetImageGenerator.copyCGImage(at: .zero, actualTime: nil)
|
||||
thumbnailImage = UIImage(cgImage: image)
|
||||
} catch {
|
||||
MXLog.error(error.localizedDescription)
|
||||
thumbnailImage = nil
|
||||
}
|
||||
|
||||
return thumbnailImage
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user