From 5ef83639e9cbefc8eee9ae961a90f8a7c20ebc06 Mon Sep 17 00:00:00 2001 From: enahum Date: Mon, 5 Feb 2018 21:14:09 -0300 Subject: [PATCH] Remove iOS share extension (#1415) --- app/mattermost.js | 2 - app/mattermost_bucket/index.js | 58 -- app/store/index.js | 20 +- app/store/middleware.js | 19 - ios/Mattermost.xcodeproj/project.pbxproj | 300 ------- ios/MattermostBucket.h | 7 - ios/MattermostBucket.m | 122 --- .../Base.lproj/MainInterface.storyboard | 24 - ios/MattermostShare/Info.plist | 65 -- .../MattermostShare.entitlements | 10 - ios/MattermostShare/PerformRequests.h | 31 - ios/MattermostShare/PerformRequests.m | 162 ---- ios/MattermostShare/ShareViewController.h | 6 - ios/MattermostShare/ShareViewController.m | 273 ------- share.ios.js | 8 - share_extension/ios/extension_channels.js | 324 -------- share_extension/ios/extension_nav_bar.js | 149 ---- share_extension/ios/extension_post.js | 758 ------------------ share_extension/ios/extension_team_item.js | 125 --- share_extension/ios/extension_teams.js | 218 ----- share_extension/ios/index.js | 161 ---- 21 files changed, 3 insertions(+), 2839 deletions(-) delete mode 100644 app/mattermost_bucket/index.js delete mode 100644 ios/MattermostBucket.h delete mode 100644 ios/MattermostBucket.m delete mode 100644 ios/MattermostShare/Base.lproj/MainInterface.storyboard delete mode 100644 ios/MattermostShare/Info.plist delete mode 100644 ios/MattermostShare/MattermostShare.entitlements delete mode 100644 ios/MattermostShare/PerformRequests.h delete mode 100644 ios/MattermostShare/PerformRequests.m delete mode 100644 ios/MattermostShare/ShareViewController.h delete mode 100644 ios/MattermostShare/ShareViewController.m delete mode 100644 share.ios.js delete mode 100644 share_extension/ios/extension_channels.js delete mode 100644 share_extension/ios/extension_nav_bar.js delete mode 100644 share_extension/ios/extension_post.js delete mode 100644 share_extension/ios/extension_team_item.js delete mode 100644 share_extension/ios/extension_teams.js delete mode 100644 share_extension/ios/index.js diff --git a/app/mattermost.js b/app/mattermost.js index 50a9488b5..901e636c3 100644 --- a/app/mattermost.js +++ b/app/mattermost.js @@ -49,7 +49,6 @@ import initialState from 'app/initial_state'; import PushNotifications from 'app/push_notifications'; import {registerScreens} from 'app/screens'; import configureStore from 'app/store'; -import mattermostBucket from 'app/mattermost_bucket'; import mattermostManaged from 'app/mattermost_managed'; import {deleteFileCache} from 'app/utils/file'; import {init as initAnalytics} from 'app/utils/segment'; @@ -211,7 +210,6 @@ export default class Mattermost { const intl = this.getIntl(); if (isSecured) { try { - mattermostBucket.setPreference('emm', vendor, Config.AppGroupId); await mattermostManaged.authenticate({ reason: intl.formatMessage({ id: 'mobile.managed.secured_by', diff --git a/app/mattermost_bucket/index.js b/app/mattermost_bucket/index.js deleted file mode 100644 index 70da1d49c..000000000 --- a/app/mattermost_bucket/index.js +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import {NativeModules, Platform} from 'react-native'; - -// TODO: Remove platform specific once android is implemented -const MattermostBucket = Platform.OS === 'ios' ? NativeModules.MattermostBucket : null; - -export default { - setPreference: (key, value, groupName) => { - if (MattermostBucket) { - MattermostBucket.setPreference(key, value, groupName); - } - }, - getPreference: async (key, groupName) => { - if (MattermostBucket) { - const value = await MattermostBucket.getPreference(key, groupName); - if (value) { - try { - return JSON.parse(value); - } catch (e) { - return value; - } - } - } - - return null; - }, - removePreference: (key, groupName) => { - if (MattermostBucket) { - MattermostBucket.removePreference(key, groupName); - } - }, - writeToFile: (fileName, content, groupName) => { - if (MattermostBucket) { - MattermostBucket.writeToFile(fileName, content, groupName); - } - }, - readFromFile: async (fileName, groupName) => { - if (MattermostBucket) { - const value = await MattermostBucket.readFromFile(fileName, groupName); - if (value) { - try { - return JSON.parse(value); - } catch (e) { - return value; - } - } - } - - return null; - }, - removeFile: (fileName, groupName) => { - if (MattermostBucket) { - MattermostBucket.removeFile(fileName, groupName); - } - } -}; diff --git a/app/store/index.js b/app/store/index.js index e05c19427..b867d34b4 100644 --- a/app/store/index.js +++ b/app/store/index.js @@ -2,7 +2,7 @@ // See License.txt for license information. import {batchActions} from 'redux-batched-actions'; -import {AsyncStorage, Platform} from 'react-native'; +import {AsyncStorage} from 'react-native'; import {createBlacklistFilter} from 'redux-persist-transform-filter'; import {createTransform, persistStore} from 'redux-persist'; @@ -13,15 +13,11 @@ import EventEmitter from 'mattermost-redux/utils/event_emitter'; import {NavigationTypes, ViewTypes} from 'app/constants'; import appReducer from 'app/reducers'; -import {throttle} from 'app/utils/general'; import networkConnectionListener from 'app/utils/network'; import {createSentryMiddleware} from 'app/utils/sentry/middleware'; import {promiseTimeout} from 'app/utils/promise_timeout'; -import mattermostBucket from 'app/mattermost_bucket'; -import Config from 'assets/config'; - -import {messageRetention, shareExtensionData} from './middleware'; +import {messageRetention} from './middleware'; import {transformSet} from './utils'; function getAppReducer() { @@ -134,16 +130,6 @@ export default function configureAppStore(initialState) { let purging = false; - // for iOS write the entities to a shared file - if (Platform.OS === 'ios') { - store.subscribe(throttle(() => { - const state = store.getState(); - if (state.entities) { - mattermostBucket.writeToFile('entities', JSON.stringify(state.entities), Config.AppGroupId); - } - }, 1000)); - } - // check to see if the logout request was successful store.subscribe(async () => { const state = store.getState(); @@ -225,7 +211,7 @@ export default function configureAppStore(initialState) { } }; - const additionalMiddleware = [createSentryMiddleware(), messageRetention, shareExtensionData]; + const additionalMiddleware = [createSentryMiddleware(), messageRetention]; return configureStore(initialState, appReducer, offlineOptions, getAppReducer, { additionalMiddleware }); diff --git a/app/store/middleware.js b/app/store/middleware.js index 3969a6db0..5b135821c 100644 --- a/app/store/middleware.js +++ b/app/store/middleware.js @@ -3,12 +3,8 @@ import DeviceInfo from 'react-native-device-info'; -import {UserTypes} from 'mattermost-redux/action_types'; - import {ViewTypes} from 'app/constants'; import initialState from 'app/initial_state'; -import mattermostBucket from 'app/mattermost_bucket'; -import Config from 'assets/config'; import { captureException, @@ -309,18 +305,3 @@ function cleanupState(action, keepCurrent = false) { error: action.error }; } - -export function shareExtensionData() { - return (next) => (action) => { - // allow other middleware to do their things - const nextAction = next(action); - - switch (action.type) { - case UserTypes.LOGOUT_SUCCESS: - mattermostBucket.removePreference('emm', Config.AppGroupId); - mattermostBucket.removeFile('entities', Config.AppGroupId); - break; - } - return nextAction; - }; -} diff --git a/ios/Mattermost.xcodeproj/project.pbxproj b/ios/Mattermost.xcodeproj/project.pbxproj index d7733d519..31ce81ae8 100644 --- a/ios/Mattermost.xcodeproj/project.pbxproj +++ b/ios/Mattermost.xcodeproj/project.pbxproj @@ -44,10 +44,6 @@ 7F292A711E8AB73400A450A3 /* SplashScreenResource in Resources */ = {isa = PBXBuildFile; fileRef = 7F292A701E8AB73400A450A3 /* SplashScreenResource */; }; 7F292AA61E8ABB1100A450A3 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7F292AA41E8ABB1100A450A3 /* LaunchScreen.xib */; }; 7F292AA71E8ABB1100A450A3 /* splash.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F292AA51E8ABB1100A450A3 /* splash.png */; }; - 7F380D0B1FDB3CFC0061AAD2 /* libRCTVideo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F93F9D91FBB726B0088E416 /* libRCTVideo.a */; }; - 7F3F66021FE426EE0085CA0E /* libRNSVG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FDF28E11E1F4B1F00DBBE56 /* libRNSVG.a */; }; - 7F3F660F1FE4280D0085CA0E /* libReactNativeExceptionHandler.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FA7950B1F61A1A500C02924 /* libReactNativeExceptionHandler.a */; }; - 7F3F66101FE4281A0085CA0E /* libRNSentry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FA795061F61A1A500C02924 /* libRNSentry.a */; }; 7F43D5A01F6BF882001FC614 /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 37DD11281E79EBE1004111BA /* libRNDeviceInfo.a */; }; 7F43D5D61F6BF8C2001FC614 /* libRNLocalAuth.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F8C49871F3DFC30003A22BA /* libRNLocalAuth.a */; }; 7F43D5D71F6BF8D0001FC614 /* libRNPasscodeStatus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F8C49F81F3E0710003A22BA /* libRNPasscodeStatus.a */; }; @@ -63,38 +59,13 @@ 7F43D63F1F6BFA19001FC614 /* libBVLinearGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 37D8FEC21E80B5230091F3BD /* libBVLinearGradient.a */; }; 7F43D6401F6BFA82001FC614 /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F63D2811E6C957C001FAE12 /* libRCTPushNotification.a */; }; 7F6877B31E7836070094B63F /* libToolTipMenu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F6877B01E7835E50094B63F /* libToolTipMenu.a */; }; - 7F6C47A51FE87E8C00F5A912 /* PerformRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F6C47A41FE87E8C00F5A912 /* PerformRequests.m */; }; 7F7D7F98201645E100D31155 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F7D7F87201645D300D31155 /* libReactNativePermissions.a */; }; - 7FB6006B1FE3116800DB284F /* libRNFetchBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 375218411F4B9E320035444B /* libRNFetchBlob.a */; }; 7FBB5E9B1E1F5A4B000DE18A /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FDF290C1E1F4B4E00DBBE56 /* libRNVectorIcons.a */; }; 7FC200E81EBB65370099331B /* libReactNativeNavigation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FC200DF1EBB65100099331B /* libReactNativeNavigation.a */; }; - 7FC649EE1FE983660074E4C7 /* EvilIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 349FBA7338E74D9BBD709528 /* EvilIcons.ttf */; }; - 7FC649F01FE9B5D90074E4C7 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D4B1B363C2414DA19C1AC521 /* OpenSans-Bold.ttf */; }; 7FDB92B11F706F58006CDFD1 /* libRNImagePicker.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FDB92A71F706F45006CDFD1 /* libRNImagePicker.a */; }; 7FEB10981F6101710039A015 /* BlurAppScreen.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FEB10971F6101710039A015 /* BlurAppScreen.m */; }; 7FEB109D1F61019C0039A015 /* MattermostManaged.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FEB109A1F61019C0039A015 /* MattermostManaged.m */; }; 7FEB109E1F61019C0039A015 /* UIImage+ImageEffects.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FEB109C1F61019C0039A015 /* UIImage+ImageEffects.m */; }; - 7FF7BE2C1FDEE4AE005E55FE /* MattermostManaged.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FEB109A1F61019C0039A015 /* MattermostManaged.m */; }; - 7FF7BE6D1FDEE5E8005E55FE /* MattermostBucket.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FF7BE6C1FDEE5E8005E55FE /* MattermostBucket.m */; }; - 7FF7BE6E1FDEE5E8005E55FE /* MattermostBucket.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FF7BE6C1FDEE5E8005E55FE /* MattermostBucket.m */; }; - 7FF7BE6F1FDF3CE4005E55FE /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FDF290C1E1F4B4E00DBBE56 /* libRNVectorIcons.a */; }; - 7FF7BE701FDF3EE7005E55FE /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2DCFD31D3F4A4154822AB532 /* Ionicons.ttf */; }; - 7FF7BE711FE004A3005E55FE /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 37DD11281E79EBE1004111BA /* libRNDeviceInfo.a */; }; - 7FF7BE721FE01FC7005E55FE /* libRCTOrientation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 374634671E848085005E1244 /* libRCTOrientation.a */; }; - 7FFDB3191FE3566C009E3BCF /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 005346E5C0E542BFABAE1411 /* FontAwesome.ttf */; }; - 7FFE329E1FD9CB650038C7A0 /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FFE329D1FD9CB650038C7A0 /* ShareViewController.m */; }; - 7FFE32A11FD9CB650038C7A0 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7FFE329F1FD9CB650038C7A0 /* MainInterface.storyboard */; }; - 7FFE32A51FD9CB650038C7A0 /* MattermostShare.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 7FFE329A1FD9CB640038C7A0 /* MattermostShare.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 7FFE32E71FD9CCD00038C7A0 /* libART.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 37ABD39C1F4CE13B001FDE6B /* libART.a */; }; - 7FFE32E81FD9CCDE0038C7A0 /* libRCTCameraRoll.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3752184F1F4B9E980035444B /* libRCTCameraRoll.a */; }; - 7FFE32E91FD9CCF40038C7A0 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; }; - 7FFE32EA1FD9CD050038C7A0 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; - 7FFE32EB1FD9CD170038C7A0 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; - 7FFE32EC1FD9CD360038C7A0 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; - 7FFE32ED1FD9CD450038C7A0 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; - 7FFE32EE1FD9CD800038C7A0 /* libRNLocalAuth.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F8C49871F3DFC30003A22BA /* libRNLocalAuth.a */; }; - 7FFE32EF1FD9CD800038C7A0 /* libRNPasscodeStatus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F8C49F81F3E0710003A22BA /* libRNPasscodeStatus.a */; }; - 7FFE32F11FD9D64E0038C7A0 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 895C9A56B94A45C1BAF568FE /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AC6EB561E1F64C17A69D2FAD /* Entypo.ttf */; }; 8D26455C994F46C39B1392F2 /* libRNSafeArea.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9263CF9B16054263B13EA23B /* libRNSafeArea.a */; }; @@ -566,13 +537,6 @@ remoteGlobalIDString = 6DA7B8031F692C4C00FD1D50; remoteInfo = RNSafeArea; }; - 7FFE32A31FD9CB650038C7A0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 7FFE32991FD9CB640038C7A0; - remoteInfo = MattermostShare; - }; 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; @@ -599,7 +563,6 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( - 7FFE32A51FD9CB650038C7A0 /* MattermostShare.appex in Embed App Extensions */, ); name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -668,14 +631,11 @@ 7F292A701E8AB73400A450A3 /* SplashScreenResource */ = {isa = PBXFileReference; lastKnownFileType = folder; path = SplashScreenResource; sourceTree = ""; }; 7F292AA41E8ABB1100A450A3 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = LaunchScreen.xib; path = SplashScreenResource/LaunchScreen.xib; sourceTree = ""; }; 7F292AA51E8ABB1100A450A3 /* splash.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = splash.png; path = SplashScreenResource/splash.png; sourceTree = ""; }; - 7F380D0A1FDB28160061AAD2 /* MattermostShare.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MattermostShare.entitlements; sourceTree = ""; }; 7F43D5DF1F6BF994001FC614 /* libRNSVG.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libRNSVG.a; path = "../../../../../../../Library/Developer/Xcode/DerivedData/Mattermost-czlinsdviifujheezzjvmisotjrm/Build/Products/Debug-iphonesimulator/libRNSVG.a"; sourceTree = ""; }; 7F43D6051F6BF9EB001FC614 /* libPods-Mattermost.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-Mattermost.a"; path = "../../../../../../../Library/Developer/Xcode/DerivedData/Mattermost-czlinsdviifujheezzjvmisotjrm/Build/Products/Debug-iphonesimulator/libPods-Mattermost.a"; sourceTree = ""; }; 7F63D27B1E6C957C001FAE12 /* RCTPushNotification.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTPushNotification.xcodeproj; path = "../node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj"; sourceTree = ""; }; 7F63D2C21E6DD98A001FAE12 /* Mattermost.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Mattermost.entitlements; path = Mattermost/Mattermost.entitlements; sourceTree = ""; }; 7F6877AA1E7835E50094B63F /* ToolTipMenu.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ToolTipMenu.xcodeproj; path = "../node_modules/react-native-tooltip/ToolTipMenu.xcodeproj"; sourceTree = ""; }; - 7F6C47A31FE87E8C00F5A912 /* PerformRequests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PerformRequests.h; sourceTree = ""; }; - 7F6C47A41FE87E8C00F5A912 /* PerformRequests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerformRequests.m; sourceTree = ""; }; 7F7D7F52201645D300D31155 /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactNativePermissions.xcodeproj; path = "../node_modules/react-native-permissions/ios/ReactNativePermissions.xcodeproj"; sourceTree = ""; }; 7FC200BC1EBB65100099331B /* ReactNativeNavigation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactNativeNavigation.xcodeproj; path = "../node_modules/react-native-navigation/ios/ReactNativeNavigation.xcodeproj"; sourceTree = ""; }; 7FDB92751F706F45006CDFD1 /* RNImagePicker.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNImagePicker.xcodeproj; path = "../node_modules/react-native-image-picker/ios/RNImagePicker.xcodeproj"; sourceTree = ""; }; @@ -685,13 +645,6 @@ 7FEB109A1F61019C0039A015 /* MattermostManaged.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MattermostManaged.m; path = Mattermost/MattermostManaged.m; sourceTree = ""; }; 7FEB109B1F61019C0039A015 /* UIImage+ImageEffects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+ImageEffects.h"; path = "Mattermost/UIImage+ImageEffects.h"; sourceTree = ""; }; 7FEB109C1F61019C0039A015 /* UIImage+ImageEffects.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImage+ImageEffects.m"; path = "Mattermost/UIImage+ImageEffects.m"; sourceTree = ""; }; - 7FF7BE6B1FDEE5E8005E55FE /* MattermostBucket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MattermostBucket.h; sourceTree = ""; }; - 7FF7BE6C1FDEE5E8005E55FE /* MattermostBucket.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MattermostBucket.m; sourceTree = ""; }; - 7FFE329A1FD9CB640038C7A0 /* MattermostShare.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MattermostShare.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - 7FFE329C1FD9CB650038C7A0 /* ShareViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShareViewController.h; sourceTree = ""; }; - 7FFE329D1FD9CB650038C7A0 /* ShareViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShareViewController.m; sourceTree = ""; }; - 7FFE32A01FD9CB650038C7A0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; - 7FFE32A21FD9CB650038C7A0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7FFE32B51FD9CCAA0038C7A0 /* FLAnimatedImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = FLAnimatedImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7FFE32B61FD9CCAA0038C7A0 /* KSCrash.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = KSCrash.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7FFE32B71FD9CCAA0038C7A0 /* KSCrash.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = KSCrash.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -784,31 +737,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 7FFE32971FD9CB640038C7A0 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 7FFE32E71FD9CCD00038C7A0 /* libART.a in Frameworks */, - 7F3F66101FE4281A0085CA0E /* libRNSentry.a in Frameworks */, - 7F3F660F1FE4280D0085CA0E /* libReactNativeExceptionHandler.a in Frameworks */, - 7FB6006B1FE3116800DB284F /* libRNFetchBlob.a in Frameworks */, - 7FF7BE721FE01FC7005E55FE /* libRCTOrientation.a in Frameworks */, - 7FF7BE711FE004A3005E55FE /* libRNDeviceInfo.a in Frameworks */, - 7FF7BE6F1FDF3CE4005E55FE /* libRNVectorIcons.a in Frameworks */, - 7F380D0B1FDB3CFC0061AAD2 /* libRCTVideo.a in Frameworks */, - 7FFE32F11FD9D64E0038C7A0 /* libRCTWebSocket.a in Frameworks */, - 7FFE32EE1FD9CD800038C7A0 /* libRNLocalAuth.a in Frameworks */, - 7FFE32EF1FD9CD800038C7A0 /* libRNPasscodeStatus.a in Frameworks */, - 7F3F66021FE426EE0085CA0E /* libRNSVG.a in Frameworks */, - 7FFE32ED1FD9CD450038C7A0 /* libRCTNetwork.a in Frameworks */, - 7FFE32EC1FD9CD360038C7A0 /* libRCTText.a in Frameworks */, - 7FFE32EB1FD9CD170038C7A0 /* libRCTImage.a in Frameworks */, - 7FFE32EA1FD9CD050038C7A0 /* libReact.a in Frameworks */, - 7FFE32E91FD9CCF40038C7A0 /* libRCTAnimation.a in Frameworks */, - 7FFE32E81FD9CCDE0038C7A0 /* libRCTCameraRoll.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -931,8 +859,6 @@ 7F292AA41E8ABB1100A450A3 /* LaunchScreen.xib */, 13B07FB71A68108700A75B9A /* main.m */, 7F63D2C21E6DD98A001FAE12 /* Mattermost.entitlements */, - 7FF7BE6B1FDEE5E8005E55FE /* MattermostBucket.h */, - 7FF7BE6C1FDEE5E8005E55FE /* MattermostBucket.m */, 7FEB10991F61019C0039A015 /* MattermostManaged.h */, 7FEB109A1F61019C0039A015 /* MattermostManaged.m */, 7F292AA51E8ABB1100A450A3 /* splash.png */, @@ -1242,20 +1168,6 @@ name = Products; sourceTree = ""; }; - 7FFE329B1FD9CB650038C7A0 /* MattermostShare */ = { - isa = PBXGroup; - children = ( - 7F380D0A1FDB28160061AAD2 /* MattermostShare.entitlements */, - 7FFE329C1FD9CB650038C7A0 /* ShareViewController.h */, - 7FFE329D1FD9CB650038C7A0 /* ShareViewController.m */, - 7FFE329F1FD9CB650038C7A0 /* MainInterface.storyboard */, - 7FFE32A21FD9CB650038C7A0 /* Info.plist */, - 7F6C47A31FE87E8C00F5A912 /* PerformRequests.h */, - 7F6C47A41FE87E8C00F5A912 /* PerformRequests.m */, - ); - path = MattermostShare; - sourceTree = ""; - }; 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( @@ -1315,7 +1227,6 @@ 13B07FAE1A68108700A75B9A /* Mattermost */, 832341AE1AAA6A7D00B99B32 /* Libraries */, 00E356EF1AD99517003FC87E /* MattermostTests */, - 7FFE329B1FD9CB650038C7A0 /* MattermostShare */, 83CBBA001A601CBA00E9B192 /* Products */, 0156F464626F49C2977D7982 /* Resources */, 37DF8AC51F5F0D410079BF89 /* Recovered References */, @@ -1331,7 +1242,6 @@ children = ( 13B07F961A680F5B00A75B9A /* Mattermost.app */, 00E356EE1AD99517003FC87E /* MattermostTests.xctest */, - 7FFE329A1FD9CB640038C7A0 /* MattermostShare.appex */, ); name = Products; sourceTree = ""; @@ -1378,31 +1288,12 @@ buildRules = ( ); dependencies = ( - 7FFE32A41FD9CB650038C7A0 /* PBXTargetDependency */, ); name = Mattermost; productName = "Hello World"; productReference = 13B07F961A680F5B00A75B9A /* Mattermost.app */; productType = "com.apple.product-type.application"; }; - 7FFE32991FD9CB640038C7A0 /* MattermostShare */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7FFE32A61FD9CB650038C7A0 /* Build configuration list for PBXNativeTarget "MattermostShare" */; - buildPhases = ( - 7FFE32961FD9CB640038C7A0 /* Sources */, - 7FFE32971FD9CB640038C7A0 /* Frameworks */, - 7FFE32981FD9CB640038C7A0 /* Resources */, - 7FFE32F01FD9D1F00038C7A0 /* Bundle React Native code and images */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = MattermostShare; - productName = MattermostShare; - productReference = 7FFE329A1FD9CB640038C7A0 /* MattermostShare.appex */; - productType = "com.apple.product-type.app-extension"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -1431,17 +1322,6 @@ }; }; }; - 7FFE32991FD9CB640038C7A0 = { - CreatedOnToolsVersion = 9.1; - DevelopmentTeam = UQ8HT4Q2XM; - LastSwiftMigration = 920; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.ApplicationGroups.iOS = { - enabled = 1; - }; - }; - }; }; }; buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Mattermost" */; @@ -1605,7 +1485,6 @@ targets = ( 13B07F861A680F5B00A75B9A /* Mattermost */, 00E356ED1AD99517003FC87E /* MattermostTests */, - 7FFE32991FD9CB640038C7A0 /* MattermostShare */, ); }; /* End PBXProject section */ @@ -2108,18 +1987,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 7FFE32981FD9CB640038C7A0 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7FC649F01FE9B5D90074E4C7 /* OpenSans-Bold.ttf in Resources */, - 7FC649EE1FE983660074E4C7 /* EvilIcons.ttf in Resources */, - 7FF7BE701FDF3EE7005E55FE /* Ionicons.ttf in Resources */, - 7FFDB3191FE3566C009E3BCF /* FontAwesome.ttf in Resources */, - 7FFE32A11FD9CB650038C7A0 /* MainInterface.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -2200,20 +2067,6 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Mattermost/Pods-Mattermost-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 7FFE32F01FD9D1F00038C7A0 /* Bundle React Native code and images */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Bundle React Native code and images"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = ./bundleReactNative.sh; - }; AE4769B235D14E6C9C64EA78 /* Upload Debug Symbols to Sentry */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -2279,23 +2132,11 @@ 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, 7FEB109E1F61019C0039A015 /* UIImage+ImageEffects.m in Sources */, 13B07FC11A68108700A75B9A /* main.m in Sources */, - 7FF7BE6D1FDEE5E8005E55FE /* MattermostBucket.m in Sources */, 7FEB10981F6101710039A015 /* BlurAppScreen.m in Sources */, 7FEB109D1F61019C0039A015 /* MattermostManaged.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 7FFE32961FD9CB640038C7A0 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7FF7BE6E1FDEE5E8005E55FE /* MattermostBucket.m in Sources */, - 7FF7BE2C1FDEE4AE005E55FE /* MattermostManaged.m in Sources */, - 7FFE329E1FD9CB650038C7A0 /* ShareViewController.m in Sources */, - 7F6C47A51FE87E8C00F5A912 /* PerformRequests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -2304,24 +2145,8 @@ target = 13B07F861A680F5B00A75B9A /* Mattermost */; targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; }; - 7FFE32A41FD9CB650038C7A0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 7FFE32991FD9CB640038C7A0 /* MattermostShare */; - targetProxy = 7FFE32A31FD9CB650038C7A0 /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ -/* Begin PBXVariantGroup section */ - 7FFE329F1FD9CB650038C7A0 /* MainInterface.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 7FFE32A01FD9CB650038C7A0 /* Base */, - ); - name = MainInterface.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; @@ -2490,122 +2315,6 @@ }; name = Release; }; - 7FFE32A71FD9CB650038C7A0 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = 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_STYLE = Automatic; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = UQ8HT4Q2XM; - GCC_C_LANGUAGE_STANDARD = gnu11; - HEADER_SEARCH_PATHS = ( - "$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/**", - "$(SRCROOT)/../node_modules/react-native-orientation/iOS/RCTOrientation/**", - "$(SRCROOT)/../node_modules/react-native-navigation/ios/**", - "$(SRCROOT)/../node_modules/react-native-notifications/RNNotifications/**", - "$(SRCROOT)/../node_modules/react-native-local-auth", - "$(SRCROOT)/../node_modules/react-native-passcode-status/ios", - "$(SRCROOT)/../node_modules/jail-monkey/JailMonkey", - "$(SRCROOT)/../node_modules/react-native/Libraries/**", - "$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**", - "$(SRCROOT)/../node_modules/react-native-fetch-blob/ios/**", - "$(SRCROOT)/../node_modules/react-native-exception-handler/ios", - "$(SRCROOT)/../node_modules/react-native-sentry/ios/**", - "$(SRCROOT)/../node_modules/react-native-cookies/ios/RNCookieManagerIOS", - "$(SRCROOT)/../node_modules/react-native-image-picker/ios", - "$(SRCROOT)/../node_modules/react-native-youtube/**", - "$(SRCROOT)/../node_modules/react-native-video/ios", - "$(SRCROOT)/../node_modules/react-native-doc-viewer/ios/**", - "$(SRCROOT)/../node_modules/react-native-safe-area/ios/RNSafeArea", - ); - INFOPLIST_FILE = MattermostShare/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.mattermost.rnbeta.MattermostShare; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_OBJC_BRIDGING_HEADER = "MattermostShare/MattermostShare-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 7FFE32A81FD9CB650038C7A0 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_MODULES = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = 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_STYLE = Automatic; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = UQ8HT4Q2XM; - GCC_C_LANGUAGE_STANDARD = gnu11; - HEADER_SEARCH_PATHS = ( - "$(SRCROOT)/../node_modules/react-native/Libraries/PushNotificationIOS/**", - "$(SRCROOT)/../node_modules/react-native-orientation/iOS/RCTOrientation/**", - "$(SRCROOT)/../node_modules/react-native-navigation/ios/**", - "$(SRCROOT)/../node_modules/react-native-notifications/RNNotifications/**", - "$(SRCROOT)/../node_modules/react-native-local-auth", - "$(SRCROOT)/../node_modules/react-native-passcode-status/ios", - "$(SRCROOT)/../node_modules/jail-monkey/JailMonkey", - "$(SRCROOT)/../node_modules/react-native/Libraries/**", - "$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**", - "$(SRCROOT)/../node_modules/react-native-fetch-blob/ios/**", - "$(SRCROOT)/../node_modules/react-native-exception-handler/ios", - "$(SRCROOT)/../node_modules/react-native-sentry/ios/**", - "$(SRCROOT)/../node_modules/react-native-cookies/ios/RNCookieManagerIOS", - "$(SRCROOT)/../node_modules/react-native-image-picker/ios", - "$(SRCROOT)/../node_modules/react-native-youtube/**", - "$(SRCROOT)/../node_modules/react-native-video/ios", - "$(SRCROOT)/../node_modules/react-native-doc-viewer/ios/**", - "$(SRCROOT)/../node_modules/react-native-safe-area/ios/RNSafeArea", - ); - INFOPLIST_FILE = MattermostShare/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.mattermost.rnbeta.MattermostShare; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_OBJC_BRIDGING_HEADER = "MattermostShare/MattermostShare-Bridging-Header.h"; - SWIFT_VERSION = 3.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; 83CBBA201A601CBA00E9B192 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2711,15 +2420,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 7FFE32A61FD9CB650038C7A0 /* Build configuration list for PBXNativeTarget "MattermostShare" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7FFE32A71FD9CB650038C7A0 /* Debug */, - 7FFE32A81FD9CB650038C7A0 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Mattermost" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/ios/MattermostBucket.h b/ios/MattermostBucket.h deleted file mode 100644 index 79bda4b8a..000000000 --- a/ios/MattermostBucket.h +++ /dev/null @@ -1,7 +0,0 @@ -#import -#import "React/RCTBridgeModule.h" - -@interface MattermostBucket : NSObject -- (NSUserDefaults *)bucketByName:(NSString*)name; --(NSString *)readFromFile:(NSString *)fileName appGroupId:(NSString *)appGroupId; -@end diff --git a/ios/MattermostBucket.m b/ios/MattermostBucket.m deleted file mode 100644 index 13358e70b..000000000 --- a/ios/MattermostBucket.m +++ /dev/null @@ -1,122 +0,0 @@ -// -// MattermostBucket.m -// Mattermost -// -// Created by Elias Nahum on 12/11/17. -// Copyright © 2017 Facebook. All rights reserved. -// - -#import "MattermostBucket.h" - -@implementation MattermostBucket - -+(BOOL)requiresMainQueueSetup -{ - return YES; -} - -RCT_EXPORT_MODULE(); - -RCT_EXPORT_METHOD(writeToFile:(NSString *)fileName - content:(NSString *)content - bucketName:(NSString *)bucketName) { - [self writeToFile:fileName content:content appGroupId:bucketName]; -} - -RCT_EXPORT_METHOD(readFromFile:(NSString *)fileName - bucketName:(NSString*)bucketName - getWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) -{ - id value = [self readFromFile:fileName appGroupId:bucketName]; - - if (value == nil) { - value = [NSNull null]; - } - - resolve(value); -} - -RCT_EXPORT_METHOD(removeFile:(NSString *)fileName - bucketName:(NSString*)bucketName) -{ - [self removeFile:fileName appGroupId:bucketName]; -} - -RCT_EXPORT_METHOD(setPreference:(NSString *) key - value:(NSString *) value - bucketName:(NSString*) bucketName) -{ - [self setPreference:key value:value appGroupId:bucketName]; -} - -RCT_EXPORT_METHOD(getPreference:(NSString *) key - bucketName:(NSString*) bucketName - getWithResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) -{ - id value = [self getPreference:key appGroupId:bucketName]; - - if (value == nil) { - value = [NSNull null]; - } - - resolve(value); -} - -RCT_EXPORT_METHOD(removePreference:(NSString *) key - bucketName:(NSString*) bucketName) -{ - [self removePreference:key appGroupId:bucketName]; -} - --(NSString *)fileUrl:(NSString *)fileName appGroupdId:(NSString *)appGroupId { - NSURL *fileManagerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:appGroupId]; - return [NSString stringWithFormat:@"%@/%@", fileManagerURL.path, fileName]; -} - --(void)writeToFile:(NSString *)fileName content:(NSString *)content appGroupId:(NSString *)appGroupId { - NSString *filePath = [self fileUrl:fileName appGroupdId:appGroupId]; - NSFileManager *fileManager= [NSFileManager defaultManager]; - if(![fileManager fileExistsAtPath:filePath]) { - [fileManager createFileAtPath:filePath contents:nil attributes:nil]; - } - [content writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil]; -} - --(NSString *)readFromFile:(NSString *)fileName appGroupId:(NSString *)appGroupId { - NSString *filePath = [self fileUrl:fileName appGroupdId:appGroupId]; - NSFileManager *fileManager= [NSFileManager defaultManager]; - if(![fileManager fileExistsAtPath:filePath]) { - return nil; - } - return [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; -} - --(void)removeFile:(NSString *)fileName appGroupId:(NSString *)appGroupId { - NSString *filePath = [self fileUrl:fileName appGroupdId:appGroupId]; - NSFileManager *fileManager= [NSFileManager defaultManager]; - if([fileManager isDeletableFileAtPath:filePath]) { - [fileManager removeItemAtPath:filePath error:nil]; - } -} - --(NSUserDefaults *)bucketByName:(NSString*)name { - return [[NSUserDefaults alloc] initWithSuiteName: name]; -} - --(void) setPreference:(NSString *)key value:(NSString *) value appGroupId:(NSString*)appGroupId { - NSUserDefaults* bucket = [self bucketByName: appGroupId]; - [bucket setObject:value forKey:key]; -} - --(id) getPreference:(NSString *)key appGroupId:(NSString*)appGroupId { - NSUserDefaults* bucket = [self bucketByName: appGroupId]; - return [bucket objectForKey:key]; -} - --(void) removePreference:(NSString *)key appGroupId:(NSString*)appGroupId { - NSUserDefaults* bucket = [self bucketByName: appGroupId]; - [bucket removeObjectForKey: key]; -} -@end diff --git a/ios/MattermostShare/Base.lproj/MainInterface.storyboard b/ios/MattermostShare/Base.lproj/MainInterface.storyboard deleted file mode 100644 index a14188503..000000000 --- a/ios/MattermostShare/Base.lproj/MainInterface.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/MattermostShare/Info.plist b/ios/MattermostShare/Info.plist deleted file mode 100644 index d85f93606..000000000 --- a/ios/MattermostShare/Info.plist +++ /dev/null @@ -1,65 +0,0 @@ - - - - - BundleEntryFilename - share.ios.js - BundleForced - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Mattermost - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - com.mattermost.rnbeta.MattermostShare - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - XPC! - CFBundleShortVersionString - 1.6.0 - CFBundleVersion - 84 - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - - NSExtension - - NSExtensionAttributes - - NSExtensionActivationRule - - NSExtensionActivationSupportsAttachmentsWithMaxCount - 5 - NSExtensionActivationSupportsFileWithMaxCount - 5 - NSExtensionActivationSupportsImageWithMaxCount - 5 - NSExtensionActivationSupportsMovieWithMaxCount - 5 - NSExtensionActivationSupportsText - - NSExtensionActivationSupportsWebURLWithMaxCount - 1 - - - NSExtensionMainStoryboard - MainInterface - NSExtensionPointIdentifier - com.apple.share-services - - UIAppFonts - - Ionicons.ttf - FontAwesome.ttf - EvilIcons.ttf - OpenSans-Bold.ttf - - - 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/PerformRequests.h b/ios/MattermostShare/PerformRequests.h deleted file mode 100644 index 471c90213..000000000 --- a/ios/MattermostShare/PerformRequests.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// PerformRequests.h -// MattermostShare -// -// Created by Elias Nahum on 12/18/17. -// Copyright © 2017 Facebook. All rights reserved. -// - -#import -#import "MattermostBucket.h" - -@interface PerformRequests : NSObject -@property (nonatomic, strong) NSString *appGroupId; -@property (nonatomic, strong) NSString *requestId; -@property (nonatomic, strong) NSMutableArray *fileIds; -@property (nonatomic, strong) NSArray *files; -@property (nonatomic, strong) NSDictionary *post; - -@property (nonatomic, strong) NSString *serverUrl; -@property (nonatomic, strong) NSString *token; -@property (nonatomic, strong) NSExtensionContext *extensionContext; -@property MattermostBucket *bucket; - -- (id) initWithPost:(NSDictionary *) post - withFiles:(NSArray *) files - forRequestId:(NSString *)requestId - inAppGroupId:(NSString *) appGroupId - inContext:(NSExtensionContext *) extensionContext; - --(void)createPost; -@end diff --git a/ios/MattermostShare/PerformRequests.m b/ios/MattermostShare/PerformRequests.m deleted file mode 100644 index 8cc3639b9..000000000 --- a/ios/MattermostShare/PerformRequests.m +++ /dev/null @@ -1,162 +0,0 @@ -// -// PerformRequests.m -// MattermostShare -// -// Created by Elias Nahum on 12/18/17. -// Copyright © 2017 Facebook. All rights reserved. -// - -#import "PerformRequests.h" -#import "MattermostBucket.h" -#import "ShareViewController.h" - -@implementation PerformRequests - -- (id) initWithPost:(NSDictionary *) post - withFiles:(NSArray *) files - forRequestId:(NSString *)requestId - inAppGroupId:(NSString *) appGroupId - inContext:(NSExtensionContext *) context { - self = [super init]; - if (self) { - self.post = post; - self.files = files; - self.appGroupId = appGroupId; - self.requestId = requestId; - self.extensionContext = context; - - self.bucket = [[MattermostBucket alloc] init]; - [self setCredentials]; - } - return self; -} - --(void)setCredentials { - NSString *entitiesString = [self.bucket readFromFile:@"entities" appGroupId:self.appGroupId]; - NSData *entitiesData = [entitiesString dataUsingEncoding:NSUTF8StringEncoding]; - NSDictionary *entities = [NSJSONSerialization JSONObjectWithData:entitiesData options:NSJSONReadingMutableContainers error:nil]; - NSDictionary *credentials = [[entities objectForKey:@"general"] objectForKey:@"credentials"]; - self.serverUrl = [credentials objectForKey:@"url"]; - self.token = [credentials objectForKey:@"token"]; -} - --(void)URLSession:(NSURLSession *)session task:(NSURLSessionDataTask *)task didCompleteWithError:(nullable NSError *)error { - if(error != nil) { - NSLog(@"ERROR %@", [error userInfo]); - [self.extensionContext completeRequestReturningItems:nil - completionHandler:nil]; - NSLog(@"invalidating session %@", self.requestId); - [session finishTasksAndInvalidate]; - } -} - --(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { - NSString *sessionRequestId = [[session configuration] identifier]; - - if ([sessionRequestId containsString:@"files"]) { - NSLog(@"Got file response"); - NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; - if (json != nil) { - NSArray *fileInfos = [json objectForKey:@"file_infos"]; - self.fileIds = [[NSMutableArray alloc] init]; - for (id file in fileInfos) { - [self.fileIds addObject:[file objectForKey:@"id"]]; - } - NSLog(@"Calling sendPostRequest"); - [self sendPostRequest]; - } - - NSLog(@"Cleaning temp files"); - [self cleanUpTempFiles]; - } -} - --(void)createPost { - NSString *channelId = [self.post objectForKey:@"channel_id"]; - - NSURL *filesUrl = [NSURL URLWithString:[self.serverUrl stringByAppendingString:@"/api/v4/files"]]; - - if (self.files != nil && [self.files count] > 0) { - NSString *POST_BODY_BOUNDARY = @"mobile.client.file.upload"; - NSURLSessionConfiguration* config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[self.requestId stringByAppendingString:@"-files"]]; - config.sharedContainerIdentifier = self.appGroupId; - - NSMutableURLRequest *uploadRequest = [NSMutableURLRequest requestWithURL:filesUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:120.0]; - [uploadRequest setHTTPMethod:@"POST"]; - [uploadRequest setValue:[@"Bearer " stringByAppendingString:self.token] forHTTPHeaderField:@"Authorization"]; - [uploadRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"]; - - NSString *contentTypeValue = [NSString stringWithFormat:@"multipart/form-data;boundary=%@", POST_BODY_BOUNDARY]; - [uploadRequest addValue:contentTypeValue forHTTPHeaderField:@"Content-Type"]; - - NSMutableData *dataForm = [NSMutableData alloc]; - [dataForm appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", POST_BODY_BOUNDARY] dataUsingEncoding:NSUTF8StringEncoding]]; - [dataForm appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"channel_id\";\r\n\r\n%@", channelId] dataUsingEncoding:NSUTF8StringEncoding]]; - - for (id file in self.files) { - NSData *fileData = [NSData dataWithContentsOfFile:[file objectForKey:@"filePath"]]; - NSString *mimeType = [file objectForKey:@"mimeType"]; - NSLog(@"MimeType %@", mimeType); - [dataForm appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", POST_BODY_BOUNDARY] dataUsingEncoding:NSUTF8StringEncoding]]; - [dataForm appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"files\"; filename=\"%@\"\r\n", - [file objectForKey:@"filename"]] dataUsingEncoding:NSUTF8StringEncoding]]; - [dataForm appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimeType] dataUsingEncoding:NSUTF8StringEncoding]]; - [dataForm appendData:[NSData dataWithData:fileData]]; - } - - [dataForm appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", POST_BODY_BOUNDARY] dataUsingEncoding:NSUTF8StringEncoding]]; - [uploadRequest setHTTPBody:dataForm]; - NSURLSession *uploadSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]]; - NSURLSessionDataTask *uploadTask = [uploadSession dataTaskWithRequest:uploadRequest]; - NSLog(@"Executing file request"); - [uploadTask resume]; - } else { - [self sendPostRequest]; - } -} - --(void)sendPostRequest { - NSMutableDictionary *post = [self.post mutableCopy]; - [post setValue:self.fileIds forKey:@"file_ids"]; - NSData *postData = [NSJSONSerialization dataWithJSONObject:post options:NSJSONWritingPrettyPrinted error:nil]; - NSString* postAsString = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding]; - - NSURL *createUrl = [NSURL URLWithString:[self.serverUrl stringByAppendingString:@"/api/v4/posts"]]; - - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:createUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0]; - [request setHTTPMethod:@"POST"]; - [request setValue:[@"Bearer " stringByAppendingString:self.token] forHTTPHeaderField:@"Authorization"]; - [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; - [request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; - [request setHTTPBody:[postAsString dataUsingEncoding:NSUTF8StringEncoding]]; - - NSURLSessionConfiguration* config = [NSURLSessionConfiguration ephemeralSessionConfiguration]; - NSURLSession *createSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil]; - NSURLSessionDataTask *createTask = [createSession dataTaskWithRequest:request]; - NSLog(@"Executing post request"); - [createTask resume]; - [self.extensionContext completeRequestReturningItems:nil - completionHandler:nil]; - NSLog(@"Extension closed"); -} - -- (void) cleanUpTempFiles { - NSURL *tmpDirectoryURL = [ShareViewController tempContainerURL:self.appGroupId]; - if (tmpDirectoryURL == nil) { - return; - } - - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSError *error; - NSArray *tmpFiles = [fileManager contentsOfDirectoryAtPath:[tmpDirectoryURL path] error:&error]; - if (error) { - return; - } - - for (NSString *file in tmpFiles) - { - error = nil; - [fileManager removeItemAtPath:[[tmpDirectoryURL URLByAppendingPathComponent:file] path] error:&error]; - } -} -@end diff --git a/ios/MattermostShare/ShareViewController.h b/ios/MattermostShare/ShareViewController.h deleted file mode 100644 index ade93ce22..000000000 --- a/ios/MattermostShare/ShareViewController.h +++ /dev/null @@ -1,6 +0,0 @@ -#import -#import "React/RCTBridgeModule.h" - -@interface ShareViewController : UIViewController -+ (NSURL*) tempContainerURL: (NSString*)appGroupId; -@end diff --git a/ios/MattermostShare/ShareViewController.m b/ios/MattermostShare/ShareViewController.m deleted file mode 100644 index c3699f174..000000000 --- a/ios/MattermostShare/ShareViewController.m +++ /dev/null @@ -1,273 +0,0 @@ -#import "ShareViewController.h" -#import -#import -#import "PerformRequests.h" - -NSExtensionContext* extensionContext; - -@implementation ShareViewController -+ (BOOL)requiresMainQueueSetup -{ - return YES; -} - -- (UIView*) shareView { - NSURL *jsCodeLocation; - - jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"share.ios" fallbackResource:nil]; - - RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation - moduleName:@"MattermostShare" - initialProperties:nil - launchOptions:nil]; - rootView.backgroundColor = nil; - return rootView; -} - -RCT_EXPORT_MODULE(MattermostShare); - -- (void)viewDidLoad { - [super viewDidLoad]; - extensionContext = self.extensionContext; - UIView *rootView = [self shareView]; - if (rootView.backgroundColor == nil) { - rootView.backgroundColor = [[UIColor alloc] initWithRed:1 green:1 blue:1 alpha:0.1]; - } - - self.view = rootView; -} - -RCT_REMAP_METHOD(getOrientation, - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - if([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height) { - resolve(@"PORTRAIT"); - } else { - resolve(@"LANDSCAPE"); - } -} - -RCT_EXPORT_METHOD(close:(NSDictionary *)data appGroupId:(NSString *)appGroupId) { - if (data != nil) { - NSDictionary *post = [data objectForKey:@"post"]; - NSArray *files = [data objectForKey:@"files"]; - NSString *requestId = [data objectForKey:@"requestId"]; - NSLog(@"Call createPost"); - PerformRequests *request = [[PerformRequests alloc] initWithPost:post withFiles:files forRequestId:requestId inAppGroupId:appGroupId inContext:extensionContext]; - [request createPost]; - } else { - [extensionContext completeRequestReturningItems:nil - completionHandler:nil]; - NSLog(@"Extension closed"); - } -} - -RCT_REMAP_METHOD(data, - appGroupId: (NSString *)appGroupId - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) -{ - [self extractDataFromContext: extensionContext withAppGroup: appGroupId andCallback:^(NSArray* items ,NSError* err) { - if (err) { - reject(@"data", @"Failed to extract attachment content", err); - return; - } - resolve(items); - }]; -} - -typedef void (^ProviderCallback)(NSString *content, NSString *contentType, BOOL owner, NSError *err); - -- (void)extractDataFromContext:(NSExtensionContext *)context withAppGroup:(NSString *) appGroupId andCallback:(void(^)(NSArray *items ,NSError *err))callback { - @try { - NSExtensionItem *item = [context.inputItems firstObject]; - NSArray *attachments = item.attachments; - NSMutableArray *items = [[NSMutableArray alloc] init]; - - __block int attachmentIdx = 0; - __block ProviderCallback providerCb = nil; - __block __weak ProviderCallback weakProviderCb = nil; - providerCb = ^ void (NSString *content, NSString *contentType, BOOL owner, NSError *err) { - if (err) { - callback(nil, err); - return; - } - - if (content != nil) { - [items addObject:@{ - @"type": contentType, - @"value": content, - @"owner": [NSNumber numberWithBool:owner], - }]; - } - - ++attachmentIdx; - if (attachmentIdx == [attachments count]) { - callback(items, nil); - } else { - [self extractDataFromProvider:attachments[attachmentIdx] withAppGroup:appGroupId andCallback: weakProviderCb]; - } - }; - weakProviderCb = providerCb; - [self extractDataFromProvider:attachments[0] withAppGroup:appGroupId andCallback: providerCb]; - } - @catch (NSException *exc) { - NSError *error = [NSError errorWithDomain:@"fiftythree.paste" code:1 userInfo:@{ - @"reason": [exc description] - }]; - callback(nil, error); - } -} - -- (void)extractDataFromProvider:(NSItemProvider *)provider withAppGroup:(NSString *) appGroupId andCallback:(void(^)(NSString* content, NSString* contentType, BOOL owner, NSError *err))callback { - if([provider hasItemConformingToTypeIdentifier:@"public.movie"]) { - [provider loadItemForTypeIdentifier:@"public.movie" options:nil completionHandler:^(id item, NSError *error) { - @try { - if ([item isKindOfClass: NSURL.class]) { - NSURL *url = (NSURL *)item; - return callback([url absoluteString], @"public.movie", NO, nil); - } - return callback(nil, nil, NO, nil); - } - @catch(NSException *exc) { - NSError *error = [NSError errorWithDomain:@"fiftythree.paste" code:2 userInfo:@{ - @"reason": [exc description] - }]; - callback(nil, nil, NO, error); - } - }]; - return; - } - if([provider hasItemConformingToTypeIdentifier:@"public.image"]) { - [provider loadItemForTypeIdentifier:@"public.image" options:nil completionHandler:^(id item, NSError *error) { - if (error) { - callback(nil, nil, NO, error); - return; - } - - @try { - if ([item isKindOfClass: NSURL.class]) { - NSURL *url = (NSURL *)item; - return callback([url absoluteString], @"public.image", NO, nil); - } else if ([item isKindOfClass: UIImage.class]) { - UIImage *image = (UIImage *)item; - NSString *fileName = [NSString stringWithFormat:@"%@.jpg", [[NSUUID UUID] UUIDString]]; - NSURL *tempContainerURL = [ShareViewController tempContainerURL:appGroupId]; - if (tempContainerURL == nil){ - return callback(nil, nil, NO, nil); - } - - NSURL *tempFileURL = [tempContainerURL URLByAppendingPathComponent: fileName]; - BOOL created = [UIImageJPEGRepresentation(image, 1) writeToFile:[tempFileURL path] atomically:YES]; - if (created) { - return callback([tempFileURL absoluteString], @"public.image", YES, nil); - } else { - return callback(nil, nil, NO, nil); - } - } else if ([item isKindOfClass: NSData.class]) { - NSString *fileName = [NSString stringWithFormat:@"%@.jpg", [[NSUUID UUID] UUIDString]]; - NSData *data = (NSData *)item; - UIImage *image = [UIImage imageWithData:data]; - NSURL *tempContainerURL = [ShareViewController tempContainerURL:appGroupId]; - if (tempContainerURL == nil){ - return callback(nil, nil, NO, nil); - } - NSURL *tempFileURL = [tempContainerURL URLByAppendingPathComponent: fileName]; - BOOL created = [UIImageJPEGRepresentation(image, 0.95) writeToFile:[tempFileURL path] atomically:YES]; - if (created) { - return callback([tempFileURL absoluteString], @"public.image", YES, nil); - } else { - return callback(nil, nil, NO, nil); - } - } else { - // Do nothing, some type we don't support. - return callback(nil, nil, NO, nil); - } - } - @catch(NSException *exc) { - NSError *error = [NSError errorWithDomain:@"fiftythree.paste" code:2 userInfo:@{ - @"reason": [exc description] - }]; - callback(nil, nil, NO, error); - } - }]; - return; - } - - if([provider hasItemConformingToTypeIdentifier:@"public.file-url"]) { - [provider loadItemForTypeIdentifier:@"public.file-url" options:nil completionHandler:^(id item, NSError *error) { - if (error) { - callback(nil, nil, NO, error); - return; - } - - if ([item isKindOfClass:NSURL.class]) { - return callback([(NSURL *)item absoluteString], @"public.file-url", NO, nil); - } else if ([item isKindOfClass:NSString.class]) { - return callback((NSString *)item, @"public.file-url", NO, nil); - } - callback(nil, nil, NO, nil); - }]; - return; - } - - if([provider hasItemConformingToTypeIdentifier:@"public.url"]) { - [provider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(id item, NSError *error) { - if (error) { - callback(nil, nil, NO, error); - return; - } - - if ([item isKindOfClass:NSURL.class]) { - return callback([(NSURL *)item absoluteString], @"public.url", NO, nil); - } else if ([item isKindOfClass:NSString.class]) { - return callback((NSString *)item, @"public.url", NO, nil); - } - }]; - return; - } - - if([provider hasItemConformingToTypeIdentifier:@"public.plain-text"]) { - [provider loadItemForTypeIdentifier:@"public.plain-text" options:nil completionHandler:^(id item, NSError *error) { - if (error) { - callback(nil, nil, NO, error); - return; - } - - if ([item isKindOfClass:NSString.class]) { - return callback((NSString *)item, @"public.plain-text", NO, nil); - } else if ([item isKindOfClass:NSAttributedString.class]) { - NSAttributedString *str = (NSAttributedString *)item; - return callback([str string], @"public.plain-text", NO, nil); - } else if ([item isKindOfClass:NSData.class]) { - NSString *str = [[NSString alloc] initWithData:(NSData *)item encoding:NSUTF8StringEncoding]; - if (str) { - return callback(str, @"public.plain-text", NO, nil); - } else { - return callback(nil, nil, NO, nil); - } - } else { - return callback(nil, nil, NO, nil); - } - }]; - return; - } - - callback(nil, nil, NO, nil); -} - -+ (NSURL*) tempContainerURL: (NSString*)appGroupId { - NSFileManager *manager = [NSFileManager defaultManager]; - NSURL *containerURL = [manager containerURLForSecurityApplicationGroupIdentifier: appGroupId]; - NSURL *tempDirectoryURL = [containerURL URLByAppendingPathComponent:@"shareTempItems"]; - if (![manager fileExistsAtPath:[tempDirectoryURL path]]) { - NSError *err; - [manager createDirectoryAtURL:tempDirectoryURL withIntermediateDirectories:YES attributes:nil error:&err]; - if (err) { - return nil; - } - } - - return tempDirectoryURL; -} -@end diff --git a/share.ios.js b/share.ios.js deleted file mode 100644 index 8946251e0..000000000 --- a/share.ios.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import {AppRegistry} from 'react-native'; - -import ShareExtension from 'share_extension/ios'; - -AppRegistry.registerComponent('MattermostShare', () => ShareExtension); diff --git a/share_extension/ios/extension_channels.js b/share_extension/ios/extension_channels.js deleted file mode 100644 index a8596bb09..000000000 --- a/share_extension/ios/extension_channels.js +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React, {PureComponent} from 'react'; -import PropTypes from 'prop-types'; -import { - ActivityIndicator, - SectionList, - Text, - View -} from 'react-native'; -import DeviceInfo from 'react-native-device-info'; -import {intlShape} from 'react-intl'; - -import {General} from 'mattermost-redux/constants'; -import {getChannelsInTeam, getDirectChannels} from 'mattermost-redux/selectors/entities/channels'; - -import SearchBar from 'app/components/search_bar'; -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; - -import ExtensionChannelItem from 'share_extension/common/extension_channel_item'; - -import ExtensionNavBar from './extension_nav_bar'; - -export default class ExtensionChannels extends PureComponent { - static propTypes = { - entities: PropTypes.object, - currentChannelId: PropTypes.string.isRequired, - navigator: PropTypes.object.isRequired, - onSelectChannel: PropTypes.func.isRequired, - teamId: PropTypes.string.isRequired, - theme: PropTypes.object.isRequired, - title: PropTypes.string.isRequired - }; - - static contextTypes = { - intl: intlShape - }; - - state = { - sections: null - }; - - componentWillMount() { - this.loadChannels(); - } - - buildSections = (term) => { - const {channels} = this.state; - const sections = []; - const publicChannels = []; - const privateChannels = []; - const directChannels = []; - - channels.forEach((channel) => { - const include = term ? channel.display_name.toLowerCase().includes(term.toLowerCase()) : true; - if (channel.display_name && include) { - switch (channel.type) { - case General.OPEN_CHANNEL: - publicChannels.push(channel); - break; - case General.PRIVATE_CHANNEL: - privateChannels.push(channel); - break; - default: - directChannels.push(channel); - break; - } - } - }); - - if (publicChannels.length) { - sections.push({ - id: 'sidebar.channels', - defaultMessage: 'PUBLIC CHANNELS', - data: publicChannels.sort(this.sortDisplayName) - }); - } - - if (privateChannels.length) { - sections.push({ - id: 'sidebar.pg', - defaultMessage: 'PRIVATE CHANNELS', - data: privateChannels.sort(this.sortDisplayName) - }); - } - - if (directChannels.length) { - sections.push({ - id: 'sidebar.direct', - defaultMessage: 'DIRECT MESSAGES', - data: directChannels.sort(this.sortDisplayName) - }); - } - - this.setState({sections}); - }; - - goBack = () => { - this.props.navigator.pop(); - }; - - keyExtractor = (item) => item.id; - - loadChannels = async () => { - try { - const {entities, teamId} = this.props; - - // get the channels for the specified team - const channelsInTeam = getChannelsInTeam({entities}); - const channelIds = channelsInTeam[teamId] || []; - const direct = getDirectChannels({entities}); - const channels = channelIds.map((id) => this.props.entities.channels.channels[id]).concat(direct); - - this.setState({ - channels - }, () => { - this.buildSections(); - }); - } catch (error) { - this.setState({error}); - } - }; - - handleSearch = (term) => { - this.setState({term}, () => { - if (this.throttleTimeout) { - clearTimeout(this.throttleTimeout); - } - - this.throttleTimeout = setTimeout(() => { - this.buildSections(term); - }, 300); - }); - }; - - handleSelectChannel = (channel) => { - this.props.onSelectChannel(channel); - this.goBack(); - }; - - renderBody = (styles) => { - const {error, sections} = this.state; - - if (error) { - return ( - - - {error.message} - - - ); - } - - if (!sections) { - return ( - - - - ); - } - - return ( - - ); - }; - - renderItem = ({item}) => { - const {currentChannelId, theme} = this.props; - - return ( - - ); - }; - - renderItemSeparator = () => { - const {theme} = this.props; - const styles = getStyleSheet(theme); - - return ( - - - - ); - }; - - renderSearchBar = (styles) => { - const {formatMessage} = this.context.intl; - const {theme} = this.props; - - return ( - - - - ); - }; - - renderSectionHeader = ({section}) => { - const {intl} = this.context; - const {theme} = this.props; - const styles = getStyleSheet(theme); - const { - defaultMessage, - id - } = section; - - return ( - - - - {intl.formatMessage({id, defaultMessage}).toUpperCase()} - - - - ); - }; - - sort = (a, b) => { - const locale = DeviceInfo.getDeviceLocale().split('-')[0]; - return a.localeCompare(b, locale, {numeric: true}); - }; - - sortDisplayName = (a, b) => { - const locale = DeviceInfo.getDeviceLocale().split('-')[0]; - return a.display_name.localeCompare(b.display_name, locale, {numeric: true}); - }; - - render() { - const {theme, title} = this.props; - const styles = getStyleSheet(theme); - - return ( - - - {this.renderBody(styles)} - - ); - } -} - -const getStyleSheet = makeStyleSheetFromTheme((theme) => { - return { - flex: { - flex: 1 - }, - separatorContainer: { - paddingLeft: 35 - }, - separator: { - backgroundColor: changeOpacity(theme.centerChannelColor, 0.2), - height: 1 - }, - loadingContainer: { - alignItems: 'center', - flex: 1, - justifyContent: 'center' - }, - searchContainer: { - backgroundColor: changeOpacity(theme.centerChannelColor, 0.2), - paddingBottom: 2 - }, - searchBarInput: { - backgroundColor: '#fff', - color: theme.centerChannelColor, - fontSize: 15 - }, - titleContainer: { - height: 30 - }, - title: { - color: changeOpacity(theme.centerChannelColor, 0.6), - fontSize: 15, - lineHeight: 30, - paddingHorizontal: 15 - }, - errorContainer: { - alignItems: 'center', - flex: 1, - justifyContent: 'center', - paddingHorizontal: 15 - }, - error: { - color: theme.errorTextColor, - fontSize: 14 - } - }; -}); diff --git a/share_extension/ios/extension_nav_bar.js b/share_extension/ios/extension_nav_bar.js deleted file mode 100644 index fa3510f21..000000000 --- a/share_extension/ios/extension_nav_bar.js +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React, {PureComponent} from 'react'; -import PropTypes from 'prop-types'; -import {Text, TouchableOpacity, View} from 'react-native'; -import IonIcon from 'react-native-vector-icons/Ionicons'; - -import {emptyFunction} from 'app/utils/general'; -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; - -export default class ExtensionNavBar extends PureComponent { - static propTypes = { - authenticated: PropTypes.bool, - backButton: PropTypes.bool, - leftButtonTitle: PropTypes.string, - onLeftButtonPress: PropTypes.func, - onRightButtonPress: PropTypes.func, - rightButtonTitle: PropTypes.string, - theme: PropTypes.object.isRequired, - title: PropTypes.string - }; - - static defaultProps = { - backButton: false, - onLeftButtonPress: emptyFunction, - title: 'Mattermost' - }; - - renderLeftButton = (styles) => { - const {backButton, leftButtonTitle, onLeftButtonPress} = this.props; - let backComponent; - if (backButton) { - backComponent = ( - - ); - } else if (leftButtonTitle) { - backComponent = ( - - {leftButtonTitle} - - ); - } - - if (backComponent) { - return ( - - {backComponent} - - ); - } - - return ; - }; - - renderRightButton = (styles) => { - const {authenticated, onRightButtonPress, rightButtonTitle} = this.props; - - if (rightButtonTitle && authenticated) { - return ( - - - {rightButtonTitle} - - - ); - } - - return ; - }; - - render() { - const {theme, title} = this.props; - const styles = getStyleSheet(theme); - - return ( - - {this.renderLeftButton(styles)} - - - {title} - - - {this.renderRightButton(styles)} - - ); - } -} - -const getStyleSheet = makeStyleSheetFromTheme((theme) => { - return { - container: { - borderBottomColor: changeOpacity(theme.centerChannelColor, 0.2), - borderBottomWidth: 1, - flexDirection: 'row', - height: 45 - }, - backButtonContainer: { - justifyContent: 'center', - paddingHorizontal: 15, - width: '30%' - }, - titleContainer: { - alignItems: 'center', - flex: 1, - justifyContent: 'center' - }, - backButton: { - color: theme.linkColor, - fontSize: 34 - }, - leftButton: { - color: theme.linkColor, - fontSize: 16 - }, - title: { - fontSize: 17, - fontWeight: '600' - }, - rightButtonContainer: { - alignItems: 'flex-end', - justifyContent: 'center', - paddingHorizontal: 15, - width: '30%' - }, - rightButton: { - color: theme.linkColor, - fontSize: 16, - fontWeight: '600' - } - }; -}); diff --git a/share_extension/ios/extension_post.js b/share_extension/ios/extension_post.js deleted file mode 100644 index 817c1f6bb..000000000 --- a/share_extension/ios/extension_post.js +++ /dev/null @@ -1,758 +0,0 @@ -// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React, {PureComponent} from 'react'; -import PropTypes from 'prop-types'; -import {intlShape} from 'react-intl'; -import { - ActivityIndicator, - Dimensions, - Image, - NativeModules, - ScrollView, - Text, - TextInput, - TouchableHighlight, - View -} from 'react-native'; -import IonIcon from 'react-native-vector-icons/Ionicons'; -import Video from 'react-native-video'; -import LocalAuth from 'react-native-local-auth'; -import RNFetchBlob from 'react-native-fetch-blob'; - -import {Client4} from 'mattermost-redux/client'; -import {getFormattedFileSize, lookupMimeType} from 'mattermost-redux/utils/file_utils'; - -import mattermostBucket from 'app/mattermost_bucket'; -import {generateId} from 'app/utils/file'; -import {wrapWithPreventDoubleTap} from 'app/utils/tap'; -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; -import Config from 'assets/config'; - -import { - ExcelSvg, - GenericSvg, - PdfSvg, - PptSvg, - ZipSvg -} from 'share_extension/common/icons'; - -import ExtensionChannels from './extension_channels'; -import ExtensionNavBar from './extension_nav_bar'; -import ExtensionTeams from './extension_teams'; -import {General} from 'mattermost-redux/constants/index'; - -const ShareExtension = NativeModules.MattermostShare; -const MAX_INPUT_HEIGHT = 95; -const MAX_MESSAGE_LENGTH = 4000; -const MAX_FILE_SIZE = 20 * 1024 * 1024; - -const extensionSvg = { - csv: ExcelSvg, - pdf: PdfSvg, - ppt: PptSvg, - pptx: PptSvg, - xls: ExcelSvg, - xlsx: ExcelSvg, - zip: ZipSvg -}; - -export default class ExtensionPost extends PureComponent { - static propTypes = { - authenticated: PropTypes.bool.isRequired, - entities: PropTypes.object, - navigator: PropTypes.object.isRequired, - onClose: PropTypes.func.isRequired, - theme: PropTypes.object.isRequired - }; - - static contextTypes = { - intl: intlShape - }; - - constructor(props, context) { - super(props, context); - - const {height, width} = Dimensions.get('window'); - const isLandscape = width > height; - - this.state = { - entities: props.entities, - error: null, - files: [], - isLandscape, - totalSize: 0, - value: '', - sending: false - }; - } - - componentWillMount() { - this.loadData(); - } - - componentDidMount() { - this.focusInput(); - } - - componentDidUpdate() { - this.focusInput(); - } - - emmAuthenticationIfNeeded = async () => { - try { - const emmSecured = await mattermostBucket.getPreference('emm', Config.AppGroupId); - if (emmSecured) { - const {intl} = this.context; - await LocalAuth.authenticate({ - reason: intl.formatMessage({ - id: 'mobile.managed.secured_by', - defaultMessage: 'Secured by {vendor}' - }, {emmSecured}), - fallbackToPasscode: true, - suppressEnterPassword: true - }); - } - } catch (error) { - this.props.onClose(); - } - }; - - focusInput = () => { - if (this.input && !this.input.isFocused()) { - this.input.focus(); - } - }; - - getInputRef = (ref) => { - this.input = ref; - }; - - getScrollViewRef = (ref) => { - this.scrollView = ref; - }; - - goToChannels = wrapWithPreventDoubleTap(() => { - const {navigator, theme} = this.props; - const {channel, entities, team} = this.state; - - navigator.push({ - component: ExtensionChannels, - wrapperStyle: { - borderRadius: 10, - backgroundColor: theme.centerChannelBg - }, - passProps: { - currentChannelId: channel.id, - entities, - onSelectChannel: this.selectChannel, - teamId: team.id, - theme, - title: team.display_name - } - }); - }); - - goToTeams = wrapWithPreventDoubleTap(() => { - const {navigator, theme} = this.props; - const {formatMessage} = this.context.intl; - const {team} = this.state; - - navigator.push({ - component: ExtensionTeams, - title: formatMessage({id: 'quick_switch_modal.teams', defaultMessage: 'Teams'}), - wrapperStyle: { - borderRadius: 10, - backgroundColor: theme.centerChannelBg - }, - passProps: { - entities: this.state.entities, - currentTeamId: team.id, - onSelectTeam: this.selectTeam, - theme - } - }); - }); - - handleCancel = wrapWithPreventDoubleTap(() => { - this.props.onClose(); - }); - - handleTextChange = (value) => { - this.setState({value}); - }; - - loadData = async () => { - const {entities} = this.state; - if (this.props.authenticated) { - try { - const {credentials} = entities.general; - const {currentUserId} = entities.users; - const team = entities.teams.teams[entities.teams.currentTeamId]; - const channel = entities.channels.channels[entities.channels.currentChannelId]; - const items = await ShareExtension.data(Config.AppGroupId); - const text = []; - const urls = []; - const files = []; - let totalSize = 0; - - for (let i = 0; i < items.length; i++) { - const item = items[i]; - switch (item.type) { - case 'public.plain-text': - text.push(item.value); - break; - case 'public.url': - urls.push(item.value); - break; - default: { - const fullPath = item.value; - const filePath = fullPath.replace('file://', ''); - const fileSize = await RNFetchBlob.fs.stat(filePath); - const filename = fullPath.replace(/^.*[\\/]/, ''); - const extension = filename.split('.').pop(); - - totalSize += fileSize.size; - files.push({ - extension, - filename, - filePath, - fullPath, - mimeType: lookupMimeType(filename.toLowerCase()), - size: getFormattedFileSize(fileSize), - type: item.type - }); - break; - } - } - } - - let value = text.join('\n'); - if (urls.length) { - value += text.length ? `\n${urls.join('\n')}` : urls.join('\n'); - } - - Client4.setUrl(credentials.url); - Client4.setToken(credentials.token); - Client4.setUserId(currentUserId); - this.setState({channel, files, team, value, totalSize}); - } catch (error) { - this.setState({error}); - } - } - }; - - onLayout = async () => { - const isLandscape = await ShareExtension.getOrientation() === 'LANDSCAPE'; - - if (this.state.isLandscape !== isLandscape) { - if (this.scrollView) { - setTimeout(() => { - this.scrollView.scrollTo({y: 0, animated: false}); - }, 250); - } - this.setState({isLandscape}); - } - }; - - renderBody = (styles) => { - const {formatMessage} = this.context.intl; - const {authenticated, theme} = this.props; - const {error, sending, totalSize, value} = this.state; - - if (sending) { - return ( - - - - {formatMessage({ - id: 'mobile.extension.posting', - defaultMessage: 'Posting...' - })} - - - ); - } - - if (totalSize >= MAX_FILE_SIZE) { - return ( - - - {formatMessage({ - id: 'mobile.extension.max_file_size', - defaultMessage: 'File attachments shared in Mattermost must be less than 20 Mb.' - })} - - - ); - } - - if (authenticated && !error) { - return ( - - - {this.renderFiles(styles)} - - ); - } - - if (error) { - return ( - - - {error.message} - - - ); - } - - return ( - - - {formatMessage({ - id: 'mobile.extension.authentication_required', - defaultMessage: 'Authentication required: Please first login using the app.' - })} - - - ); - }; - - renderChannelButton = (styles) => { - const {formatMessage} = this.context.intl; - const {authenticated, theme} = this.props; - const {channel, sending} = this.state; - const channelName = channel ? channel.display_name : ''; - - if (sending) { - return null; - } - - if (!authenticated) { - return null; - } - - return ( - - - - - {formatMessage({id: 'mobile.share_extension.channel', defaultMessage: 'Channel'})} - - - - - {channelName} - - - - - - - - ); - }; - - renderFiles = (styles) => { - const {files} = this.state; - return files.map((file, index) => { - let component; - - switch (file.type) { - case 'public.image': - component = ( - - - - ); - break; - case 'public.movie': - component = ( - - - ); - break; - case 'public.file-url': { - let SvgIcon = extensionSvg[file.extension]; - if (!SvgIcon) { - SvgIcon = GenericSvg; - } - - component = ( - - - - - - - - ); - break; - } - } - - return ( - - {component} - - {`${file.size} - ${file.filename}`} - - - ); - }); - }; - - renderTeamButton = (styles) => { - const {formatMessage} = this.context.intl; - const {authenticated, theme} = this.props; - const {sending, team} = this.state; - const teamName = team ? team.display_name : ''; - - if (sending) { - return null; - } - - if (!authenticated) { - return null; - } - - return ( - - - - - {formatMessage({id: 'mobile.share_extension.team', defaultMessage: 'Team'})} - - - - - {teamName} - - - - - - - - ); - }; - - selectChannel = (channel) => { - this.setState({channel}); - }; - - selectTeam = (team, channel) => { - this.setState({channel, team}); - - // Update the channels for the team - Client4.getMyChannels(team.id).then((channels) => { - const defaultChannel = channels.find((c) => c.name === General.DEFAULT_CHANNEL && c.team_id === team.id); - this.updateChannelsInEntities(channels); - if (!channel) { - this.setState({channel: defaultChannel}); - } - }).catch((error) => { - this.setState({error}); - }); - }; - - sendMessage = wrapWithPreventDoubleTap(async () => { - const {authenticated, onClose} = this.props; - const {channel, entities, files, value} = this.state; - const {currentUserId} = entities.users; - - // If no text and no files do nothing - if (!value && !files.length) { - return; - } - - if (currentUserId && authenticated) { - await this.emmAuthenticationIfNeeded(); - - try { - // Check to see if the use still belongs to the channel - await Client4.getMyChannelMember(channel.id); - const post = { - user_id: currentUserId, - channel_id: channel.id, - message: value - }; - - const data = { - files, - post, - requestId: generateId() - }; - - this.setState({sending: true}); - onClose(data); - } catch (error) { - this.setState({error}); - setTimeout(() => { - onClose(); - }, 5000); - } - } - }); - - updateChannelsInEntities = (newChannels) => { - const {entities} = this.state; - const newEntities = { - ...entities, - channels: { - ...entities.channels, - channels: {...entities.channels.channels}, - channelsInTeam: {...entities.channels.channelsInTeam} - } - }; - const {channels, channelsInTeam} = newEntities.channels; - - newChannels.forEach((c) => { - channels[c.id] = c; - const channelIdsInTeam = channelsInTeam[c.team_id]; - if (channelIdsInTeam) { - if (!channelIdsInTeam.includes(c.id)) { - channelsInTeam[c.team_id].push(c.id); - } - } else { - channelsInTeam[c.team_id] = [c.id]; - } - }); - - this.setState({entities: newEntities}); - mattermostBucket.writeToFile('entities', JSON.stringify(newEntities), Config.AppGroupId); - }; - - render() { - const {authenticated, theme} = this.props; - const {channel, totalSize, sending} = this.state; - const {formatMessage} = this.context.intl; - const styles = getStyleSheet(theme); - - let postButtonText = formatMessage({id: 'mobile.share_extension.send', defaultMessage: 'Send'}); - if (totalSize >= MAX_FILE_SIZE || sending || !channel) { - postButtonText = null; - } - - return ( - - - {this.renderBody(styles)} - {this.renderTeamButton(styles)} - {this.renderChannelButton(styles)} - - ); - } -} - -const getStyleSheet = makeStyleSheetFromTheme((theme) => { - return { - flex: { - flex: 1 - }, - container: { - flex: 1, - backgroundColor: changeOpacity(theme.centerChannelColor, 0.05) - }, - input: { - color: theme.centerChannelColor, - fontSize: 17, - marginBottom: 5, - width: '100%' - }, - divider: { - backgroundColor: changeOpacity(theme.centerChannelColor, 0.1), - height: 1, - marginVertical: 5, - width: '100%' - }, - scrollView: { - paddingHorizontal: 15 - }, - buttonContainer: { - borderTopColor: changeOpacity(theme.centerChannelColor, 0.2), - borderTopWidth: 1, - height: 45, - paddingHorizontal: 15 - }, - buttonWrapper: { - alignItems: 'center', - flex: 1, - flexDirection: 'row' - }, - buttonLabelContainer: { - flex: 1 - }, - buttonLabel: { - fontSize: 17, - lineHeight: 45 - }, - buttonValueContainer: { - justifyContent: 'flex-end', - flex: 1, - flexDirection: 'row' - }, - buttonValue: { - color: changeOpacity(theme.centerChannelColor, 0.4), - alignSelf: 'flex-end', - fontSize: 17, - lineHeight: 45 - }, - arrowContainer: { - height: 45, - justifyContent: 'center', - marginLeft: 15, - top: 2 - }, - unauthenticatedContainer: { - alignItems: 'center', - flex: 1, - justifyContent: 'center', - paddingHorizontal: 15 - }, - unauthenticated: { - color: theme.errorTextColor, - fontSize: 14 - }, - fileContainer: { - alignItems: 'center', - backgroundColor: theme.centerChannelBg, - borderColor: changeOpacity(theme.centerChannelColor, 0.2), - borderRadius: 4, - borderWidth: 1, - flexDirection: 'row', - height: 48, - marginBottom: 10, - width: '100%' - }, - filename: { - color: changeOpacity(theme.centerChannelColor, 0.5), - fontSize: 13, - flex: 1 - }, - otherContainer: { - borderBottomLeftRadius: 4, - borderTopLeftRadius: 4, - height: 48, - marginRight: 10, - paddingVertical: 10, - width: 38 - }, - otherWrapper: { - borderRightWidth: 1, - borderRightColor: changeOpacity(theme.centerChannelColor, 0.2), - flex: 1 - }, - fileIcon: { - alignItems: 'center', - justifyContent: 'center', - flex: 1 - }, - imageContainer: { - borderBottomLeftRadius: 4, - borderTopLeftRadius: 4, - height: 48, - marginRight: 10, - width: 38 - }, - image: { - alignItems: 'center', - height: 48, - justifyContent: 'center', - overflow: 'hidden', - width: 38 - }, - video: { - backgroundColor: theme.centerChannelBg, - alignItems: 'center', - height: 48, - justifyContent: 'center', - overflow: 'hidden', - width: 38 - }, - sendingContainer: { - alignItems: 'center', - flex: 1, - justifyContent: 'center', - paddingHorizontal: 15 - }, - sendingText: { - color: theme.centerChannelColor, - fontSize: 16, - paddingTop: 10 - } - }; -}); diff --git a/share_extension/ios/extension_team_item.js b/share_extension/ios/extension_team_item.js deleted file mode 100644 index c09d5e4bf..000000000 --- a/share_extension/ios/extension_team_item.js +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React from 'react'; -import PropTypes from 'prop-types'; -import { - Text, - TouchableHighlight, - View -} from 'react-native'; -import IonIcon from 'react-native-vector-icons/Ionicons'; - -import {wrapWithPreventDoubleTap} from 'app/utils/tap'; -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; - -export default class TeamsListItem extends React.PureComponent { - static propTypes = { - currentTeamId: PropTypes.string.isRequired, - onSelectTeam: PropTypes.func.isRequired, - team: PropTypes.object.isRequired, - theme: PropTypes.object.isRequired - }; - - onPress = wrapWithPreventDoubleTap(() => { - const {onSelectTeam, team} = this.props; - onSelectTeam(team); - }); - - render() { - const { - currentTeamId, - team, - theme - } = this.props; - const styles = getStyleSheet(theme); - - let current; - if (team.id === currentTeamId) { - current = ( - - - - ); - } - - const icon = ( - - - {team.display_name.substr(0, 2).toUpperCase()} - - - ); - - return ( - - - - {icon} - - {team.display_name} - - {current} - - - - ); - } -} - -const getStyleSheet = makeStyleSheetFromTheme((theme) => { - return { - container: { - flex: 1, - flexDirection: 'row', - height: 45, - paddingHorizontal: 15 - }, - item: { - alignItems: 'center', - height: 45, - flex: 1, - flexDirection: 'row' - }, - text: { - color: theme.centerChannelColor, - flex: 1, - fontSize: 16, - fontWeight: '600', - lineHeight: 16, - paddingRight: 5 - }, - iconContainer: { - alignItems: 'center', - backgroundColor: theme.linkColor, - borderRadius: 2, - height: 30, - justifyContent: 'center', - width: 30, - marginRight: 10 - }, - icon: { - color: theme.sidebarText, - fontFamily: 'OpenSans', - fontSize: 15, - fontWeight: '600' - }, - checkmarkContainer: { - alignItems: 'flex-end' - }, - checkmark: { - color: theme.linkColor, - fontSize: 16 - } - }; -}); diff --git a/share_extension/ios/extension_teams.js b/share_extension/ios/extension_teams.js deleted file mode 100644 index 485b46740..000000000 --- a/share_extension/ios/extension_teams.js +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React, {PureComponent} from 'react'; -import PropTypes from 'prop-types'; -import {ActivityIndicator, FlatList, Text, View} from 'react-native'; -import DeviceInfo from 'react-native-device-info'; -import {intlShape} from 'react-intl'; - -import {General} from 'mattermost-redux/constants'; -import {getChannelsInTeam} from 'mattermost-redux/selectors/entities/channels'; - -import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; - -import ExtensionNavBar from './extension_nav_bar'; -import ExtensionTeamItem from './extension_team_item'; - -export default class ExtensionTeams extends PureComponent { - static propTypes = { - currentTeamId: PropTypes.string.isRequired, - entities: PropTypes.object, - navigator: PropTypes.object.isRequired, - onSelectTeam: PropTypes.func.isRequired, - theme: PropTypes.object.isRequired - }; - - static contextTypes = { - intl: intlShape - }; - - state = { - defaultChannels: null, - error: null, - myTeams: null - }; - - componentWillMount() { - this.loadTeams(); - } - - goBack = () => { - this.props.navigator.pop(); - }; - - handleSelectTeam = (team) => { - const {defaultChannels} = this.state; - const townSquare = defaultChannels[team.id]; - this.props.onSelectTeam(team, townSquare); - this.goBack(); - }; - - keyExtractor = (item) => item.id; - - loadTeams = async () => { - try { - const defaultChannels = {}; - const {teams, myMembers} = this.props.entities.teams; - const myTeams = []; - const channelsInTeam = getChannelsInTeam({entities: this.props.entities}); - - for (const key in teams) { - if (teams.hasOwnProperty(key)) { - const team = teams[key]; - const belong = myMembers[key]; - if (belong) { - const channelIds = channelsInTeam[key]; - let channels; - if (channelIds) { - channels = channelIds.map((id) => this.props.entities.channels.channels[id]); - defaultChannels[team.id] = channels.find((channel) => channel.name === General.DEFAULT_CHANNEL); - } - - myTeams.push(team); - } - } - } - - this.setState({ - defaultChannels, - myTeams: myTeams.sort(this.sortDisplayName) - }); - } catch (error) { - this.setState({error}); - } - }; - - renderBody = (styles) => { - const {error, myTeams} = this.state; - - if (error) { - return ( - - - {error.message} - - - ); - } - - if (!myTeams) { - return ( - - - - ); - } - - return ( - - ); - }; - - renderItem = ({item}) => { - const {currentTeamId, theme} = this.props; - - return ( - - ); - }; - - renderItemSeparator = () => { - const {theme} = this.props; - const styles = getStyleSheet(theme); - - return ( - - - - ); - }; - - sortDisplayName = (a, b) => { - const locale = DeviceInfo.getDeviceLocale().split('-')[0]; - return a.display_name.localeCompare(b.display_name, locale, {numeric: true}); - }; - - render() { - const {formatMessage} = this.context.intl; - const {theme} = this.props; - const styles = getStyleSheet(theme); - - return ( - - - {this.renderBody(styles)} - - ); - } -} - -const getStyleSheet = makeStyleSheetFromTheme((theme) => { - return { - flex: { - flex: 1 - }, - separatorContainer: { - paddingLeft: 60 - }, - separator: { - backgroundColor: changeOpacity(theme.centerChannelColor, 0.2), - height: 1 - }, - loadingContainer: { - alignItems: 'center', - flex: 1, - justifyContent: 'center' - }, - searchContainer: { - backgroundColor: changeOpacity(theme.centerChannelColor, 0.2), - paddingBottom: 2 - }, - searchBarInput: { - backgroundColor: '#fff', - color: theme.centerChannelColor, - fontSize: 15 - }, - titleContainer: { - height: 30 - }, - title: { - color: changeOpacity(theme.centerChannelColor, 0.6), - fontSize: 15, - lineHeight: 30, - paddingHorizontal: 15 - }, - errorContainer: { - alignItems: 'center', - flex: 1, - justifyContent: 'center', - paddingHorizontal: 15 - }, - error: { - color: theme.errorTextColor, - fontSize: 14 - } - }; -}); diff --git a/share_extension/ios/index.js b/share_extension/ios/index.js deleted file mode 100644 index 86d0081ae..000000000 --- a/share_extension/ios/index.js +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React, {PureComponent} from 'react'; -import {IntlProvider} from 'react-intl'; -import DeviceInfo from 'react-native-device-info'; -import { - Animated, - Dimensions, - NativeModules, - NavigatorIOS, - StyleSheet, - View -} from 'react-native'; - -import {Preferences} from 'mattermost-redux/constants'; - -import {getTranslations} from 'app/i18n'; -import mattermostBucket from 'app/mattermost_bucket'; -import Config from 'assets/config'; - -import ExtensionPost from './extension_post'; - -const {View: AnimatedView} = Animated; -const ShareExtension = NativeModules.MattermostShare; - -export default class SharedApp extends PureComponent { - constructor(props) { - super(props); - - const {height, width} = Dimensions.get('window'); - const isLandscape = width > height; - - this.state = { - backdropOpacity: new Animated.Value(0), - containerOpacity: new Animated.Value(0), - isLandscape - }; - - mattermostBucket.readFromFile('entities', Config.AppGroupId).then((value) => { - this.entities = value; - this.setState({init: true}); - }); - } - - componentDidMount() { - Animated.parallel([ - Animated.timing( - this.state.backdropOpacity, - { - toValue: 0.5, - duration: 100 - }), - Animated.timing( - this.state.containerOpacity, - { - toValue: 1, - duration: 250 - }) - ]).start(); - } - - onClose = (data) => { - ShareExtension.close(data, Config.AppGroupId); - }; - - onLayout = (e) => { - const {height, width} = e.nativeEvent.layout; - const isLandscape = width > height; - if (this.state.isLandscape !== isLandscape) { - this.setState({isLandscape}); - } - }; - - userIsLoggedIn = () => { - return Boolean(this.entities && this.entities.general && this.entities.general.credentials && - this.entities.general.credentials.token && this.entities.general.credentials.url); - }; - - render() { - const {init, isLandscape} = this.state; - - if (!init) { - return null; - } - - const theme = Preferences.THEMES.default; - const locale = DeviceInfo.getDeviceLocale().split('-')[0]; - - const initialRoute = { - component: ExtensionPost, - title: 'Mattermost', - passProps: { - authenticated: this.userIsLoggedIn(), - entities: this.entities, - onClose: this.onClose, - isLandscape, - theme - }, - wrapperStyle: { - borderRadius: 10, - backgroundColor: theme.centerChannelBg - } - }; - - return ( - - - - - - - - - - - ); - } -} - -const styles = StyleSheet.create({ - flex: { - flex: 1 - }, - backdrop: { - position: 'absolute', - flex: 1, - backgroundColor: '#000', - height: '100%', - width: '100%' - }, - wrapper: { - flex: 1, - marginHorizontal: 20 - }, - container: { - backgroundColor: 'white', - borderRadius: 10, - position: 'relative', - width: '100%' - } -});