mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-21 17:12:45 +02:00
Merge MatrixKit develop with commit hash: b85b736313bec0592bd1cabc68035d97f5331137
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// 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 DTCoreText
|
||||
|
||||
public extension DTHTMLElement {
|
||||
typealias ImageHandler = (_ sourceURL: String, _ width: CGFloat, _ height: CGFloat) -> URL?
|
||||
|
||||
/// Sanitize the element using the given parameters.
|
||||
/// - Parameters:
|
||||
/// - allowedHTMLTags: An array of tags that are allowed. All other tags will be removed.
|
||||
/// - font: The default font to use when resetting the content of any unsupported tags.
|
||||
/// - imageHandler: An optional image handler to be run on `img` tags (if allowed) to update the `src` attribute.
|
||||
@objc func sanitize(with allowedHTMLTags: [String], bodyFont font: UIFont, imageHandler: ImageHandler?) {
|
||||
if let name = name, !allowedHTMLTags.contains(name) {
|
||||
|
||||
// This is an unsupported tag.
|
||||
// Remove any attachments to fix rendering.
|
||||
textAttachment = nil
|
||||
|
||||
// If the element has plain text content show that,
|
||||
// otherwise prevent the tag from displaying.
|
||||
if let stringContent = attributedString()?.string,
|
||||
!stringContent.isEmpty,
|
||||
let element = DTTextHTMLElement(name: nil, attributes: nil) {
|
||||
element.setText(stringContent)
|
||||
removeAllChildNodes()
|
||||
addChildNode(element)
|
||||
|
||||
if let parent = parent() {
|
||||
element.inheritAttributes(from: parent)
|
||||
} else {
|
||||
fontDescriptor = DTCoreTextFontDescriptor()
|
||||
fontDescriptor.fontFamily = font.familyName
|
||||
fontDescriptor.fontName = font.fontName
|
||||
fontDescriptor.pointSize = font.pointSize
|
||||
paragraphStyle = DTCoreTextParagraphStyle.default()
|
||||
|
||||
element.inheritAttributes(from: self)
|
||||
}
|
||||
element.interpretAttributes()
|
||||
|
||||
} else if let parent = parent() {
|
||||
parent.removeChildNode(self)
|
||||
} else {
|
||||
didOutput = true
|
||||
}
|
||||
|
||||
} else {
|
||||
// Process images with the handler when self is an image tag.
|
||||
if name == "img", let imageHandler = imageHandler {
|
||||
process(with: imageHandler)
|
||||
}
|
||||
|
||||
// This element is a supported tag, but it may contain children that aren't,
|
||||
// so santize all child nodes to ensure correct tags.
|
||||
if let childNodes = childNodes as? [DTHTMLElement] {
|
||||
childNodes.forEach { $0.sanitize(with: allowedHTMLTags, bodyFont: font, imageHandler: imageHandler) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Process the element with the supplied image handler.
|
||||
private func process(with imageHandler: ImageHandler) {
|
||||
// Get the values required to pass to the image handler
|
||||
guard let sourceURL = attributes["src"] as? String else { return }
|
||||
|
||||
var width: CGFloat = -1
|
||||
if let widthString = attributes["width"] as? String,
|
||||
let widthDouble = Double(widthString) {
|
||||
width = CGFloat(widthDouble)
|
||||
}
|
||||
|
||||
var height: CGFloat = -1
|
||||
if let heightString = attributes["height"] as? String,
|
||||
let heightDouble = Double(heightString) {
|
||||
height = CGFloat(heightDouble)
|
||||
}
|
||||
|
||||
// If the handler returns an updated URL, update the text attachment.
|
||||
guard let localSourceURL = imageHandler(sourceURL, width, height) else { return }
|
||||
textAttachment.contentURL = localSourceURL
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
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 "MXKEventFormatter.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Define a `MXEvent` category at matrixKit level to store data related to UI handling.
|
||||
*/
|
||||
@interface MXAggregatedReactions (MatrixKit)
|
||||
|
||||
- (nullable MXAggregatedReactions *)aggregatedReactionsWithSingleEmoji;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
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 "MXAggregatedReactions+MatrixKit.h"
|
||||
|
||||
#import "MXKTools.h"
|
||||
|
||||
@implementation MXAggregatedReactions (MatrixKit)
|
||||
|
||||
- (nullable MXAggregatedReactions *)aggregatedReactionsWithSingleEmoji
|
||||
{
|
||||
NSMutableArray *reactions = [NSMutableArray arrayWithCapacity:self.reactions.count];
|
||||
for (MXReactionCount *reactionCount in self.reactions)
|
||||
{
|
||||
if ([MXKTools isSingleEmojiString:reactionCount.reaction])
|
||||
{
|
||||
[reactions addObject:reactionCount];
|
||||
}
|
||||
}
|
||||
|
||||
MXAggregatedReactions *aggregatedReactionsWithSingleEmoji;
|
||||
if (reactions.count)
|
||||
{
|
||||
aggregatedReactionsWithSingleEmoji = [MXAggregatedReactions new];
|
||||
aggregatedReactionsWithSingleEmoji.reactions = reactions;
|
||||
}
|
||||
|
||||
return aggregatedReactionsWithSingleEmoji;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
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 "MXKEventFormatter.h"
|
||||
|
||||
/**
|
||||
Define a `MXEvent` category at matrixKit level to store data related to UI handling.
|
||||
*/
|
||||
@interface MXEvent (MatrixKit)
|
||||
|
||||
/**
|
||||
The potential error observed when the event formatter tried to stringify the event (MXKEventFormatterErrorNone by default).
|
||||
*/
|
||||
@property (nonatomic) MXKEventFormatterError mxkEventFormatterError;
|
||||
|
||||
/**
|
||||
Tell whether the event is highlighted or not (NO by default).
|
||||
*/
|
||||
@property (nonatomic) BOOL mxkIsHighlighted;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
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 "MXEvent+MatrixKit.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation MXEvent (MatrixKit)
|
||||
|
||||
- (MXKEventFormatterError)mxkEventFormatterError
|
||||
{
|
||||
NSNumber *associatedError = objc_getAssociatedObject(self, @selector(mxkEventFormatterError));
|
||||
if (associatedError)
|
||||
{
|
||||
return [associatedError unsignedIntegerValue];
|
||||
}
|
||||
return MXKEventFormatterErrorNone;
|
||||
}
|
||||
|
||||
- (void)setMxkEventFormatterError:(MXKEventFormatterError)mxkEventFormatterError
|
||||
{
|
||||
objc_setAssociatedObject(self, @selector(mxkEventFormatterError), [NSNumber numberWithUnsignedInteger:mxkEventFormatterError], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (BOOL)mxkIsHighlighted
|
||||
{
|
||||
NSNumber *associatedIsHighlighted = objc_getAssociatedObject(self, @selector(mxkIsHighlighted));
|
||||
if (associatedIsHighlighted)
|
||||
{
|
||||
return [associatedIsHighlighted boolValue];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setMxkIsHighlighted:(BOOL)mxkIsHighlighted
|
||||
{
|
||||
objc_setAssociatedObject(self, @selector(mxkIsHighlighted), [NSNumber numberWithBool:mxkIsHighlighted], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
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/Foundation.h>
|
||||
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
|
||||
/**
|
||||
Temporary category to help in the transition from synchronous access to room.state
|
||||
to asynchronous access.
|
||||
*/
|
||||
@interface MXRoom (Sync)
|
||||
|
||||
/**
|
||||
Get the room state if it has been already loaded else return nil.
|
||||
|
||||
Use this method only where you are sure the room state is already mounted.
|
||||
*/
|
||||
@property (nonatomic, readonly) MXRoomState *dangerousSyncState;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
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 "MXRoom+Sync.h"
|
||||
|
||||
@implementation MXRoom (Sync)
|
||||
|
||||
- (MXRoomState *)dangerousSyncState
|
||||
{
|
||||
__block MXRoomState *syncState;
|
||||
|
||||
// If syncState is called from the right place, the following call will be
|
||||
// synchronous and every thing will be fine
|
||||
[self state:^(MXRoomState *roomState) {
|
||||
syncState = roomState;
|
||||
}];
|
||||
|
||||
NSAssert(syncState, @"[MXRoom+Sync] syncState failed. Are you sure the state of the room has been already loaded?");
|
||||
|
||||
return syncState;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// 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 <MatrixSDK/MatrixSDK.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MXSession (MatrixKit)
|
||||
|
||||
/// Flag to indicate whether the session is in a suitable state to show some activity indicators on UI.
|
||||
@property (nonatomic, readonly) BOOL shouldShowActivityIndicator;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// 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 "MXSession+MatrixKit.h"
|
||||
|
||||
@implementation MXSession (MatrixKit)
|
||||
|
||||
- (BOOL)shouldShowActivityIndicator
|
||||
{
|
||||
switch (self.state)
|
||||
{
|
||||
case MXSessionStateInitialised:
|
||||
case MXSessionStateProcessingBackgroundSyncCache:
|
||||
case MXSessionStateSyncInProgress:
|
||||
return YES;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
public extension NSAttributedString {
|
||||
/// Returns a string created by joining all ranges of the attributed string that don't have
|
||||
/// the `kMXKToolsBlockquoteMarkAttribute` attribute.
|
||||
@objc func mxk_unquotedString() -> NSString? {
|
||||
var unquotedSubstrings = [String]()
|
||||
|
||||
enumerateAttributes(in: NSRange(location: 0, length: self.length), options: []) { attributes, range, stop in
|
||||
guard !attributes.keys.contains(where: { $0.rawValue == kMXKToolsBlockquoteMarkAttribute }) else { return }
|
||||
unquotedSubstrings.append(self.attributedSubstring(from: range).string)
|
||||
}
|
||||
|
||||
return unquotedSubstrings.joined(separator: " ") as NSString
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
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>
|
||||
|
||||
@interface NSBundle (MXKLanguage)
|
||||
|
||||
/**
|
||||
Set the application language independently from the device language.
|
||||
|
||||
The language can be changed at runtime but the app display must be reloaded.
|
||||
|
||||
@param language the ISO language code. nil lets the OS choose it according to the device language
|
||||
and languages available in the app bundle.
|
||||
*/
|
||||
+ (void)mxk_setLanguage:(NSString *)language;
|
||||
|
||||
/**
|
||||
The language set by mxk_setLanguage.
|
||||
|
||||
@return the ISO language code of the current language.
|
||||
*/
|
||||
+ (NSString *)mxk_language;
|
||||
|
||||
/**
|
||||
Some strings may lack a translation in a language.
|
||||
Use mxk_setFallbackLanguage to define a fallback language where all the
|
||||
translation is complete.
|
||||
|
||||
@param language the ISO language code.
|
||||
*/
|
||||
+ (void)mxk_setFallbackLanguage:(NSString*)language;
|
||||
|
||||
/**
|
||||
The fallback language set by mxk_setFallbackLanguage.
|
||||
|
||||
@return the ISO language code of the current fallback language.
|
||||
*/
|
||||
+ (NSString *)mxk_fallbackLanguage;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
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 "NSBundle+MXKLanguage.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
static const char _bundle = 0;
|
||||
static const char _fallbackBundle = 0;
|
||||
static const char _language = 0;
|
||||
static const char _fallbackLanguage = 0;
|
||||
|
||||
@interface MXKLanguageBundle : NSBundle
|
||||
@end
|
||||
|
||||
@implementation MXKLanguageBundle
|
||||
|
||||
- (NSString*)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
|
||||
{
|
||||
NSBundle* bundle = objc_getAssociatedObject(self, &_bundle);
|
||||
|
||||
// Check if the translation is available in the selected or default language.
|
||||
// Use "_", a string that does not worth to be translated, as default value to mark
|
||||
// a key that does not have a translation.
|
||||
NSString *localizedString = bundle ? [bundle localizedStringForKey:key value:@"_" table:tableName] : [super localizedStringForKey:key value:@"_" table:tableName];
|
||||
|
||||
if (!localizedString || (localizedString.length == 1 && [localizedString isEqualToString:@"_"]))
|
||||
{
|
||||
// Use the string in the fallback language
|
||||
NSBundle *fallbackBundle = objc_getAssociatedObject(self, &_fallbackBundle);
|
||||
localizedString = [fallbackBundle localizedStringForKey:key value:value table:tableName];
|
||||
}
|
||||
|
||||
return localizedString;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSBundle (MXKLanguage)
|
||||
|
||||
+ (void)mxk_setLanguage:(NSString *)language
|
||||
{
|
||||
[self setupMXKLanguageBundle];
|
||||
|
||||
// [NSBundle localizedStringForKey] calls will be redirected to the bundle corresponding
|
||||
// to "language"
|
||||
objc_setAssociatedObject([NSBundle mainBundle],
|
||||
&_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil,
|
||||
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
|
||||
objc_setAssociatedObject([NSBundle mainBundle],
|
||||
&_language, language,
|
||||
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
+ (NSString *)mxk_language
|
||||
{
|
||||
return objc_getAssociatedObject([NSBundle mainBundle], &_language);
|
||||
}
|
||||
|
||||
+ (void)mxk_setFallbackLanguage:(NSString *)language
|
||||
{
|
||||
[self setupMXKLanguageBundle];
|
||||
|
||||
objc_setAssociatedObject([NSBundle mainBundle],
|
||||
&_fallbackBundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil,
|
||||
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
|
||||
objc_setAssociatedObject([NSBundle mainBundle],
|
||||
&_fallbackLanguage, language,
|
||||
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
+ (NSString *)mxk_fallbackLanguage
|
||||
{
|
||||
return objc_getAssociatedObject([NSBundle mainBundle], &_fallbackLanguage);
|
||||
}
|
||||
|
||||
#pragma mark - Private methods
|
||||
|
||||
+ (void)setupMXKLanguageBundle
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
|
||||
// Use MXKLanguageBundle as the [NSBundle mainBundle] class
|
||||
object_setClass([NSBundle mainBundle], [MXKLanguageBundle class]);
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
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>
|
||||
|
||||
/**
|
||||
Define a `NSBundle` category at MatrixKit level to retrieve images and sounds from MatrixKit Assets bundle.
|
||||
*/
|
||||
@interface NSBundle (MatrixKit)
|
||||
|
||||
/**
|
||||
Retrieve an image from MatrixKit Assets bundle.
|
||||
|
||||
@param name image file name without extension.
|
||||
@return a UIImage instance (nil if the file does not exist).
|
||||
*/
|
||||
+ (UIImage *)mxk_imageFromMXKAssetsBundleWithName:(NSString *)name;
|
||||
|
||||
/**
|
||||
Retrieve an audio file url from MatrixKit Assets bundle.
|
||||
|
||||
@param name audio file name without extension.
|
||||
@return a NSURL instance.
|
||||
*/
|
||||
+ (NSURL *)mxk_audioURLFromMXKAssetsBundleWithName:(NSString *)name;
|
||||
|
||||
/**
|
||||
Customize the table used to retrieve the localized version of a string during [mxk_localizedStringForKey:] call.
|
||||
If the key is not defined in this table, the localized string is retrieved from the default table "MatrixKit.strings".
|
||||
|
||||
@param tableName the name of the table containing the key-value pairs. Also, the suffix for the strings file (a file with the .strings extension) to store the localized string.
|
||||
*/
|
||||
+ (void)mxk_customizeLocalizedStringTableName:(NSString*)tableName;
|
||||
|
||||
/**
|
||||
Retrieve localized string from the customized table. If none, MatrixKit Assets bundle is used.
|
||||
|
||||
@param key The string key.
|
||||
@return The localized string.
|
||||
*/
|
||||
+ (NSString *)mxk_localizedStringForKey:(NSString *)key;
|
||||
|
||||
/**
|
||||
An AppExtension-compatible wrapper for bundleForClass.
|
||||
*/
|
||||
+ (NSBundle *)mxk_bundleForClass:(Class)aClass;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
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 "NSBundle+MatrixKit.h"
|
||||
#import "NSBundle+MXKLanguage.h"
|
||||
#import "MXKViewController.h"
|
||||
|
||||
@implementation NSBundle (MatrixKit)
|
||||
|
||||
static NSString *customLocalizedStringTableName = nil;
|
||||
|
||||
+ (NSBundle*)mxk_assetsBundle
|
||||
{
|
||||
// Get the bundle within MatrixKit
|
||||
NSBundle *bundle = [NSBundle mxk_bundleForClass:[MXKViewController class]];
|
||||
NSURL *assetsBundleURL = [bundle URLForResource:@"MatrixKitAssets" withExtension:@"bundle"];
|
||||
|
||||
return [NSBundle bundleWithURL:assetsBundleURL];
|
||||
}
|
||||
|
||||
+ (NSBundle*)mxk_languageBundle
|
||||
{
|
||||
NSString *language = [NSBundle mxk_language];
|
||||
NSBundle *bundle = [NSBundle mxk_assetsBundle];
|
||||
|
||||
// If there is a runtime language (different from the legacy language chose by the OS),
|
||||
// return the sub bundle for this language
|
||||
if (language)
|
||||
{
|
||||
bundle = [NSBundle bundleWithPath:[bundle pathForResource:[NSBundle mxk_language] ofType:@"lproj"]];
|
||||
}
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
+ (NSBundle*)mxk_fallbackLanguageBundle
|
||||
{
|
||||
NSString *fallbackLanguage = [NSBundle mxk_fallbackLanguage];
|
||||
NSBundle *bundle = [NSBundle mxk_assetsBundle];
|
||||
|
||||
// Return the sub bundle of the fallback language if any
|
||||
if (fallbackLanguage)
|
||||
{
|
||||
bundle = [NSBundle bundleWithPath:[bundle pathForResource:fallbackLanguage ofType:@"lproj"]];
|
||||
}
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
// use a cache to avoid loading images from file system.
|
||||
// It often triggers an UI lag.
|
||||
static MXLRUCache *imagesResourceCache = nil;
|
||||
|
||||
+ (UIImage *)mxk_imageFromMXKAssetsBundleWithName:(NSString *)name
|
||||
{
|
||||
// use a cache to avoid loading the image at each call
|
||||
if (!imagesResourceCache)
|
||||
{
|
||||
imagesResourceCache = [[MXLRUCache alloc] initWithCapacity:20];
|
||||
}
|
||||
|
||||
NSString *imagePath = [[NSBundle mxk_assetsBundle] pathForResource:name ofType:@"png" inDirectory:@"Images"];
|
||||
UIImage* image = (UIImage*)[imagesResourceCache get:imagePath];
|
||||
|
||||
// the image does not exist
|
||||
if (!image)
|
||||
{
|
||||
// retrieve it
|
||||
image = [UIImage imageWithContentsOfFile:imagePath];
|
||||
// and store it in the cache.
|
||||
[imagesResourceCache put:imagePath object:image];
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
+ (NSURL*)mxk_audioURLFromMXKAssetsBundleWithName:(NSString *)name
|
||||
{
|
||||
return [NSURL fileURLWithPath:[[NSBundle mxk_assetsBundle] pathForResource:name ofType:@"mp3" inDirectory:@"Sounds"]];
|
||||
}
|
||||
|
||||
+ (void)mxk_customizeLocalizedStringTableName:(NSString*)tableName
|
||||
{
|
||||
customLocalizedStringTableName = tableName;
|
||||
}
|
||||
|
||||
+ (NSString *)mxk_localizedStringForKey:(NSString *)key
|
||||
{
|
||||
NSString *localizedString;
|
||||
|
||||
// Check first customized table
|
||||
// Use "_", a string that does not worth to be translated, as default value to mark
|
||||
// a key that does not have a value in the customized table.
|
||||
if (customLocalizedStringTableName)
|
||||
{
|
||||
localizedString = NSLocalizedStringWithDefaultValue(key, customLocalizedStringTableName, [NSBundle mainBundle], @"_", nil);
|
||||
}
|
||||
|
||||
if (!localizedString || (localizedString.length == 1 && [localizedString isEqualToString:@"_"]))
|
||||
{
|
||||
// Check if we need to manage a fallback language
|
||||
// as we do in NSBundle+MXKLanguage
|
||||
NSString *language = [NSBundle mxk_language];
|
||||
NSString *fallbackLanguage = [NSBundle mxk_fallbackLanguage];
|
||||
|
||||
BOOL manageFallbackLanguage = fallbackLanguage && ![fallbackLanguage isEqualToString:language];
|
||||
|
||||
localizedString = NSLocalizedStringWithDefaultValue(key, @"MatrixKit",
|
||||
[NSBundle mxk_languageBundle],
|
||||
manageFallbackLanguage ? @"_" : nil,
|
||||
nil);
|
||||
|
||||
if (manageFallbackLanguage
|
||||
&& (!localizedString || (localizedString.length == 1 && [localizedString isEqualToString:@"_"])))
|
||||
{
|
||||
// The translation is not available, use the fallback language
|
||||
localizedString = NSLocalizedStringFromTableInBundle(key, @"MatrixKit",
|
||||
[NSBundle mxk_fallbackLanguageBundle],
|
||||
nil);
|
||||
}
|
||||
}
|
||||
|
||||
return localizedString;
|
||||
}
|
||||
|
||||
+ (NSBundle *)mxk_bundleForClass:(Class)aClass
|
||||
{
|
||||
NSBundle *bundle = [NSBundle bundleForClass:aClass];
|
||||
if ([[bundle.bundleURL pathExtension] isEqualToString:@"appex"])
|
||||
{
|
||||
// For App extensions, peel off two levels
|
||||
bundle = [NSBundle bundleWithURL:[[bundle.bundleURL URLByDeletingLastPathComponent] URLByDeletingLastPathComponent]];
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// 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 MatrixSDK.MXLog
|
||||
|
||||
public extension NSString {
|
||||
/// Gets the first URL contained in the string ignoring any links to hosts defined in
|
||||
/// the `firstURLDetectionIgnoredHosts` property of `MXKAppSettings`.
|
||||
/// - Returns: A URL if detected, otherwise nil.
|
||||
@objc func mxk_firstURLDetected() -> NSURL? {
|
||||
let hosts = MXKAppSettings.standard().firstURLDetectionIgnoredHosts ?? []
|
||||
return mxk_firstURLDetected(ignoring: hosts)
|
||||
}
|
||||
|
||||
/// Gets the first URL contained in the string ignoring any links to the specified hosts.
|
||||
/// - Returns: A URL if detected, otherwise nil.
|
||||
@objc func mxk_firstURLDetected(ignoring ignoredHosts: [String]) -> NSURL? {
|
||||
guard let linkDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
|
||||
MXLog.debug("[NSString+URLDetector]: Unable to create link detector.")
|
||||
return nil
|
||||
}
|
||||
|
||||
var detectedURL: NSURL?
|
||||
|
||||
// enumerate all urls that were found in the string to ensure
|
||||
// detection of a valid link if there are invalid links preceding it
|
||||
linkDetector.enumerateMatches(in: self as String,
|
||||
options: [],
|
||||
range: NSRange(location: 0, length: self.length)) { match, flags, stop in
|
||||
guard let match = match else { return }
|
||||
|
||||
// check if the match is a valid url
|
||||
let urlString = self.substring(with: match.range)
|
||||
guard let url = NSURL(string: urlString) else { return }
|
||||
|
||||
// ensure the match is a web link
|
||||
guard let scheme = url.scheme?.lowercased(),
|
||||
scheme == "https" || scheme == "http"
|
||||
else { return }
|
||||
|
||||
// discard any links to ignored hosts
|
||||
guard let host = url.host?.lowercased(),
|
||||
!ignoredHosts.contains(host)
|
||||
else { return }
|
||||
|
||||
detectedURL = url
|
||||
stop.pointee = true
|
||||
}
|
||||
|
||||
return detectedURL
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
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 <UIKit/UIKit.h>
|
||||
|
||||
/**
|
||||
Define a `UIAlertController` category at MatrixKit level to handle accessibility identifiers.
|
||||
*/
|
||||
@interface UIAlertController (MatrixKit)
|
||||
|
||||
/**
|
||||
Apply an accessibility on the alert view and its items (actions and text fields).
|
||||
|
||||
@param accessibilityIdentifier the identifier.
|
||||
*/
|
||||
- (void)mxk_setAccessibilityIdentifier:(NSString *)accessibilityIdentifier;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
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 "UIAlertController+MatrixKit.h"
|
||||
|
||||
@implementation UIAlertController (MatrixKit)
|
||||
|
||||
- (void)mxk_setAccessibilityIdentifier:(NSString *)accessibilityIdentifier
|
||||
{
|
||||
self.view.accessibilityIdentifier = accessibilityIdentifier;
|
||||
|
||||
for (UIAlertAction *action in self.actions)
|
||||
{
|
||||
action.accessibilityLabel = [NSString stringWithFormat:@"%@Action%@", accessibilityIdentifier, action.title];
|
||||
}
|
||||
|
||||
NSArray *textFieldArray = self.textFields;
|
||||
for (NSUInteger index = 0; index < textFieldArray.count; index++)
|
||||
{
|
||||
UITextField *textField = textFieldArray[index];
|
||||
textField.accessibilityIdentifier = [NSString stringWithFormat:@"%@TextField%tu", accessibilityIdentifier, index];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright 2019 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;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UITextView(MatrixKit)
|
||||
|
||||
/**
|
||||
Determine if there is a link near a location point in UITextView bounds.
|
||||
|
||||
@param point The point inside the UITextView bounds
|
||||
@return YES to indicate that a link has been detected near the location point.
|
||||
*/
|
||||
- (BOOL)isThereALinkNearPoint:(CGPoint)point;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2019 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 "UITextView+MatrixKit.h"
|
||||
|
||||
@implementation UITextView(MatrixKit)
|
||||
|
||||
- (BOOL)isThereALinkNearPoint:(CGPoint)point
|
||||
{
|
||||
if (!CGRectContainsPoint(self.bounds, point))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
UITextPosition *textPosition = [self closestPositionToPoint:point];
|
||||
|
||||
if (!textPosition)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
UITextRange *textRange = [self.tokenizer rangeEnclosingPosition:textPosition
|
||||
withGranularity:UITextGranularityCharacter
|
||||
inDirection:UITextLayoutDirectionLeft];
|
||||
|
||||
if (!textRange)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSInteger startIndex = [self offsetFromPosition:self.beginningOfDocument toPosition:textRange.start];
|
||||
|
||||
if (startIndex < 0)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
return [self.attributedText attribute:NSLinkAttributeName atIndex:startIndex effectiveRange:NULL] != nil;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
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>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIViewController (MatrixKit)
|
||||
|
||||
/**
|
||||
The main navigation controller if the view controller is embedded inside a split view controller.
|
||||
*/
|
||||
@property (nullable, nonatomic, readonly) UINavigationController *mxk_mainNavigationController;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 "UIViewController+MatrixKit.h"
|
||||
|
||||
@implementation UIViewController (MatrixKit)
|
||||
|
||||
- (UINavigationController *)mxk_mainNavigationController
|
||||
{
|
||||
UINavigationController *mainNavigationController;
|
||||
|
||||
if (self.splitViewController)
|
||||
{
|
||||
mainNavigationController = self.navigationController;
|
||||
UIViewController *parentViewController = self.parentViewController;
|
||||
while (parentViewController)
|
||||
{
|
||||
if (parentViewController.navigationController)
|
||||
{
|
||||
mainNavigationController = parentViewController.navigationController;
|
||||
parentViewController = parentViewController.parentViewController;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mainNavigationController;
|
||||
}
|
||||
@end
|
||||
Reference in New Issue
Block a user