From 0c1e9a4812035b3626d0d7323558a80a419f2ae3 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Fri, 6 May 2022 08:32:04 -0400 Subject: [PATCH] Remove Share Extensions (#6238) --- android/app/src/main/AndroidManifest.xml | 18 - .../mattermost/rnbeta/MainApplication.java | 4 - .../com/mattermost/share/ShareActivity.java | 20 - .../com/mattermost/share/ShareModule.java | 263 -------- fastlane/Fastfile | 37 -- index.ts | 8 +- ios/Mattermost.xcodeproj/project.pbxproj | 269 --------- .../xcschemes/MattermostShare.xcscheme | 94 --- .../Base.lproj/MainInterface.storyboard | 24 - .../ChannelsViewController.swift | 175 ------ ios/MattermostShare/Config.swift | 6 - ios/MattermostShare/GenericPreview.swift | 25 - ios/MattermostShare/GenericPreview.xib | 57 -- ios/MattermostShare/Images/generic.png | Bin 33406 -> 0 bytes ios/MattermostShare/Info.plist | 56 -- ios/MattermostShare/Item.swift | 7 - .../MattermostShare-Bridging-Header.h | 6 - .../MattermostShare.entitlements | 10 - ios/MattermostShare/Section.swift | 13 - ios/MattermostShare/ShareViewController.swift | 559 ------------------ ios/MattermostShare/TeamsViewController.swift | 57 -- share_extension/index.tsx | 111 ---- 22 files changed, 1 insertion(+), 1818 deletions(-) delete mode 100644 android/app/src/main/java/com/mattermost/share/ShareActivity.java delete mode 100644 android/app/src/main/java/com/mattermost/share/ShareModule.java delete mode 100644 ios/Mattermost.xcodeproj/xcshareddata/xcschemes/MattermostShare.xcscheme delete mode 100644 ios/MattermostShare/Base.lproj/MainInterface.storyboard delete mode 100644 ios/MattermostShare/ChannelsViewController.swift delete mode 100644 ios/MattermostShare/Config.swift delete mode 100644 ios/MattermostShare/GenericPreview.swift delete mode 100644 ios/MattermostShare/GenericPreview.xib delete mode 100644 ios/MattermostShare/Images/generic.png delete mode 100644 ios/MattermostShare/Info.plist delete mode 100644 ios/MattermostShare/Item.swift delete mode 100644 ios/MattermostShare/MattermostShare-Bridging-Header.h delete mode 100644 ios/MattermostShare/MattermostShare.entitlements delete mode 100644 ios/MattermostShare/Section.swift delete mode 100644 ios/MattermostShare/ShareViewController.swift delete mode 100644 ios/MattermostShare/TeamsViewController.swift delete mode 100644 share_extension/index.tsx diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7a2d60aac..b32be15f9 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -71,23 +71,5 @@ android:resizeableActivity="true" android:exported="true" /> - - - - - - - - - diff --git a/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java b/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java index cf9f1bcab..482106510 100644 --- a/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java +++ b/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java @@ -14,7 +14,6 @@ import java.util.Map; import com.airbnb.android.react.lottie.LottiePackage; import com.mattermost.helpers.RealPathUtil; -import com.mattermost.share.ShareModule; import com.wix.reactnativenotifications.RNNotificationsPackage; import com.reactnativenavigation.NavigationApplication; @@ -73,8 +72,6 @@ public class MainApplication extends NavigationApplication implements INotificat switch (name) { case "MattermostManaged": return MattermostManagedModule.getInstance(reactContext); - case "MattermostShare": - return new ShareModule(instance, reactContext); case "NotificationPreferences": return NotificationPreferencesModule.getInstance(instance, reactContext); default: @@ -87,7 +84,6 @@ public class MainApplication extends NavigationApplication implements INotificat return () -> { Map map = new HashMap<>(); map.put("MattermostManaged", new ReactModuleInfo("MattermostManaged", "com.mattermost.rnbeta.MattermostManagedModule", false, false, false, false, false)); - map.put("MattermostShare", new ReactModuleInfo("MattermostShare", "com.mattermost.share.ShareModule", false, false, true, false, false)); map.put("NotificationPreferences", new ReactModuleInfo("NotificationPreferences", "com.mattermost.rnbeta.NotificationPreferencesModule", false, false, false, false, false)); return map; }; diff --git a/android/app/src/main/java/com/mattermost/share/ShareActivity.java b/android/app/src/main/java/com/mattermost/share/ShareActivity.java deleted file mode 100644 index 573f9ac83..000000000 --- a/android/app/src/main/java/com/mattermost/share/ShareActivity.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.mattermost.share; - -import android.os.Bundle; - -import com.facebook.react.ReactActivity; -import com.mattermost.rnbeta.MainApplication; - -public class ShareActivity extends ReactActivity { - @Override - protected String getMainComponentName() { - return "MattermostShare"; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - MainApplication app = (MainApplication) this.getApplication(); - app.sharedExtensionIsOpened = true; - } -} diff --git a/android/app/src/main/java/com/mattermost/share/ShareModule.java b/android/app/src/main/java/com/mattermost/share/ShareModule.java deleted file mode 100644 index 0f86aba84..000000000 --- a/android/app/src/main/java/com/mattermost/share/ShareModule.java +++ /dev/null @@ -1,263 +0,0 @@ -package com.mattermost.share; - -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.WritableArray; -import com.facebook.react.bridge.Arguments; -import com.mattermost.rnbeta.MainApplication; -import com.mattermost.helpers.RealPathUtil; - -import android.app.Activity; -import android.content.Intent; -import android.net.Uri; - -import java.io.File; -import java.util.ArrayList; - -import javax.annotation.Nullable; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.json.JSONException; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.MultipartBody; -import okhttp3.RequestBody; -import okhttp3.Response; - -public class ShareModule extends ReactContextBaseJavaModule { - private final OkHttpClient client = new OkHttpClient(); - public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private final MainApplication mApplication; - - public ShareModule(MainApplication application, ReactApplicationContext reactContext) { - super(reactContext); - mApplication = application; - } - private File tempFolder; - - @Override - public String getName() { - return "MattermostShare"; - } - - @ReactMethod - public void clear() { - Activity currentActivity = getCurrentActivity(); - - if (currentActivity != null) { - Intent intent = currentActivity.getIntent(); - intent.setAction(""); - intent.removeExtra(Intent.EXTRA_TEXT); - intent.removeExtra(Intent.EXTRA_STREAM); - } - } - - @Nullable - @Override - public Map getConstants() { - HashMap constants = new HashMap<>(1); - constants.put("cacheDirName", RealPathUtil.CACHE_DIR_NAME); - constants.put("isOpened", mApplication.sharedExtensionIsOpened); - mApplication.sharedExtensionIsOpened = false; - return constants; - } - - @ReactMethod - public void close(ReadableMap data) { - this.clear(); - Activity currentActivity = getCurrentActivity(); - if (currentActivity != null) { - currentActivity.finishAndRemoveTask(); - } - - if (data != null && data.hasKey("url")) { - ReadableArray files = data.getArray("files"); - String serverUrl = data.getString("url"); - String token = data.getString("token"); - JSONObject postData = buildPostObject(data); - - if (files.size() > 0) { - uploadFiles(serverUrl, token, files, postData); - } else { - try { - post(serverUrl, token, postData); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - RealPathUtil.deleteTempFiles(this.tempFolder); - } - - @ReactMethod - public void data(Promise promise) { - promise.resolve(processIntent()); - } - - @ReactMethod - public void getFilePath(String filePath, Promise promise) { - Activity currentActivity = getCurrentActivity(); - WritableMap map = Arguments.createMap(); - - if (currentActivity != null) { - Uri uri = Uri.parse(filePath); - String path = RealPathUtil.getRealPathFromURI(currentActivity, uri); - if (path != null) { - String text = "file://" + path; - map.putString("filePath", text); - } - } - - promise.resolve(map); - } - - public WritableArray processIntent() { - WritableMap map = Arguments.createMap(); - WritableArray items = Arguments.createArray(); - - String text = ""; - String type = ""; - String action = ""; - - Activity currentActivity = getCurrentActivity(); - - if (currentActivity != null) { - this.tempFolder = new File(currentActivity.getCacheDir(), RealPathUtil.CACHE_DIR_NAME); - Intent intent = currentActivity.getIntent(); - action = intent.getAction(); - type = intent.getType(); - if (type == null) { - type = ""; - } - - if (Intent.ACTION_SEND.equals(action) && "text/plain".equals(type)) { - text = intent.getStringExtra(Intent.EXTRA_TEXT); - map.putString("value", text); - map.putString("type", type); - items.pushMap(map); - } else if (Intent.ACTION_SEND.equals(action)) { - Uri uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM); - if (uri != null) { - text = "file://" + RealPathUtil.getRealPathFromURI(currentActivity, uri); - map.putString("value", text); - - if (type.equals("image/*")) { - type = "image/jpeg"; - } else if (type.equals("video/*")) { - type = "video/mp4"; - } - - map.putString("type", type); - items.pushMap(map); - } - } else if (Intent.ACTION_SEND_MULTIPLE.equals(action)) { - ArrayList uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); - for (Uri uri : uris) { - String filePath = RealPathUtil.getRealPathFromURI(currentActivity, uri); - map = Arguments.createMap(); - text = "file://" + filePath; - map.putString("value", text); - - type = RealPathUtil.getMimeTypeFromUri(currentActivity, uri); - if (type != null) { - if (type.equals("image/*")) { - type = "image/jpeg"; - } else if (type.equals("video/*")) { - type = "video/mp4"; - } - } else { - type = "application/octet-stream"; - } - map.putString("type", type); - items.pushMap(map); - } - } - } - - return items; - } - - private JSONObject buildPostObject(ReadableMap data) { - JSONObject json = new JSONObject(); - try { - json.put("user_id", data.getString("currentUserId")); - if (data.hasKey("channelId")) { - json.put("channel_id", data.getString("channelId")); - } - if (data.hasKey("value")) { - json.put("message", data.getString("value")); - } - } catch (JSONException e) { - e.printStackTrace(); - } - return json; - } - - private void post(String serverUrl, String token, JSONObject postData) throws IOException { - RequestBody body = RequestBody.create(JSON, postData.toString()); - Request request = new Request.Builder() - .header("Authorization", "BEARER " + token) - .url(serverUrl + "/api/v4/posts") - .post(body) - .build(); - Response response = client.newCall(request).execute(); - } - - private void uploadFiles(String serverUrl, String token, ReadableArray files, JSONObject postData) { - try { - MultipartBody.Builder builder = new MultipartBody.Builder() - .setType(MultipartBody.FORM); - - for(int i = 0 ; i < files.size() ; i++) { - ReadableMap file = files.getMap(i); - String filePath = file.getString("fullPath").replaceFirst("file://", ""); - File fileInfo = new File(filePath); - if (fileInfo.exists()) { - final MediaType MEDIA_TYPE = MediaType.parse(file.getString("mimeType")); - builder.addFormDataPart("files", file.getString("filename"), RequestBody.create(MEDIA_TYPE, fileInfo)); - } - } - - builder.addFormDataPart("channel_id", postData.getString("channel_id")); - RequestBody body = builder.build(); - Request request = new Request.Builder() - .header("Authorization", "BEARER " + token) - .url(serverUrl + "/api/v4/files") - .post(body) - .build(); - - try (Response response = client.newCall(request).execute()) { - if (response.isSuccessful()) { - String responseData = response.body().string(); - JSONObject responseJson = new JSONObject(responseData); - JSONArray fileInfoArray = responseJson.getJSONArray("file_infos"); - JSONArray file_ids = new JSONArray(); - for(int i = 0 ; i < fileInfoArray.length() ; i++) { - JSONObject fileInfo = fileInfoArray.getJSONObject(i); - file_ids.put(fileInfo.getString("id")); - } - postData.put("file_ids", file_ids); - post(serverUrl, token, postData); - } - } catch (IOException e) { - e.printStackTrace(); - } - - } catch (JSONException e) { - e.printStackTrace(); - } - } -} diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 39fc55121..957d64fb1 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -403,20 +403,6 @@ platform :ios do new_string: notification_bundle_id ) - # Set the share extension bundle identifier - extension_bundle_id = ENV['EXTENSION_APP_IDENTIFIER'] || 'com.mattermost.rnbeta.MattermostShare' - update_app_identifier( - xcodeproj: './ios/Mattermost.xcodeproj', - plist_path: 'MattermostShare/Info.plist', - app_identifier: extension_bundle_id - ) - - find_replace_string( - path_to_file: './ios/Mattermost.xcodeproj/project.pbxproj', - old_string: 'com.mattermost.rnbeta.MattermostShare', - new_string: extension_bundle_id - ) - # Set the app bundle id app_bundle_id = ENV['MAIN_APP_IDENTIFIER'] || 'com.mattermost.rnbeta' update_app_identifier( @@ -473,19 +459,6 @@ platform :ios do end ) - update_app_group_identifiers( - entitlements_file: './ios/MattermostShare/MattermostShare.entitlements', - app_group_identifiers: [app_group_id] - ) - - update_info_plist( - xcodeproj: './ios/Mattermost.xcodeproj', - plist_path: 'MattermostShare/Info.plist', - block: proc do |plist| - plist["AppGroupIdentifier"] = app_group_id - end - ) - update_app_group_identifiers( entitlements_file: './ios/NotificationService/NotificationService.entitlements', app_group_identifiers: [app_group_id] @@ -547,8 +520,6 @@ platform :ios do target = 'Mattermost' if id.include? 'NotificationService' target = 'NotificationService' - elsif id.include? 'MattermostShare' - target = 'MattermostShare' end profile = "sigh_#{id}_#{ENV['MATCH_TYPE']}" @@ -677,14 +648,6 @@ platform :android do ) end - Dir.glob('../android/app/src/main/java/com/mattermost/share/*.java') do |item| - find_replace_string( - path_to_file: item[1..-1], - old_string: 'import com.mattermost.rnbeta.MainApplication;', - new_string: "import #{package_id}.MainApplication;" - ) - end - Dir.glob('../android/app/src/main/java/com/mattermost/helpers/*.java') do |item| find_replace_string( path_to_file: item[1..-1], diff --git a/index.ts b/index.ts index 2a2c98b22..bdc439f7a 100644 --- a/index.ts +++ b/index.ts @@ -1,7 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {DeviceEventEmitter, LogBox, Platform} from 'react-native'; +import {DeviceEventEmitter, LogBox} from 'react-native'; import {RUNNING_E2E} from 'react-native-dotenv'; import 'react-native-gesture-handler'; import {ComponentDidAppearEvent, ComponentDidDisappearEvent, Navigation} from 'react-native-navigation'; @@ -52,12 +52,6 @@ if (global.HermesInternal) { require('@formatjs/intl-datetimeformat/add-golden-tz'); } -if (Platform.OS === 'android') { - const ShareExtension = require('share_extension/index.tsx').default; - const AppRegistry = require('react-native/Libraries/ReactNative/AppRegistry'); - AppRegistry.registerComponent('MattermostShare', () => ShareExtension); -} - let alreadyInitialized = false; Navigation.events().registerAppLaunchedListener(async () => { // See caution in the library doc https://wix.github.io/react-native-navigation/docs/app-launch#android diff --git a/ios/Mattermost.xcodeproj/project.pbxproj b/ios/Mattermost.xcodeproj/project.pbxproj index e51c416c5..e288f61c8 100644 --- a/ios/Mattermost.xcodeproj/project.pbxproj +++ b/ios/Mattermost.xcodeproj/project.pbxproj @@ -12,32 +12,19 @@ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 4953BF602368AE8600593328 /* SwimeProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4953BF5F2368AE8600593328 /* SwimeProxy.swift */; }; - 49AE36FF26D4455800EF4E52 /* Gekidou in Frameworks */ = {isa = PBXBuildFile; productRef = 49AE36FE26D4455800EF4E52 /* Gekidou */; }; 49AE370126D4455D00EF4E52 /* Gekidou in Frameworks */ = {isa = PBXBuildFile; productRef = 49AE370026D4455D00EF4E52 /* Gekidou */; }; 49B4C050230C981C006E919E /* libUploadAttachments.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FABE04522137F2A00D0F595 /* libUploadAttachments.a */; }; - 531BEBC72513E93C00BC05B1 /* compass-icons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 531BEBC52513E93C00BC05B1 /* compass-icons.ttf */; }; 536CC6C323E79287002C478C /* RNNotificationEventHandler+HandleReplyAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 536CC6C123E79287002C478C /* RNNotificationEventHandler+HandleReplyAction.m */; }; 58495E36BF1A4EAB93609E57 /* Metropolis-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 54956DEFEBB74EF78C3A6AE5 /* Metropolis-SemiBold.ttf */; }; 6C9B1EFD6561083917AF06CF /* libPods-Mattermost.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DEEFB3ED6175724A2653247 /* libPods-Mattermost.a */; }; 7F0F4B0A24BA173900E14C60 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7F0F4B0924BA173900E14C60 /* LaunchScreen.storyboard */; }; 7F151D3E221B062700FAD8F3 /* RuntimeUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F151D3D221B062700FAD8F3 /* RuntimeUtils.swift */; }; 7F1EB88527FDE361002E7EEC /* GekidouWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F1EB88427FDE361002E7EEC /* GekidouWrapper.swift */; }; - 7F240A1C220D3A2300637665 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F240A1B220D3A2300637665 /* ShareViewController.swift */; }; - 7F240A1F220D3A2300637665 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7F240A1D220D3A2300637665 /* MainInterface.storyboard */; }; - 7F240A23220D3A2300637665 /* MattermostShare.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 7F240A19220D3A2300637665 /* MattermostShare.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 7F240ADB220E089300637665 /* Item.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F240ADA220E089300637665 /* Item.swift */; }; - 7F240ADD220E094A00637665 /* TeamsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F240ADC220E094A00637665 /* TeamsViewController.swift */; }; 7F292A711E8AB73400A450A3 /* SplashScreenResource in Resources */ = {isa = PBXBuildFile; fileRef = 7F292A701E8AB73400A450A3 /* SplashScreenResource */; }; 7F581D35221ED5C60099E66B /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F581D34221ED5C60099E66B /* NotificationService.swift */; }; 7F581D39221ED5C60099E66B /* NotificationService.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 7F581D32221ED5C60099E66B /* NotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 7F581F78221EEA7C0099E66B /* libUploadAttachments.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FABE04522137F2A00D0F595 /* libUploadAttachments.a */; }; - 7F72F2EE2211220500F98FFF /* GenericPreview.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7F72F2ED2211220500F98FFF /* GenericPreview.xib */; }; - 7F72F2F0221123E200F98FFF /* GenericPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F72F2EF221123E200F98FFF /* GenericPreview.swift */; }; - 7F72F2F322112EC700F98FFF /* generic.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F72F2F222112EC700F98FFF /* generic.png */; }; 7F98836227FD46A9001C9BFC /* Gekidou in Frameworks */ = {isa = PBXBuildFile; productRef = 7F98836127FD46A9001C9BFC /* Gekidou */; }; - 7FABDFC22211A39000D0F595 /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FABDFC12211A39000D0F595 /* Section.swift */; }; - 7FABE00A2212650600D0F595 /* ChannelsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FABE0092212650600D0F595 /* ChannelsViewController.swift */; }; - 7FABE0562213884700D0F595 /* libUploadAttachments.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FABE04522137F2A00D0F595 /* libUploadAttachments.a */; }; 7FB31F812710995B0032E2E5 /* Metropolis-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7F25B626270F666D00F32373 /* Metropolis-Light.ttf */; }; 7FB31F822710996D0032E2E5 /* Metropolis-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7F25B628270F666D00F32373 /* Metropolis-Regular.ttf */; }; 7FB31F842710996D0032E2E5 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D4B1B363C2414DA19C1AC521 /* OpenSans-Bold.ttf */; }; @@ -51,18 +38,10 @@ 7FB31F8E2710996D0032E2E5 /* compass-icons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 531BEBC52513E93C00BC05B1 /* compass-icons.ttf */; }; 7FCEFB9326B7934F006DC1DE /* SDWebImageDownloaderOperation+Swizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FCEFB9226B7934F006DC1DE /* SDWebImageDownloaderOperation+Swizzle.m */; }; 7FEB109D1F61019C0039A015 /* MattermostManaged.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FEB109A1F61019C0039A015 /* MattermostManaged.m */; }; - 84E3264B229834C30055068A /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E325FF229834C30055068A /* Config.swift */; }; A94508A396424B2DB778AFE9 /* OpenSans-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E5C16B14E1CE4868886A1A00 /* OpenSans-SemiBold.ttf */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 7F240A21220D3A2300637665 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 7F240A18220D3A2300637665; - remoteInfo = MattermostShare; - }; 7F581D37221ED5C60099E66B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; @@ -70,13 +49,6 @@ remoteGlobalIDString = 7F581D31221ED5C60099E66B; remoteInfo = NotificationService; }; - 7FAB4570222DD0DA00EBFFC8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 7FABE04022137F2900D0F595 /* UploadAttachments.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 7FABE03522137F2900D0F595; - remoteInfo = UploadAttachments; - }; 7FAB45B9222DD0E300EBFFC8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 7FABE04022137F2900D0F595 /* UploadAttachments.xcodeproj */; @@ -117,7 +89,6 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( - 7F240A23220D3A2300637665 /* MattermostShare.appex in Embed App Extensions */, 7F581D39221ED5C60099E66B /* NotificationService.appex in Embed App Extensions */, ); name = "Embed App Extensions"; @@ -157,16 +128,8 @@ 6BAF8296411D4657B5A0E8F8 /* libRNReactNativeDocViewer.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNReactNativeDocViewer.a; sourceTree = ""; }; 7F0F4B0924BA173900E14C60 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = SplashScreenResource/LaunchScreen.storyboard; sourceTree = ""; }; 7F151D3D221B062700FAD8F3 /* RuntimeUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RuntimeUtils.swift; path = Mattermost/RuntimeUtils.swift; sourceTree = ""; }; - 7F151D42221B07F700FAD8F3 /* MattermostShare-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MattermostShare-Bridging-Header.h"; sourceTree = ""; }; 7F151D43221B082A00FAD8F3 /* Mattermost-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Mattermost-Bridging-Header.h"; path = "Mattermost/Mattermost-Bridging-Header.h"; sourceTree = ""; }; 7F1EB88427FDE361002E7EEC /* GekidouWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GekidouWrapper.swift; sourceTree = ""; }; - 7F240A19220D3A2300637665 /* MattermostShare.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MattermostShare.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - 7F240A1B220D3A2300637665 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; - 7F240A1E220D3A2300637665 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; - 7F240A20220D3A2300637665 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 7F240A27220D3A7E00637665 /* MattermostShare.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MattermostShare.entitlements; sourceTree = ""; }; - 7F240ADA220E089300637665 /* Item.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Item.swift; sourceTree = ""; }; - 7F240ADC220E094A00637665 /* TeamsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeamsViewController.swift; sourceTree = ""; }; 7F25B626270F666D00F32373 /* Metropolis-Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Metropolis-Light.ttf"; path = "../assets/fonts/Metropolis-Light.ttf"; sourceTree = ""; }; 7F25B628270F666D00F32373 /* Metropolis-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Metropolis-Regular.ttf"; path = "../assets/fonts/Metropolis-Regular.ttf"; sourceTree = ""; }; 7F292A701E8AB73400A450A3 /* SplashScreenResource */ = {isa = PBXFileReference; lastKnownFileType = folder; path = SplashScreenResource; sourceTree = ""; }; @@ -177,11 +140,6 @@ 7F581D36221ED5C60099E66B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7F581F77221EEA5A0099E66B /* NotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NotificationService.entitlements; sourceTree = ""; }; 7F63D2C21E6DD98A001FAE12 /* Mattermost.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Mattermost.entitlements; path = Mattermost/Mattermost.entitlements; sourceTree = ""; }; - 7F72F2ED2211220500F98FFF /* GenericPreview.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GenericPreview.xib; sourceTree = ""; }; - 7F72F2EF221123E200F98FFF /* GenericPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericPreview.swift; sourceTree = ""; }; - 7F72F2F222112EC700F98FFF /* generic.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = generic.png; sourceTree = ""; }; - 7FABDFC12211A39000D0F595 /* Section.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Section.swift; sourceTree = ""; }; - 7FABE0092212650600D0F595 /* ChannelsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsViewController.swift; sourceTree = ""; }; 7FABE04022137F2900D0F595 /* UploadAttachments.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = UploadAttachments.xcodeproj; path = UploadAttachments/UploadAttachments.xcodeproj; sourceTree = ""; }; 7FCEFB9126B7934F006DC1DE /* SDWebImageDownloaderOperation+Swizzle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SDWebImageDownloaderOperation+Swizzle.h"; path = "Mattermost/SDWebImageDownloaderOperation+Swizzle.h"; sourceTree = ""; }; 7FCEFB9226B7934F006DC1DE /* SDWebImageDownloaderOperation+Swizzle.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "SDWebImageDownloaderOperation+Swizzle.m"; path = "Mattermost/SDWebImageDownloaderOperation+Swizzle.m"; sourceTree = ""; }; @@ -199,7 +157,6 @@ 7FFE32BE1FD9CCAA0038C7A0 /* SDWebImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7FFE32BF1FD9CCAA0038C7A0 /* Sentry.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Sentry.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 81061F4CBB31484A94D5A8EE /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; - 84E325FF229834C30055068A /* Config.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = ""; }; 8DEEFB3ED6175724A2653247 /* libPods-Mattermost.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Mattermost.a"; sourceTree = BUILT_PRODUCTS_DIR; }; BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Regular.ttf"; path = "../assets/fonts/OpenSans-Regular.ttf"; sourceTree = ""; }; BE17F630DB5D41FD93F32D22 /* OpenSans-LightItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-LightItalic.ttf"; path = "../assets/fonts/OpenSans-LightItalic.ttf"; sourceTree = ""; }; @@ -221,15 +178,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 7F240A16220D3A2300637665 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 49AE36FF26D4455800EF4E52 /* Gekidou in Frameworks */, - 7FABE0562213884700D0F595 /* libUploadAttachments.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 7F581D2F221ED5C60099E66B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -351,26 +299,6 @@ name = Frameworks; sourceTree = ""; }; - 7F240A1A220D3A2300637665 /* MattermostShare */ = { - isa = PBXGroup; - children = ( - 84E325FF229834C30055068A /* Config.swift */, - 7F72F2E4221113DF00F98FFF /* Images */, - 7F240A20220D3A2300637665 /* Info.plist */, - 7F240A27220D3A7E00637665 /* MattermostShare.entitlements */, - 7F240A1D220D3A2300637665 /* MainInterface.storyboard */, - 7F151D42221B07F700FAD8F3 /* MattermostShare-Bridging-Header.h */, - 7F240ADA220E089300637665 /* Item.swift */, - 7FABE0092212650600D0F595 /* ChannelsViewController.swift */, - 7F240A1B220D3A2300637665 /* ShareViewController.swift */, - 7F240ADC220E094A00637665 /* TeamsViewController.swift */, - 7F72F2ED2211220500F98FFF /* GenericPreview.xib */, - 7F72F2EF221123E200F98FFF /* GenericPreview.swift */, - 7FABDFC12211A39000D0F595 /* Section.swift */, - ); - path = MattermostShare; - sourceTree = ""; - }; 7F581D33221ED5C60099E66B /* NotificationService */ = { isa = PBXGroup; children = ( @@ -381,14 +309,6 @@ path = NotificationService; sourceTree = ""; }; - 7F72F2E4221113DF00F98FFF /* Images */ = { - isa = PBXGroup; - children = ( - 7F72F2F222112EC700F98FFF /* generic.png */, - ); - path = Images; - sourceTree = ""; - }; 7FABE04122137F2900D0F595 /* Products */ = { isa = PBXGroup; children = ( @@ -411,7 +331,6 @@ children = ( 4953BF5F2368AE8600593328 /* SwimeProxy.swift */, 13B07FAE1A68108700A75B9A /* Mattermost */, - 7F240A1A220D3A2300637665 /* MattermostShare */, 7F581D33221ED5C60099E66B /* NotificationService */, 7F292A701E8AB73400A450A3 /* SplashScreenResource */, 832341AE1AAA6A7D00B99B32 /* Libraries */, @@ -430,7 +349,6 @@ isa = PBXGroup; children = ( 13B07F961A680F5B00A75B9A /* Mattermost.app */, - 7F240A19220D3A2300637665 /* MattermostShare.appex */, 7F581D32221ED5C60099E66B /* NotificationService.appex */, ); name = Products; @@ -458,7 +376,6 @@ ); dependencies = ( 7FAB45BA222DD0E300EBFFC8 /* PBXTargetDependency */, - 7F240A22220D3A2300637665 /* PBXTargetDependency */, 7F581D38221ED5C60099E66B /* PBXTargetDependency */, ); name = Mattermost; @@ -469,27 +386,6 @@ productReference = 13B07F961A680F5B00A75B9A /* Mattermost.app */; productType = "com.apple.product-type.application"; }; - 7F240A18220D3A2300637665 /* MattermostShare */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7F240A24220D3A2300637665 /* Build configuration list for PBXNativeTarget "MattermostShare" */; - buildPhases = ( - 7F240A15220D3A2300637665 /* Sources */, - 7F240A16220D3A2300637665 /* Frameworks */, - 7F240A17220D3A2300637665 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 7FAB4571222DD0DA00EBFFC8 /* PBXTargetDependency */, - ); - name = MattermostShare; - packageProductDependencies = ( - 49AE36FE26D4455800EF4E52 /* Gekidou */, - ); - productName = MattermostShare; - productReference = 7F240A19220D3A2300637665 /* MattermostShare.appex */; - productType = "com.apple.product-type.app-extension"; - }; 7F581D31221ED5C60099E66B /* NotificationService */ = { isa = PBXNativeTarget; buildConfigurationList = 7F581D82221ED5C60099E66B /* Build configuration list for PBXNativeTarget "NotificationService" */; @@ -543,16 +439,6 @@ }; }; }; - 7F240A18220D3A2300637665 = { - CreatedOnToolsVersion = 10.1; - DevelopmentTeam = UQ8HT4Q2XM; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.ApplicationGroups.iOS = { - enabled = 1; - }; - }; - }; 7F581D31221ED5C60099E66B = { CreatedOnToolsVersion = 10.1; DevelopmentTeam = UQ8HT4Q2XM; @@ -586,7 +472,6 @@ projectRoot = ""; targets = ( 13B07F861A680F5B00A75B9A /* Mattermost */, - 7F240A18220D3A2300637665 /* MattermostShare */, 7F581D31221ED5C60099E66B /* NotificationService */, ); }; @@ -627,17 +512,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 7F240A17220D3A2300637665 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 531BEBC72513E93C00BC05B1 /* compass-icons.ttf in Resources */, - 7F240A1F220D3A2300637665 /* MainInterface.storyboard in Resources */, - 7F72F2EE2211220500F98FFF /* GenericPreview.xib in Resources */, - 7F72F2F322112EC700F98FFF /* generic.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 7F581D30221ED5C60099E66B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -794,20 +668,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 7F240A15220D3A2300637665 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7F72F2F0221123E200F98FFF /* GenericPreview.swift in Sources */, - 7F240ADB220E089300637665 /* Item.swift in Sources */, - 7F240A1C220D3A2300637665 /* ShareViewController.swift in Sources */, - 7FABDFC22211A39000D0F595 /* Section.swift in Sources */, - 84E3264B229834C30055068A /* Config.swift in Sources */, - 7FABE00A2212650600D0F595 /* ChannelsViewController.swift in Sources */, - 7F240ADD220E094A00637665 /* TeamsViewController.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 7F581D2E221ED5C60099E66B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -819,21 +679,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 7F240A22220D3A2300637665 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 7F240A18220D3A2300637665 /* MattermostShare */; - targetProxy = 7F240A21220D3A2300637665 /* PBXContainerItemProxy */; - }; 7F581D38221ED5C60099E66B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 7F581D31221ED5C60099E66B /* NotificationService */; targetProxy = 7F581D37221ED5C60099E66B /* PBXContainerItemProxy */; }; - 7FAB4571222DD0DA00EBFFC8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = UploadAttachments; - targetProxy = 7FAB4570222DD0DA00EBFFC8 /* PBXContainerItemProxy */; - }; 7FAB45BA222DD0E300EBFFC8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = UploadAttachments; @@ -846,17 +696,6 @@ }; /* End PBXTargetDependency section */ -/* Begin PBXVariantGroup section */ - 7F240A1D220D3A2300637665 /* MainInterface.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 7F240A1E220D3A2300637665 /* Base */, - ); - name = MainInterface.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; @@ -942,101 +781,6 @@ }; name = Release; }; - 7F240A25220D3A2300637665 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = MattermostShare/MattermostShare.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = UQ8HT4Q2XM; - GCC_C_LANGUAGE_STANDARD = gnu11; - HEADER_SEARCH_PATHS = "$(SRCROOT)/UploadAttachments/UploadAttachments"; - INFOPLIST_FILE = MattermostShare/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - OTHER_CFLAGS = ( - "$(inherited)", - "-DFB_SONARKIT_ENABLED=1", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.mattermost.rnbeta.MattermostShare; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OBJC_BRIDGING_HEADER = "MattermostShare/MattermostShare-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.2; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 7F240A26220D3A2300637665 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = MattermostShare/MattermostShare.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = UQ8HT4Q2XM; - GCC_C_LANGUAGE_STANDARD = gnu11; - HEADER_SEARCH_PATHS = "$(SRCROOT)/UploadAttachments/UploadAttachments"; - INFOPLIST_FILE = MattermostShare/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - MTL_FAST_MATH = YES; - OTHER_CFLAGS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = com.mattermost.rnbeta.MattermostShare; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OBJC_BRIDGING_HEADER = "MattermostShare/MattermostShare-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 4.2; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; 7F581D3A221ED5C60099E66B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1226,15 +970,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 7F240A24220D3A2300637665 /* Build configuration list for PBXNativeTarget "MattermostShare" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7F240A25220D3A2300637665 /* Debug */, - 7F240A26220D3A2300637665 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 7F581D82221ED5C60099E66B /* Build configuration list for PBXNativeTarget "NotificationService" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -1256,10 +991,6 @@ /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ - 49AE36FE26D4455800EF4E52 /* Gekidou */ = { - isa = XCSwiftPackageProductDependency; - productName = Gekidou; - }; 49AE370026D4455D00EF4E52 /* Gekidou */ = { isa = XCSwiftPackageProductDependency; productName = Gekidou; diff --git a/ios/Mattermost.xcodeproj/xcshareddata/xcschemes/MattermostShare.xcscheme b/ios/Mattermost.xcodeproj/xcshareddata/xcschemes/MattermostShare.xcscheme deleted file mode 100644 index 1c8abaafb..000000000 --- a/ios/Mattermost.xcodeproj/xcshareddata/xcschemes/MattermostShare.xcscheme +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/MattermostShare/Base.lproj/MainInterface.storyboard b/ios/MattermostShare/Base.lproj/MainInterface.storyboard deleted file mode 100644 index 286a50894..000000000 --- a/ios/MattermostShare/Base.lproj/MainInterface.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/MattermostShare/ChannelsViewController.swift b/ios/MattermostShare/ChannelsViewController.swift deleted file mode 100644 index 26ada828a..000000000 --- a/ios/MattermostShare/ChannelsViewController.swift +++ /dev/null @@ -1,175 +0,0 @@ -import UIKit - -class ChannelsViewController: UIViewController { - - let searchController = UISearchController(searchResultsController: nil) - - lazy var tableView: UITableView = { - let tableView = UITableView(frame: self.view.frame) - tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight] - tableView.dataSource = self - tableView.delegate = self - tableView.backgroundColor = .clear - tableView.register(UITableViewCell.self, forCellReuseIdentifier: Identifiers.ChannelCell) - - return tableView - }() - - var navbarTitle: String? = "Channels" - var channelDecks = [Section]() - var filteredDecks: [Section]? - weak var delegate: ChannelsViewControllerDelegate? - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - if #available(iOS 11.0, *) { - navigationItem.hidesSearchBarWhenScrolling = false - } - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - if #available(iOS 11.0, *) { - navigationItem.hidesSearchBarWhenScrolling = true - } - } - - override func viewDidLoad() { - super.viewDidLoad() - - filteredDecks = channelDecks - title = navbarTitle - configureSearchBar() - view.addSubview(tableView) - } - - func configureSearchBar() { - searchController.searchResultsUpdater = self - searchController.hidesNavigationBarDuringPresentation = false - searchController.dimsBackgroundDuringPresentation = false - searchController.searchBar.searchBarStyle = .minimal - searchController.searchBar.autocapitalizationType = .none - searchController.searchBar.delegate = self - - self.definesPresentationContext = true - - if #available(iOS 11.0, *) { - // For iOS 11 and later, place the search bar in the navigation bar. - - // Give space at the top so provide a better look and feel - let offset = UIOffset(horizontal: 0.0, vertical: 6.0) - searchController.searchBar.searchFieldBackgroundPositionAdjustment = offset - - - navigationItem.searchController = searchController - } else { - // For iOS 10 and earlier, place the search controller's search bar in the table view's header. - tableView.tableHeaderView = searchController.searchBar - } - } - -} - -private extension ChannelsViewController { - struct Identifiers { - static let ChannelCell = "channelCell" - } -} - -extension ChannelsViewController: UITableViewDataSource { - func numberOfSections(in tableView: UITableView) -> Int { - return filteredDecks?.count ?? 0 - } - - func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - let sec = filteredDecks?[section] - if (sec?.items.count)! > 0 { - return sec?.title - } - - return nil - } - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return filteredDecks?[section].items.count ?? 0 - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let section = filteredDecks?[indexPath.section] - let cell = tableView.dequeueReusableCell(withIdentifier: Identifiers.ChannelCell, for: indexPath) - let item = section?.items[indexPath.row] - cell.textLabel?.text = item?.title - if item?.selected ?? false { - cell.accessoryType = .checkmark - } else { - cell.accessoryType = .none - } - cell.backgroundColor = .clear - return cell - } -} - -protocol ChannelsViewControllerDelegate: class { - func selectedChannel(deck: Item) -} - -extension ChannelsViewController: UITableViewDelegate { - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - let section = filteredDecks?[indexPath.section] - if (section?.items != nil) { - delegate?.selectedChannel(deck: (section?.items[indexPath.row])!) - } - } -} - -extension ChannelsViewController: UISearchResultsUpdating { - func updateSearchResults(for searchController: UISearchController) { - if let searchText = searchController.searchBar.text, !searchText.isEmpty { - filteredDecks = channelDecks.map {section in - let s = section.copy() as! Section - let items = section.items.filter{($0.title?.lowercased().contains(searchText.lowercased()))!} - s.items = items - return s - } - } else { - filteredDecks = channelDecks - } - - tableView.reloadData() - } -} - -extension ChannelsViewController: UISearchBarDelegate { - func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { - searchBar.showsCancelButton = false - searchBar.text = "" - searchBar.resignFirstResponder() - tableView.reloadData() - } - - func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) { - searchBar.showsCancelButton = true - - // Center the Cancel Button - if #available(iOS 11.0, *) { - searchBar.cancelButton?.titleEdgeInsets = UIEdgeInsets(top: 12.0, left: 0, bottom: 0, right: 0) - } - } -} - -// get the cancel button of the Search Bar -extension UISearchBar { - var cancelButton : UIButton? { - let topView: UIView = self.subviews[0] as UIView - - if let pvtClass = NSClassFromString("UINavigationButton") { - for v in topView.subviews { - if v.isKind(of: pvtClass) { - return v as? UIButton - } - } - } - - return nil - } -} diff --git a/ios/MattermostShare/Config.swift b/ios/MattermostShare/Config.swift deleted file mode 100644 index 12833d787..000000000 --- a/ios/MattermostShare/Config.swift +++ /dev/null @@ -1,6 +0,0 @@ -let configurationKey = "com.apple.configuration.managed" - -func getManagedConfig() -> [String : Any] { - let appGroupId = Bundle.main.infoDictionary!["AppGroupIdentifier"] as! String - return UserDefaults.init(suiteName: appGroupId)?.dictionary(forKey: configurationKey) ?? [:] -} diff --git a/ios/MattermostShare/GenericPreview.swift b/ios/MattermostShare/GenericPreview.swift deleted file mode 100644 index 1647451f0..000000000 --- a/ios/MattermostShare/GenericPreview.swift +++ /dev/null @@ -1,25 +0,0 @@ -import UIKit - -class GenericPreview: UIView { - - @IBOutlet var contentView: UIView! - @IBOutlet weak var mainLabel: UILabel! - - override init(frame: CGRect) { - super.init(frame: frame) - commonInit() - } - - required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - commonInit() - } - - - private func commonInit() { - Bundle.main.loadNibNamed("GenericPreview", owner: self, options: nil) - addSubview(contentView) - contentView.frame = self.bounds - contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth] - } -} diff --git a/ios/MattermostShare/GenericPreview.xib b/ios/MattermostShare/GenericPreview.xib deleted file mode 100644 index 80b4b05b0..000000000 --- a/ios/MattermostShare/GenericPreview.xib +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/MattermostShare/Images/generic.png b/ios/MattermostShare/Images/generic.png deleted file mode 100644 index c706ae09418406db9be6d10cf958173bb3a19966..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33406 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 diff --git a/ios/MattermostShare/Info.plist b/ios/MattermostShare/Info.plist deleted file mode 100644 index 6a93e0f2c..000000000 --- a/ios/MattermostShare/Info.plist +++ /dev/null @@ -1,56 +0,0 @@ - - - - - AppGroupIdentifier - group.com.mattermost.rnbeta - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Mattermost - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - com.mattermost.rnbeta.MattermostShare - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - XPC! - CFBundleShortVersionString - 2.0.0 - CFBundleVersion - 393 - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - - NSExtension - - NSExtensionAttributes - - NSExtensionActivationRule - - NSExtensionActivationSupportsAttachmentsWithMaxCount - 5 - NSExtensionActivationSupportsFileWithMaxCount - 5 - NSExtensionActivationSupportsImageWithMaxCount - 5 - NSExtensionActivationSupportsMovieWithMaxCount - 5 - NSExtensionActivationSupportsText - - NSExtensionActivationSupportsWebURLWithMaxCount - 1 - - - NSExtensionMainStoryboard - MainInterface - NSExtensionPointIdentifier - com.apple.share-services - - - diff --git a/ios/MattermostShare/Item.swift b/ios/MattermostShare/Item.swift deleted file mode 100644 index ecf99299a..000000000 --- a/ios/MattermostShare/Item.swift +++ /dev/null @@ -1,7 +0,0 @@ -import Foundation - -final class Item { - var id: String? - var title: String? - var selected: Bool = false -} diff --git a/ios/MattermostShare/MattermostShare-Bridging-Header.h b/ios/MattermostShare/MattermostShare-Bridging-Header.h deleted file mode 100644 index feb62f040..000000000 --- a/ios/MattermostShare/MattermostShare-Bridging-Header.h +++ /dev/null @@ -1,6 +0,0 @@ -// -// Use this file to import your target's public headers that you would like to expose to Swift. -// - -#import "MMMConstants.h" -#import "StoreManager.h" diff --git a/ios/MattermostShare/MattermostShare.entitlements b/ios/MattermostShare/MattermostShare.entitlements deleted file mode 100644 index 55fdcdea6..000000000 --- a/ios/MattermostShare/MattermostShare.entitlements +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.security.application-groups - - group.com.mattermost.rnbeta - - - diff --git a/ios/MattermostShare/Section.swift b/ios/MattermostShare/Section.swift deleted file mode 100644 index 9a5eed3b8..000000000 --- a/ios/MattermostShare/Section.swift +++ /dev/null @@ -1,13 +0,0 @@ -import Foundation - -class Section: NSObject, NSCopying { - var title: String? - var items: [Item] = [] - - func copy(with zone: NSZone? = nil) -> Any { - let copy = Section() - copy.title = title - copy.items = items - return copy - } -} diff --git a/ios/MattermostShare/ShareViewController.swift b/ios/MattermostShare/ShareViewController.swift deleted file mode 100644 index a15db28aa..000000000 --- a/ios/MattermostShare/ShareViewController.swift +++ /dev/null @@ -1,559 +0,0 @@ -import UIKit -import Social -import MobileCoreServices -import UploadAttachments -import Gekidou -import LocalAuthentication - -extension Bundle { - var displayName: String? { - return object(forInfoDictionaryKey: "CFBundleDisplayName") as? String - } -} - -class ShareViewController: SLComposeServiceViewController { - - private var dispatchGroup = DispatchGroup() - private var attachments = AttachmentArray() - private var store = StoreManager.shared() as StoreManager - private var entities: [AnyHashable:Any]? = nil - private var sessionToken: String? - private var serverUrl: String? - private var message: String? - private var publicUrl: String? - private var maxPostAlertShown: Bool = false - private var tempContainerUrl: URL? = UploadSessionManager.shared.tempContainerUrl() as URL? - - fileprivate var selectedChannel: Item? - fileprivate var selectedTeam: Item? - private var channelsVC: ChannelsViewController = ChannelsViewController() - private var teamsVC: TeamsViewController = TeamsViewController() - - private var maxMessageSize: Int = 0 - private var canUploadFiles: Bool = true - - required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - - entities = store.getEntities(true) as [AnyHashable:Any]? - - // TODO: If we don't have a single server then we'll need the user to - // select the server from a dropdown. Once the server is selected we - // can fetch its token. - serverUrl = try? Database.default.getOnlyServerUrl() - if (serverUrl != nil), let token = try? Keychain.default.getToken(for: serverUrl!) { - sessionToken = token - } - - maxMessageSize = Int(store.getMaxPostSize()) - canUploadFiles = store.getCanUploadFiles() - } - - // MARK: - Lifecycle methods - override func viewDidLoad() { - super.viewDidLoad() - - title = Bundle.main.displayName - placeholder = "Write a message..." - - let config = getManagedConfig() - if let inAppPinCode = config["inAppPinCode"] as? String, inAppPinCode == "true" { - self.auth(vendor: config["vendor"] as? String) - } else { - self.loadData() - } - } - - func auth(vendor: String?) { - let context = LAContext() - - var error: NSError? - if !context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) { - if let error = error, error.code == kLAErrorPasscodeNotSet { - var message = "This device must be secured with a passcode to use Mattermost.\n\nGo to Settings > Touch ID & Passcode." - if #available(iOS 11.0, *) { - if (context.biometryType == LABiometryType.faceID) { - message = "This device must be secured with a passcode to use Mattermost.\n\nGo to Settings > Face ID & Passcode." - } - } - - self.showErrorMessage( - title: "", - message: message, - VC: self - ) - } else { - self.showErrorMessage(title: "", message: "Unable to authenticate device owner for Mattermost", VC: self) - } - - return - } - - let reason = "Secured by " + (vendor ?? "Mattermost") - context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason) { success, error in - if success { - self.loadData() - } else { - self.showErrorMessage(title: "", message: "Unable to authenticate device owner for Mattermost", VC: self) - } - } - } - - func loadData() { - if sessionToken == nil || serverUrl == nil { - showErrorMessage(title: "", message: "Authentication required: Please first login using the app.", VC: self) - } else if store.getCurrentTeamId() == "" || store.getMyTeams().count == 0 { - showErrorMessage(title: "", message: "You must belong to a team before you can share files.", VC: self) - } else if !canUploadFiles { - showErrorMessage(title: "", message: "File uploads from mobile are disabled. Please contact your System Admin for more details.", VC: self) - } else { - extractDataFromContext() - } - } - - override func isContentValid() -> Bool { - if let currentMessage = contentText { - let contentCount = currentMessage.count - if #available(iOS 13, *) {} else { - let remaining = (maxMessageSize - contentCount) as NSNumber - // this is causing the extension to run OOM on iOS 13 - charactersRemaining = remaining - } - - //Check content text size is not above max - if (contentCount > maxMessageSize) { - if !maxPostAlertShown { - maxPostAlertShown = true - showErrorMessageAndStayOpen(title: "", message: "Content text shared in Mattermost must be less than \(maxMessageSize+1) characters.", VC: self) - } - return false - } else if (attachments.count > 0) { // Do validation of contentText and/or NSExtensionContext attachments here - let maxImagePixels = store.getMaxImagePixels() - if attachments.hasImageLargerThan(pixels: maxImagePixels) { - let readableMaxImagePixels = formatImagePixels(pixels: maxImagePixels) - showErrorMessage(title: "", message: "Image attachments shared in Mattermost must be less than \(readableMaxImagePixels).", VC: self) - } - let maxFileSize = store.getMaxFileSize() - if attachments.hasAttachementLargerThan(fileSize: maxFileSize) { - let readableMaxFileSize = formatFileSize(fileSize: maxFileSize) - showErrorMessage(title: "", message: "File attachments shared in Mattermost must be less than \(readableMaxFileSize).", VC: self) - } - } - } - - return serverUrl != nil && - sessionToken != nil && - attachmentsCount() == attachments.count && - selectedTeam != nil && - selectedChannel != nil - } - - override func didSelectCancel() { - UploadSessionManager.shared.clearTempDirectory() - super.didSelectCancel() - } - - override func didSelectPost() { - // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments. - if publicUrl != nil { - self.message = "\(contentText!)\n\n\(publicUrl!)" - } else { - self.message = contentText - } - - UploadManager.shared.uploadFiles(baseUrl: serverUrl!, token: sessionToken!, channelId: selectedChannel!.id!, message: message, attachments: attachments, callback: { - // Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context. - self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) - }) - } - - override func loadPreviewView() -> UIView! { - if attachments.findBy(type: kUTTypeFileURL as String) { - let genericPreview = GenericPreview() - genericPreview.contentMode = .scaleAspectFit - genericPreview.clipsToBounds = true - genericPreview.isUserInteractionEnabled = false - genericPreview.addConstraints([ - NSLayoutConstraint(item: genericPreview, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1.0, constant: 70), - NSLayoutConstraint(item: genericPreview, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1.0, constant: 70) - ]) - - if attachments.count > 1 { - genericPreview.mainLabel.text = "\(attachments.count) Items" - } - - return genericPreview - } - return super.loadPreviewView(); - } - - override func configurationItems() -> [Any]! { - var items: [SLComposeSheetConfigurationItem] = [] - - // To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here. - let teamDecks = getTeamItems() - if let teams = SLComposeSheetConfigurationItem() { - teams.title = "Team" - teams.value = selectedTeam?.title - teams.tapHandler = { - self.teamsVC.teamDecks = teamDecks - self.teamsVC.delegate = self - self.pushConfigurationViewController(self.teamsVC) - } - items.append(teams) - } - - let channelDecks = getChannelItems(forTeamId: selectedTeam?.id) - if let channels = SLComposeSheetConfigurationItem() { - channels.title = "Channels" - channels.value = selectedChannel?.title - channels.valuePending = channelDecks == nil - channels.tapHandler = { - self.channelsVC.channelDecks = channelDecks! - self.channelsVC.navbarTitle = self.selectedTeam?.title - self.channelsVC.delegate = self - self.pushConfigurationViewController(self.channelsVC) - } - - items.append(channels) - } - - validateContent() - return items - } - - // MARK: - Extension Builder - - func attachmentsCount() -> Int { - var count = 0 - for item in extensionContext?.inputItems as! [NSExtensionItem] { - guard let attachments = item.attachments else {return 0} - for itemProvider in attachments { - if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeMovie as String) || - itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) || - itemProvider.hasItemConformingToTypeIdentifier(kUTTypeFileURL as String) { - count = count + 1 - } - } - } - - return count - } - - func buildChannelSection(channels: NSArray, currentChannelId: String, key: String, title:String) -> Section { - let section = Section() - section.title = title - for channel in channels as! [NSDictionary] { - let item = Item() - let id = channel.object(forKey: "id") as? String - item.id = id - item.title = channel.object(forKey: "display_name") as? String - if id == currentChannelId { - item.selected = true - selectedChannel = item - if #available(iOS 13, *) {} else { - // this is causing the extension to run OOM on iOS 13 - self.placeholder = "Write to \(item.title!)" - } - } - section.items.append(item) - } - return section - } - - func getImagePixels(imageUrl: URL) -> UInt64 { - guard let imageData = try? Data(contentsOf: imageUrl) else { - return 0 - } - - guard let image = UIImage.init(data: imageData) else { - return 0 - } - - return getImagePixels(image: image) - } - - func getImagePixels(image: UIImage) -> UInt64 { - guard let cgImage = image.cgImage else { - return 0 - } - - return UInt64(cgImage.width * cgImage.height) - } - - func extractDataFromContext() { - for item in extensionContext?.inputItems as! [NSExtensionItem] { - guard let attachments = item.attachments else {continue} - for itemProvider in attachments { - if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeMovie as String) { - dispatchGroup.enter() - itemProvider.loadItem(forTypeIdentifier: kUTTypeMovie as String, options: nil, completionHandler: ({item, error in - if error == nil { - if let url = item as? URL { - let attachment = self.saveAttachment(url: url) - if (attachment != nil) { - attachment?.type = kUTTypeMovie as String - self.attachments.append(attachment!) - } - } - } - self.dispatchGroup.leave() - })) - } else if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) { - dispatchGroup.enter() - itemProvider.loadItem(forTypeIdentifier: kUTTypeImage as String, options: nil, completionHandler: ({item, error in - if error == nil { - if let url = item as? URL { - let attachment = self.saveAttachment(url: url) - if (attachment != nil) { - attachment?.type = kUTTypeImage as String - attachment?.imagePixels = self.getImagePixels(imageUrl: url) - self.attachments.append(attachment!) - } - } else if let image = item as? UIImage { - if let data = image.pngData() { - let tempImageUrl = self.tempContainerUrl? - .appendingPathComponent(UUID().uuidString) - .appendingPathExtension(".png") - if (try? data.write(to: tempImageUrl!)) != nil { - let attachment = self.saveAttachment(url: tempImageUrl!) - if (attachment != nil) { - attachment?.type = kUTTypeImage as String - attachment?.imagePixels = self.getImagePixels(image: image) - self.attachments.append(attachment!) - } - } - } - } - } - self.dispatchGroup.leave() - })) - } else if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeFileURL as String) { - dispatchGroup.enter() - itemProvider.loadItem(forTypeIdentifier: kUTTypeFileURL as String, options: nil, completionHandler: ({item, error in - if error == nil { - if let url = item as? URL { - let attachment = self.saveAttachment(url: url) - if (attachment != nil) { - attachment?.type = kUTTypeFileURL as String - self.attachments.append(attachment!) - } - } - } - self.dispatchGroup.leave() - })) - } else if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeURL as String) { - itemProvider.loadItem(forTypeIdentifier: kUTTypeURL as String, options: nil, completionHandler: ({item, error in - if let url = item as? URL { - self.publicUrl = url.absoluteString - } - })) - } - } - } - dispatchGroup.notify(queue: DispatchQueue.main) { - self.validateContent() - } - } - - func getChannelsFromServerAndReload(forTeamId: String) { - var currentChannel = store.getCurrentChannel() as NSDictionary? - if currentChannel?.object(forKey: "team_id") as! String != forTeamId { - currentChannel = store.getDefaultChannel(forTeamId) as NSDictionary? - } - - // If currentChannel is nil it means we don't have the channels for this team - if (currentChannel == nil) { - let urlString = "\(serverUrl!)/api/v4/users/me/teams/\(forTeamId)/channels" - let url = URL(string: urlString) - var request = URLRequest(url: url!) - let auth = "Bearer \(sessionToken!)" as String - request.setValue(auth, forHTTPHeaderField: "Authorization") - - let task = URLSession.shared.dataTask(with: request) { (data, response, error) in - guard let dataResponse = data, - error == nil else { - print(error?.localizedDescription ?? "Response Error") - return - - } - - do{ - //here dataResponse received from a network request - let jsonArray = try JSONSerialization.jsonObject(with: dataResponse, options: []) as! NSArray - let channels = jsonArray.filter {element in - let channel = element as! NSDictionary - let type = channel.object(forKey: "type") as! String - return type == "O" || type == "P" - } - let ent = self.store.getEntities(false)! as NSDictionary - let mutableEntities = ent.mutableCopy() as! NSMutableDictionary - let entitiesChannels = NSDictionary(dictionary: mutableEntities.object(forKey: "channels") as! NSMutableDictionary) - .object(forKey: "channels") as! NSMutableDictionary - - for item in channels { - let channel = item as! NSDictionary - entitiesChannels.setValue(channel, forKey: channel.object(forKey: "id") as! String) - } - - if let entitiesData: NSData = try? JSONSerialization.data(withJSONObject: ent, options: JSONSerialization.WritingOptions.prettyPrinted) as NSData { - let jsonString = String(data: entitiesData as Data, encoding: String.Encoding.utf8)! as String - self.store.updateEntities(jsonString) - self.store.getEntities(true) - self.reloadConfigurationItems() - self.view.setNeedsDisplay() - } - } catch let parsingError { - print("Error", parsingError) - } - } - task.resume() - } - } - - func getChannelItems(forTeamId: String?) -> [Section]? { - var channelDecks = [Section]() - var currentChannel = store.getCurrentChannel() as NSDictionary? - if currentChannel?.object(forKey: "team_id") as? String != forTeamId { - currentChannel = store.getDefaultChannel(forTeamId) as NSDictionary? - } - - if currentChannel == nil { - return nil - } - - let channelsInTeamBySections = store.getChannelsBySections(forTeamId, excludeArchived: true) as NSDictionary - channelDecks.append(buildChannelSection( - channels: channelsInTeamBySections.object(forKey: "public") as! NSArray, - currentChannelId: selectedChannel?.id ?? currentChannel?.object(forKey: "id") as! String, - key: "public", - title: "Public Channels" - )) - - channelDecks.append(buildChannelSection( - channels: channelsInTeamBySections.object(forKey: "private") as! NSArray, - currentChannelId: selectedChannel?.id ?? currentChannel?.object(forKey: "id") as! String, - key: "private", - title: "Private Channels" - )) - - channelDecks.append(buildChannelSection( - channels: channelsInTeamBySections.object(forKey: "direct") as! NSArray, - currentChannelId: selectedChannel?.id ?? currentChannel?.object(forKey: "id") as! String, - key: "direct", - title: "Direct Channels" - )) - - return channelDecks - } - - func getTeamItems() -> [Item] { - var teamDecks = [Item]() - let currentTeamId = store.getCurrentTeamId() - let teams = store.getMyTeams() as NSArray? - - for case let team as NSDictionary in teams! { - let item = Item() - item.title = team.object(forKey: "display_name") as! String? - item.id = team.object(forKey: "id") as! String? - item.selected = false - if (item.id == (selectedTeam?.id ?? currentTeamId)) { - item.selected = true - selectedTeam = item - } - teamDecks.append(item) - } - - return teamDecks - } - - func saveAttachment(url: URL) -> AttachmentItem? { - let fileMgr = FileManager.default - let fileName = url.lastPathComponent - let tempFileUrl = tempContainerUrl?.appendingPathComponent(fileName) - - do { - if (tempFileUrl != url) { - try? FileManager.default.removeItem(at: tempFileUrl!) - try fileMgr.copyItem(at: url, to: tempFileUrl!) - } - - let attr = try fileMgr.attributesOfItem(atPath: (tempFileUrl?.path)!) as NSDictionary - let attachment = AttachmentItem() - attachment.fileName = fileName - attachment.fileUrl = tempFileUrl - attachment.fileSize = attr.fileSize() - - return attachment - } catch { - return nil - } - } - - // MARK: - Utiilities - - func showErrorMessage(title: String, message: String, VC: UIViewController) { - let alert: UIAlertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert) - let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.default) { - UIAlertAction in - self.cancel() - } - alert.addAction(okAction) - VC.present(alert, animated: true, completion: nil) - } - - func showErrorMessageAndStayOpen(title: String, message: String, VC: UIViewController) { - let alert: UIAlertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert) - let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.default) - alert.addAction(okAction) - VC.present(alert, animated: true, completion: nil) - } - - func formatImagePixels(pixels: UInt64) -> String { - let suffixes = ["pixels", "KP", "MP", "GP", "TP", "PP", "EP", "ZP", "YP"] - let k: Double = 1000 - return formatSize(size: Double(pixels), k: k, suffixes: suffixes) - } - - func formatFileSize(fileSize: UInt64) -> String { - let suffixes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] - let k: Double = 1024 - return formatSize(size: Double(fileSize), k: k, suffixes: suffixes) - } - - func formatSize(size: Double, k: Double, suffixes: Array) -> String { - guard size > 0 else { - return "0 \(suffixes[0])" - } - - // Adapted from http://stackoverflow.com/a/18650828 - let i = floor(log(size) / log(k)) - - // Format number with thousands separator and everything below 1 giga with no decimal places. - let numberFormatter = NumberFormatter() - numberFormatter.maximumFractionDigits = i < 3 ? 0 : 1 - numberFormatter.numberStyle = .decimal - - let numberString = numberFormatter.string(from: NSNumber(value: size / pow(k, i))) ?? "Unknown" - let suffix = suffixes[Int(i)] - return "\(numberString) \(suffix)" - } -} - -extension ShareViewController: TeamsViewControllerDelegate { - func selectedTeam(deck: Item) { - selectedTeam = deck - selectedChannel = nil - self.getChannelsFromServerAndReload(forTeamId: deck.id!) - reloadConfigurationItems() - popConfigurationViewController() - } -} - -extension ShareViewController: ChannelsViewControllerDelegate { - func selectedChannel(deck: Item) { - selectedChannel = deck - reloadConfigurationItems() - popConfigurationViewController() - } -} diff --git a/ios/MattermostShare/TeamsViewController.swift b/ios/MattermostShare/TeamsViewController.swift deleted file mode 100644 index 7f95846ec..000000000 --- a/ios/MattermostShare/TeamsViewController.swift +++ /dev/null @@ -1,57 +0,0 @@ -import UIKit - -class TeamsViewController: UIViewController { - - lazy var tableView: UITableView = { - let tableView = UITableView(frame: self.view.frame) - tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight] - tableView.dataSource = self - tableView.delegate = self - tableView.backgroundColor = .clear - tableView.register(UITableViewCell.self, forCellReuseIdentifier: Identifiers.TeamCell) - return tableView - }() - var teamDecks = [Item]() - weak var delegate: TeamsViewControllerDelegate? - - override func viewDidLoad() { - super.viewDidLoad() - - title = "Team" - view.addSubview(tableView) - } - -} - -private extension TeamsViewController { - struct Identifiers { - static let TeamCell = "teamCell" - } -} - -extension TeamsViewController: UITableViewDataSource { - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return teamDecks.count - } - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: Identifiers.TeamCell, for: indexPath) - cell.textLabel?.text = teamDecks[indexPath.row].title - if teamDecks[indexPath.row].selected { - cell.accessoryType = .checkmark - } else { - cell.accessoryType = .none - } - cell.backgroundColor = .clear - return cell - } -} - -protocol TeamsViewControllerDelegate: class { - func selectedTeam(deck: Item) -} - -extension TeamsViewController: UITableViewDelegate { - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - delegate?.selectedTeam(deck: teamDecks[indexPath.row]) - } -} diff --git a/share_extension/index.tsx b/share_extension/index.tsx deleted file mode 100644 index e884f7048..000000000 --- a/share_extension/index.tsx +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import React from 'react'; -import { - SafeAreaView, - StyleSheet, - ScrollView, - View, - Text, - StatusBar, -} from 'react-native'; -import { - Header, - LearnMoreLinks, - Colors, - DebugInstructions, - ReloadInstructions, -} from 'react-native/Libraries/NewAppScreen'; - -declare const global: {HermesInternal: null | {}}; - -const Channel = () => { - return ( - <> - - - -
- {global.HermesInternal == null ? null : ( - - {'Engine: Hermes'} - - )} - - - {'Step One'} - - {'Edit '}{'/share_extension/index.tsx'}{' to change this'} - {'screen and then come back to see your edits.'} - - - - {'See Your Changes'} - - - - - - {'Debug'} - - - - - - {'Learn More'} - - {'Read the docs to discover what to do next:'} - - - - - - - - ); -}; - -const styles = StyleSheet.create({ - scrollView: { - backgroundColor: Colors.lighter, - }, - engine: { - position: 'absolute', - right: 0, - }, - body: { - backgroundColor: Colors.white, - }, - sectionContainer: { - marginTop: 32, - paddingHorizontal: 24, - }, - sectionTitle: { - fontSize: 24, - fontFamily: 'OpenSans-SemiBold', - color: Colors.black, - }, - sectionDescription: { - marginTop: 8, - fontSize: 18, - fontWeight: '400', - color: Colors.dark, - }, - highlight: { - fontFamily: 'OpenSans-Bold', - }, - footer: { - color: Colors.dark, - fontSize: 12, - fontWeight: '600', - padding: 4, - paddingRight: 12, - textAlign: 'right', - }, -}); - -export default Channel;