Remove Share Extensions (#6238)
This commit is contained in:
parent
40e3ae525d
commit
0c1e9a4812
22 changed files with 1 additions and 1818 deletions
|
|
@ -71,23 +71,5 @@
|
|||
android:resizeableActivity="true"
|
||||
android:exported="true"
|
||||
/>
|
||||
<activity
|
||||
android:name="com.mattermost.share.ShareActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/AppTheme"
|
||||
android:taskAffinity="com.mattermost.share"
|
||||
android:launchMode="singleInstance"
|
||||
android:exported="true"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<!-- for sharing-->
|
||||
<data android:mimeType="*/*" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -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<String, ReactModuleInfo> 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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String, Object> getConstants() {
|
||||
HashMap<String, Object> 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<Uri> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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],
|
||||
|
|
|
|||
8
index.ts
8
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
|
||||
|
|
|
|||
|
|
@ -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 = "<group>"; };
|
||||
7F0F4B0924BA173900E14C60 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = SplashScreenResource/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
7F151D3D221B062700FAD8F3 /* RuntimeUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RuntimeUtils.swift; path = Mattermost/RuntimeUtils.swift; sourceTree = "<group>"; };
|
||||
7F151D42221B07F700FAD8F3 /* MattermostShare-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MattermostShare-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
7F1EB88427FDE361002E7EEC /* GekidouWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GekidouWrapper.swift; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
7F240A1E220D3A2300637665 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
|
||||
7F240A20220D3A2300637665 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
7F240A27220D3A7E00637665 /* MattermostShare.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MattermostShare.entitlements; sourceTree = "<group>"; };
|
||||
7F240ADA220E089300637665 /* Item.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Item.swift; sourceTree = "<group>"; };
|
||||
7F240ADC220E094A00637665 /* TeamsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeamsViewController.swift; sourceTree = "<group>"; };
|
||||
7F25B626270F666D00F32373 /* Metropolis-Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Metropolis-Light.ttf"; path = "../assets/fonts/Metropolis-Light.ttf"; sourceTree = "<group>"; };
|
||||
7F25B628270F666D00F32373 /* Metropolis-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "Metropolis-Regular.ttf"; path = "../assets/fonts/Metropolis-Regular.ttf"; sourceTree = "<group>"; };
|
||||
7F292A701E8AB73400A450A3 /* SplashScreenResource */ = {isa = PBXFileReference; lastKnownFileType = folder; path = SplashScreenResource; sourceTree = "<group>"; };
|
||||
|
|
@ -177,11 +140,6 @@
|
|||
7F581D36221ED5C60099E66B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
7F581F77221EEA5A0099E66B /* NotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NotificationService.entitlements; sourceTree = "<group>"; };
|
||||
7F63D2C21E6DD98A001FAE12 /* Mattermost.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Mattermost.entitlements; path = Mattermost/Mattermost.entitlements; sourceTree = "<group>"; };
|
||||
7F72F2ED2211220500F98FFF /* GenericPreview.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GenericPreview.xib; sourceTree = "<group>"; };
|
||||
7F72F2EF221123E200F98FFF /* GenericPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericPreview.swift; sourceTree = "<group>"; };
|
||||
7F72F2F222112EC700F98FFF /* generic.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = generic.png; sourceTree = "<group>"; };
|
||||
7FABDFC12211A39000D0F595 /* Section.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Section.swift; sourceTree = "<group>"; };
|
||||
7FABE0092212650600D0F595 /* ChannelsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsViewController.swift; sourceTree = "<group>"; };
|
||||
7FABE04022137F2900D0F595 /* UploadAttachments.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = UploadAttachments.xcodeproj; path = UploadAttachments/UploadAttachments.xcodeproj; sourceTree = "<group>"; };
|
||||
7FCEFB9126B7934F006DC1DE /* SDWebImageDownloaderOperation+Swizzle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SDWebImageDownloaderOperation+Swizzle.h"; path = "Mattermost/SDWebImageDownloaderOperation+Swizzle.h"; sourceTree = "<group>"; };
|
||||
7FCEFB9226B7934F006DC1DE /* SDWebImageDownloaderOperation+Swizzle.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "SDWebImageDownloaderOperation+Swizzle.m"; path = "Mattermost/SDWebImageDownloaderOperation+Swizzle.m"; sourceTree = "<group>"; };
|
||||
|
|
@ -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 = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
|
|
@ -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 = "<group>";
|
||||
};
|
||||
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 = "<group>";
|
||||
};
|
||||
7F581D33221ED5C60099E66B /* NotificationService */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -381,14 +309,6 @@
|
|||
path = NotificationService;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7F72F2E4221113DF00F98FFF /* Images */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7F72F2F222112EC700F98FFF /* generic.png */,
|
||||
);
|
||||
path = Images;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
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 = "<group>";
|
||||
};
|
||||
/* 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;
|
||||
|
|
|
|||
|
|
@ -1,94 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1010"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7F240A18220D3A2300637665"
|
||||
BuildableName = "MattermostShare.appex"
|
||||
BlueprintName = "MattermostShare"
|
||||
ReferencedContainer = "container:Mattermost.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7F240A18220D3A2300637665"
|
||||
BuildableName = "MattermostShare.appex"
|
||||
BlueprintName = "MattermostShare"
|
||||
ReferencedContainer = "container:Mattermost.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
launchStyle = "0"
|
||||
askForAppToLaunch = "Yes"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<RemoteRunnable
|
||||
runnableDebuggingMode = "1"
|
||||
BundleIdentifier = "com.apple.mobileslideshow"
|
||||
RemotePath = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/Applications/MobileSlideShow.app">
|
||||
</RemoteRunnable>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7F240A18220D3A2300637665"
|
||||
BuildableName = "MattermostShare.appex"
|
||||
BlueprintName = "MattermostShare"
|
||||
ReferencedContainer = "container:Mattermost.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7F240A18220D3A2300637665"
|
||||
BuildableName = "MattermostShare.appex"
|
||||
BlueprintName = "MattermostShare"
|
||||
ReferencedContainer = "container:Mattermost.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="j1y-V4-xli">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Share View Controller-->
|
||||
<scene sceneID="ceB-am-kn3">
|
||||
<objects>
|
||||
<viewController id="j1y-V4-xli" customClass="ShareViewController" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" opaque="NO" contentMode="scaleToFill" id="wbc-yd-nQP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<viewLayoutGuide key="safeArea" id="1Xd-am-t49"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="CEy-Cv-SGf" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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) ?? [:]
|
||||
}
|
||||
|
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment version="4144" identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="GenericPreview" customModule="MattermostShare">
|
||||
<connections>
|
||||
<outlet property="contentView" destination="iN0-l3-epB" id="zsU-gT-pKk"/>
|
||||
<outlet property="mainLabel" destination="VCO-Fr-5i7" id="kIN-uo-sj1"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view userInteractionEnabled="NO" contentMode="scaleAspectFit" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="70" height="80"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="generic.png" translatesAutoresizingMaskIntoConstraints="NO" id="TSh-2S-BCu">
|
||||
<rect key="frame" x="0.0" y="0.0" width="70" height="60"/>
|
||||
<accessibility key="accessibilityConfiguration">
|
||||
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
|
||||
</accessibility>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VCO-Fr-5i7">
|
||||
<rect key="frame" x="0.0" y="80" width="70" height="0.0"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<accessibility key="accessibilityConfiguration">
|
||||
<accessibilityTraits key="traits" notEnabled="YES"/>
|
||||
</accessibility>
|
||||
<constraints>
|
||||
<constraint firstItem="TSh-2S-BCu" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="5B6-O1-NR2"/>
|
||||
<constraint firstItem="VCO-Fr-5i7" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="aFc-0b-hsh"/>
|
||||
<constraint firstItem="TSh-2S-BCu" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="cce-KU-XTm"/>
|
||||
<constraint firstAttribute="bottom" secondItem="TSh-2S-BCu" secondAttribute="bottom" constant="20" id="lHP-mg-Ogd"/>
|
||||
<constraint firstAttribute="trailing" secondItem="TSh-2S-BCu" secondAttribute="trailing" id="q2A-Bm-uko"/>
|
||||
<constraint firstAttribute="bottom" secondItem="VCO-Fr-5i7" secondAttribute="bottom" id="rpf-k7-OZN"/>
|
||||
<constraint firstItem="VCO-Fr-5i7" firstAttribute="trailing" secondItem="iN0-l3-epB" secondAttribute="trailingMargin" constant="16" id="thO-W2-G2h"/>
|
||||
</constraints>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="-387.19999999999999" y="-305.84707646176912"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="generic.png" width="512" height="512"/>
|
||||
</resources>
|
||||
</document>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB |
|
|
@ -1,56 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AppGroupIdentifier</key>
|
||||
<string>group.com.mattermost.rnbeta</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Mattermost</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.mattermost.rnbeta.MattermostShare</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>393</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationSupportsAttachmentsWithMaxCount</key>
|
||||
<integer>5</integer>
|
||||
<key>NSExtensionActivationSupportsFileWithMaxCount</key>
|
||||
<integer>5</integer>
|
||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||
<integer>5</integer>
|
||||
<key>NSExtensionActivationSupportsMovieWithMaxCount</key>
|
||||
<integer>5</integer>
|
||||
<key>NSExtensionActivationSupportsText</key>
|
||||
<true/>
|
||||
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
<string>MainInterface</string>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.share-services</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
import Foundation
|
||||
|
||||
final class Item {
|
||||
var id: String?
|
||||
var title: String?
|
||||
var selected: Bool = false
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.com.mattermost.rnbeta</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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<AttachmentItem>()
|
||||
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>) -> 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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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])
|
||||
}
|
||||
}
|
||||
|
|
@ -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 (
|
||||
<>
|
||||
<StatusBar barStyle='dark-content'/>
|
||||
<SafeAreaView>
|
||||
<ScrollView
|
||||
contentInsetAdjustmentBehavior='automatic'
|
||||
style={styles.scrollView}
|
||||
>
|
||||
<Header/>
|
||||
{global.HermesInternal == null ? null : (
|
||||
<View style={styles.engine}>
|
||||
<Text style={styles.footer}>{'Engine: Hermes'}</Text>
|
||||
</View>
|
||||
)}
|
||||
<View style={styles.body}>
|
||||
<View style={styles.sectionContainer}>
|
||||
<Text style={styles.sectionTitle}>{'Step One'}</Text>
|
||||
<Text style={styles.sectionDescription}>
|
||||
{'Edit '}<Text style={styles.highlight}>{'/share_extension/index.tsx'}</Text>{' to change this'}
|
||||
{'screen and then come back to see your edits.'}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.sectionContainer}>
|
||||
<Text style={styles.sectionTitle}>{'See Your Changes'}</Text>
|
||||
<Text style={styles.sectionDescription}>
|
||||
<ReloadInstructions/>
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.sectionContainer}>
|
||||
<Text style={styles.sectionTitle}>{'Debug'}</Text>
|
||||
<Text style={styles.sectionDescription}>
|
||||
<DebugInstructions/>
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.sectionContainer}>
|
||||
<Text style={styles.sectionTitle}>{'Learn More'}</Text>
|
||||
<Text style={styles.sectionDescription}>
|
||||
{'Read the docs to discover what to do next:'}
|
||||
</Text>
|
||||
</View>
|
||||
<LearnMoreLinks/>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
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;
|
||||
Loading…
Reference in a new issue