Browse Source
Bank-1136: APP. Поширення фото/відео/документів з інших додатків у додаток TaskMe у чат Reviewed-on: #27 Co-authored-by: Oksana Stepanenko <oksana.stepanenko@jetup.team> Co-committed-by: Oksana Stepanenko <oksana.stepanenko@jetup.team>change/chat-conversation
33 changed files with 17431 additions and 19223 deletions
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
<?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> |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
<?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>NSExtension</key> |
||||
<dict> |
||||
<key>NSExtensionAttributes</key> |
||||
<dict> |
||||
<key>PHSupportedMediaTypes</key> |
||||
<array> |
||||
<string>Video</string> |
||||
<string>Image</string> |
||||
</array> |
||||
<key>NSExtensionActivationRule</key> |
||||
<dict> |
||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key> |
||||
<integer>100</integer> |
||||
<key>NSExtensionActivationSupportsMovieWithMaxCount</key> |
||||
<integer>100</integer> |
||||
<key>NSExtensionActivationSupportsFileWithMaxCount</key> |
||||
<integer>100</integer> |
||||
</dict> |
||||
</dict> |
||||
<key>NSExtensionMainStoryboard</key> |
||||
<string>MainInterface</string> |
||||
<key>NSExtensionPointIdentifier</key> |
||||
<string>com.apple.share-services</string> |
||||
</dict> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
<?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.app.taskme</string> |
||||
</array> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,338 @@
@@ -0,0 +1,338 @@
|
||||
|
||||
import UIKit |
||||
import Social |
||||
import MobileCoreServices |
||||
import Photos |
||||
|
||||
class ShareViewController: SLComposeServiceViewController { |
||||
// TODO: IMPORTANT: This should be your host app bundle identifier |
||||
let hostAppBundleIdentifier = "com.app.taskme" |
||||
let shareProtocol = "ShareMediaTaskme" //share url protocol (must be unique to your app, suggest using your apple bundle id, ie: `hostAppBundleIdentifier`) |
||||
let sharedKey = "ShareKey" |
||||
var sharedMedia: [SharedMediaFile] = [] |
||||
var sharedText: [String] = [] |
||||
let imageContentType = kUTTypeImage as String |
||||
let videoContentType = kUTTypeMovie as String |
||||
let textContentType = kUTTypeText as String |
||||
let urlContentType = kUTTypeURL as String |
||||
let fileURLType = kUTTypeFileURL as String; |
||||
|
||||
override func isContentValid() -> Bool { |
||||
return true |
||||
} |
||||
|
||||
override func viewDidLoad() { |
||||
super.viewDidLoad(); |
||||
|
||||
if let content = extensionContext!.inputItems[0] as? NSExtensionItem { |
||||
if let contents = content.attachments { |
||||
for (index, attachment) in (contents).enumerated() { |
||||
if attachment.hasItemConformingToTypeIdentifier(imageContentType) { |
||||
handleImages(content: content, attachment: attachment, index: index) |
||||
} else if attachment.hasItemConformingToTypeIdentifier(textContentType) { |
||||
handleText(content: content, attachment: attachment, index: index) |
||||
} else if attachment.hasItemConformingToTypeIdentifier(fileURLType) { |
||||
handleFiles(content: content, attachment: attachment, index: index) |
||||
} else if attachment.hasItemConformingToTypeIdentifier(urlContentType) { |
||||
handleUrl(content: content, attachment: attachment, index: index) |
||||
} else if attachment.hasItemConformingToTypeIdentifier(videoContentType) { |
||||
handleVideos(content: content, attachment: attachment, index: index) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
override func viewDidAppear(_ animated: Bool) { |
||||
super.viewDidAppear(animated) |
||||
} |
||||
|
||||
override func didSelectPost() { |
||||
print("didSelectPost"); |
||||
} |
||||
|
||||
override func configurationItems() -> [Any]! { |
||||
// To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here. |
||||
return [] |
||||
} |
||||
|
||||
private func handleText (content: NSExtensionItem, attachment: NSItemProvider, index: Int) { |
||||
attachment.loadItem(forTypeIdentifier: textContentType, options: nil) { [weak self] data, error in |
||||
|
||||
if error == nil, let item = data as? String, let this = self { |
||||
|
||||
this.sharedText.append(item) |
||||
|
||||
// If this is the last item, save imagesData in userDefaults and redirect to host app |
||||
if index == (content.attachments?.count)! - 1 { |
||||
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)") |
||||
userDefaults?.set(this.sharedText, forKey: this.sharedKey) |
||||
userDefaults?.synchronize() |
||||
this.redirectToHostApp(type: .text) |
||||
} |
||||
|
||||
} else { |
||||
self?.dismissWithError() |
||||
} |
||||
} |
||||
} |
||||
|
||||
private func handleUrl (content: NSExtensionItem, attachment: NSItemProvider, index: Int) { |
||||
attachment.loadItem(forTypeIdentifier: urlContentType, options: nil) { [weak self] data, error in |
||||
|
||||
if error == nil, let item = data as? URL, let this = self { |
||||
|
||||
this.sharedText.append(item.absoluteString) |
||||
|
||||
// If this is the last item, save imagesData in userDefaults and redirect to host app |
||||
if index == (content.attachments?.count)! - 1 { |
||||
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)") |
||||
userDefaults?.set(this.sharedText, forKey: this.sharedKey) |
||||
userDefaults?.synchronize() |
||||
this.redirectToHostApp(type: .text) |
||||
} |
||||
|
||||
} else { |
||||
self?.dismissWithError() |
||||
} |
||||
} |
||||
} |
||||
|
||||
private func handleImages (content: NSExtensionItem, attachment: NSItemProvider, index: Int) { |
||||
attachment.loadItem(forTypeIdentifier: imageContentType, options: nil) { [weak self] data, error in |
||||
|
||||
if error == nil, let url = data as? URL, let this = self { |
||||
// this.redirectToHostApp(type: .media) |
||||
// Always copy |
||||
let fileExtension = this.getExtension(from: url, type: .video) |
||||
let newName = UUID().uuidString |
||||
let newPath = FileManager.default |
||||
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")! |
||||
.appendingPathComponent("\(newName).\(fileExtension)") |
||||
let copied = this.copyFile(at: url, to: newPath) |
||||
if(copied) { |
||||
this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .image)) |
||||
} |
||||
|
||||
// If this is the last item, save imagesData in userDefaults and redirect to host app |
||||
if index == (content.attachments?.count)! - 1 { |
||||
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)") |
||||
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey) |
||||
userDefaults?.synchronize() |
||||
this.redirectToHostApp(type: .media) |
||||
} |
||||
|
||||
} else { |
||||
self?.dismissWithError() |
||||
} |
||||
} |
||||
} |
||||
|
||||
private func handleVideos (content: NSExtensionItem, attachment: NSItemProvider, index: Int) { |
||||
attachment.loadItem(forTypeIdentifier: videoContentType, options:nil) { [weak self] data, error in |
||||
|
||||
if error == nil, let url = data as? URL, let this = self { |
||||
|
||||
// Always copy |
||||
let fileExtension = this.getExtension(from: url, type: .video) |
||||
let newName = UUID().uuidString |
||||
let newPath = FileManager.default |
||||
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")! |
||||
.appendingPathComponent("\(newName).\(fileExtension)") |
||||
let copied = this.copyFile(at: url, to: newPath) |
||||
if(copied) { |
||||
guard let sharedFile = this.getSharedMediaFile(forVideo: newPath) else { |
||||
return |
||||
} |
||||
this.sharedMedia.append(sharedFile) |
||||
} |
||||
|
||||
// If this is the last item, save imagesData in userDefaults and redirect to host app |
||||
if index == (content.attachments?.count)! - 1 { |
||||
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)") |
||||
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey) |
||||
userDefaults?.synchronize() |
||||
this.redirectToHostApp(type: .media) |
||||
} |
||||
|
||||
} else { |
||||
self?.dismissWithError() |
||||
} |
||||
} |
||||
} |
||||
|
||||
private func handleFiles (content: NSExtensionItem, attachment: NSItemProvider, index: Int) { |
||||
attachment.loadItem(forTypeIdentifier: fileURLType, options: nil) { [weak self] data, error in |
||||
|
||||
if error == nil, let url = data as? URL, let this = self { |
||||
|
||||
// Always copy |
||||
let newName = this.getFileName(from :url) |
||||
let newPath = FileManager.default |
||||
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(this.hostAppBundleIdentifier)")! |
||||
.appendingPathComponent("\(newName)") |
||||
let copied = this.copyFile(at: url, to: newPath) |
||||
if (copied) { |
||||
this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .file)) |
||||
} |
||||
|
||||
if index == (content.attachments?.count)! - 1 { |
||||
let userDefaults = UserDefaults(suiteName: "group.\(this.hostAppBundleIdentifier)") |
||||
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey) |
||||
userDefaults?.synchronize() |
||||
this.redirectToHostApp(type: .file) |
||||
} |
||||
|
||||
} else { |
||||
self?.dismissWithError() |
||||
} |
||||
} |
||||
} |
||||
|
||||
private func dismissWithError() { |
||||
print("[ERROR] Error loading data!") |
||||
let alert = UIAlertController(title: "Error", message: "Error loading data", preferredStyle: .alert) |
||||
|
||||
let action = UIAlertAction(title: "Error", style: .cancel) { _ in |
||||
self.dismiss(animated: true, completion: nil) |
||||
} |
||||
|
||||
alert.addAction(action) |
||||
present(alert, animated: true, completion: nil) |
||||
extensionContext!.completeRequest(returningItems: [], completionHandler: nil) |
||||
} |
||||
|
||||
private func redirectToHostApp(type: RedirectType) { |
||||
let url = URL(string: "\(shareProtocol)://dataUrl=\(sharedKey)#\(type)") |
||||
var responder = self as UIResponder? |
||||
let selectorOpenURL = sel_registerName("openURL:") |
||||
|
||||
while (responder != nil) { |
||||
if (responder?.responds(to: selectorOpenURL))! { |
||||
let _ = responder?.perform(selectorOpenURL, with: url) |
||||
} |
||||
responder = responder!.next |
||||
} |
||||
extensionContext!.completeRequest(returningItems: [], completionHandler: nil) |
||||
} |
||||
|
||||
enum RedirectType { |
||||
case media |
||||
case text |
||||
case file |
||||
} |
||||
|
||||
func getExtension(from url: URL, type: SharedMediaType) -> String { |
||||
let parts = url.lastPathComponent.components(separatedBy: ".") |
||||
var ex: String? = nil |
||||
if (parts.count > 1) { |
||||
ex = parts.last |
||||
} |
||||
|
||||
if (ex == nil) { |
||||
switch type { |
||||
case .image: |
||||
ex = "PNG" |
||||
case .video: |
||||
ex = "MP4" |
||||
case .file: |
||||
ex = "TXT" |
||||
} |
||||
} |
||||
return ex ?? "Unknown" |
||||
} |
||||
|
||||
func getFileName(from url: URL) -> String { |
||||
var name = url.lastPathComponent |
||||
|
||||
if (name == "") { |
||||
name = UUID().uuidString + "." + getExtension(from: url, type: .file) |
||||
} |
||||
|
||||
return name |
||||
} |
||||
|
||||
func copyFile(at srcURL: URL, to dstURL: URL) -> Bool { |
||||
do { |
||||
if FileManager.default.fileExists(atPath: dstURL.path) { |
||||
try FileManager.default.removeItem(at: dstURL) |
||||
} |
||||
try FileManager.default.copyItem(at: srcURL, to: dstURL) |
||||
} catch (let error) { |
||||
print("Cannot copy item at \(srcURL) to \(dstURL): \(error)") |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
|
||||
private func getSharedMediaFile(forVideo: URL) -> SharedMediaFile? { |
||||
let asset = AVAsset(url: forVideo) |
||||
let duration = (CMTimeGetSeconds(asset.duration) * 1000).rounded() |
||||
let thumbnailPath = getThumbnailPath(for: forVideo) |
||||
|
||||
if FileManager.default.fileExists(atPath: thumbnailPath.path) { |
||||
return SharedMediaFile(path: forVideo.absoluteString, thumbnail: thumbnailPath.absoluteString, duration: duration, type: .video) |
||||
} |
||||
|
||||
var saved = false |
||||
let assetImgGenerate = AVAssetImageGenerator(asset: asset) |
||||
assetImgGenerate.appliesPreferredTrackTransform = true |
||||
// let scale = UIScreen.main.scale |
||||
assetImgGenerate.maximumSize = CGSize(width: 360, height: 360) |
||||
do { |
||||
let img = try assetImgGenerate.copyCGImage(at: CMTimeMakeWithSeconds(600, preferredTimescale: Int32(1.0)), actualTime: nil) |
||||
try UIImage.pngData(UIImage(cgImage: img))()?.write(to: thumbnailPath) |
||||
saved = true |
||||
} catch { |
||||
saved = false |
||||
} |
||||
|
||||
return saved ? SharedMediaFile(path: forVideo.absoluteString, thumbnail: thumbnailPath.absoluteString, duration: duration, type: .video) : nil |
||||
|
||||
} |
||||
|
||||
private func getThumbnailPath(for url: URL) -> URL { |
||||
let fileName = Data(url.lastPathComponent.utf8).base64EncodedString().replacingOccurrences(of: "==", with: "") |
||||
let path = FileManager.default |
||||
.containerURL(forSecurityApplicationGroupIdentifier: "group.\(hostAppBundleIdentifier)")! |
||||
.appendingPathComponent("\(fileName).jpg") |
||||
return path |
||||
} |
||||
|
||||
class SharedMediaFile: Codable { |
||||
var path: String; // can be image, video or url path. It can also be text content |
||||
var thumbnail: String?; // video thumbnail |
||||
var duration: Double?; // video duration in milliseconds |
||||
var type: SharedMediaType; |
||||
|
||||
|
||||
init(path: String, thumbnail: String?, duration: Double?, type: SharedMediaType) { |
||||
self.path = path |
||||
self.thumbnail = thumbnail |
||||
self.duration = duration |
||||
self.type = type |
||||
} |
||||
|
||||
// Debug method to print out SharedMediaFile details in the console |
||||
func toString() { |
||||
print("[SharedMediaFile] \n\tpath: \(self.path)\n\tthumbnail: \(self.thumbnail)\n\tduration: \(self.duration)\n\ttype: \(self.type)") |
||||
} |
||||
} |
||||
|
||||
enum SharedMediaType: Int, Codable { |
||||
case image |
||||
case video |
||||
case file |
||||
} |
||||
|
||||
func toData(data: [SharedMediaFile]) -> Data { |
||||
let encodedData = try? JSONEncoder().encode(data) |
||||
return encodedData! |
||||
} |
||||
} |
||||
|
||||
extension Array { |
||||
subscript (safe index: UInt) -> Element? { |
||||
return Int(index) < count ? self[Int(index)] : nil |
||||
} |
||||
} |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
<?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>aps-environment</key> |
||||
<string>development</string> |
||||
<key>com.apple.developer.associated-domains</key> |
||||
<array> |
||||
<string>applinks:example.com</string> |
||||
</array> |
||||
<key>com.apple.security.application-groups</key> |
||||
<array> |
||||
<string>group.com.app.taskme.onesignal</string> |
||||
<string>group.com.app.taskme</string> |
||||
</array> |
||||
</dict> |
||||
</plist> |
@ -0,0 +1,200 @@
@@ -0,0 +1,200 @@
|
||||
import React, { FC, useEffect, useMemo } from 'react' |
||||
import { |
||||
$size, |
||||
FooterWithBtn, |
||||
IRouteParams, |
||||
ISharedFile, |
||||
NotFound, |
||||
RouteKey, |
||||
ScreenLayout, |
||||
SearchWithBtn, |
||||
appEvents, |
||||
useTheme, |
||||
} from '@/shared' |
||||
import { FlatList, StyleSheet, View } from 'react-native' |
||||
import { SelectChatListItem, SelectedChatsRow } from '../components' |
||||
import { PartialTheme } from '@/shared/themes/interfaces' |
||||
import { |
||||
alertFileSizeExceeded, |
||||
checkFileSize, |
||||
isCloseToBottom, |
||||
} from '@/shared/helpers' |
||||
import _ from 'lodash' |
||||
import { useSelectedChats } from '../hooks' |
||||
import { fsService } from '@/services/system' |
||||
import { chatMessagesService } from '@/services/domain' |
||||
import { useSelector } from 'react-redux' |
||||
import { getFilesConfig } from '@/store/shared' |
||||
import { ISendFileMessage } from '@/api/chat-messages/requests.interfaces' |
||||
|
||||
interface IProps extends IRouteParams { |
||||
route: { |
||||
params: { |
||||
files: ISharedFile[] |
||||
} |
||||
} |
||||
} |
||||
|
||||
export const SendSharedFilesScreen: FC<IProps> = ({ |
||||
navigation, |
||||
route: { |
||||
params: { files }, |
||||
}, |
||||
}) => { |
||||
const { styles } = useTheme(createStyles) |
||||
const { chatFilesSize, chatVideosSize } = useSelector(getFilesConfig) |
||||
|
||||
const { |
||||
chats, |
||||
selectedChats, |
||||
selectAll, |
||||
selectChat, |
||||
unselectChat, |
||||
searchString, |
||||
setSearchString, |
||||
loadMore, |
||||
setSelectedChats, |
||||
} = useSelectedChats() |
||||
|
||||
const renderSelectedChatsRow = useMemo(() => { |
||||
return ( |
||||
<SelectedChatsRow |
||||
selectedChats={selectedChats} |
||||
onPressRemove={id => { |
||||
unselectChat(id) |
||||
}} |
||||
/> |
||||
) |
||||
}, [selectedChats]) |
||||
|
||||
useEffect(() => { |
||||
setSelectedChats([]) |
||||
}, [files]) |
||||
|
||||
const send = async () => { |
||||
const chatsIds = selectedChats.map(it => it.id) |
||||
if (_.isEmpty(chatsIds)) return |
||||
|
||||
try { |
||||
const filesStats = [] |
||||
for await (const file of files) { |
||||
const fileStat = await fsService.getSharedFileStat(file) |
||||
|
||||
if (fileStat) filesStats.push(fileStat) |
||||
} |
||||
|
||||
const { allowed, exceeded } = checkFileSize( |
||||
filesStats, |
||||
chatFilesSize, |
||||
chatVideosSize, |
||||
) |
||||
|
||||
if (!_.isEmpty(exceeded)) |
||||
alertFileSizeExceeded(exceeded, chatFilesSize, chatVideosSize) |
||||
if (_.isEmpty(allowed)) return |
||||
|
||||
for await (const chat of selectedChats) { |
||||
try { |
||||
await chatMessagesService.storeMessageByType( |
||||
allowed.map(it => { |
||||
const dataToStore: ISendFileMessage = { |
||||
file: it, |
||||
chatId: chat.id, |
||||
fileName: it.name, |
||||
} |
||||
return dataToStore |
||||
}), |
||||
) |
||||
} catch (e) { |
||||
console.log('Error on send shared file to chat', chat.id, e) |
||||
} |
||||
} |
||||
|
||||
navigation.navigate(RouteKey.Chats) |
||||
} catch (e) { |
||||
appEvents.emit('openInfoModal', { |
||||
title: 'Виникла помилка, ', |
||||
message: 'спробуйте будь-ласка пізніше', |
||||
pressButtonText: 'Продовжити', |
||||
}) |
||||
} |
||||
} |
||||
|
||||
return ( |
||||
<ScreenLayout |
||||
header={{ |
||||
title: `Виберіть бесіди`, |
||||
goBack: () => { |
||||
navigation.goBack() |
||||
}, |
||||
style: { |
||||
marginBottom: $size(20, 18), |
||||
paddingTop: $size(10, 10), |
||||
}, |
||||
}} |
||||
footer={() => <FooterWithBtn btnTitle="Надіслати" onPress={send} />} |
||||
horizontalPadding={0}> |
||||
{selectedChats.length ? renderSelectedChatsRow : null} |
||||
|
||||
<View style={styles.container}> |
||||
<SearchWithBtn |
||||
containerStyle={styles.searchContainer} |
||||
searchValue={searchString} |
||||
btnStyle={styles.searchBtn} |
||||
btnTitleStyle={styles.searchBtnTitle} |
||||
borderBottom={false} |
||||
onChange={setSearchString} |
||||
onPressBtn={selectAll} |
||||
btnTitle="Вибрати всі" |
||||
placeholder="Знайдіть бесіду" |
||||
/> |
||||
<FlatList |
||||
data={chats} |
||||
contentContainerStyle={styles.contentContainerStyle} |
||||
initialNumToRender={10} |
||||
onScroll={({ nativeEvent }) => { |
||||
if (isCloseToBottom(nativeEvent)) loadMore() |
||||
}} |
||||
keyExtractor={item => `${item.id}`} |
||||
renderItem={({ item }) => ( |
||||
<SelectChatListItem |
||||
previewUri={item.previewUrl} |
||||
name={item.name} |
||||
isChecked={item.isSelected} |
||||
onSelectItem={() => |
||||
!item.isSelected |
||||
? selectChat(item.id) |
||||
: unselectChat(item.id) |
||||
} |
||||
isDisabled={item.isDisabled} |
||||
/> |
||||
)} |
||||
ListEmptyComponent={<NotFound text="Бесіди не знайдені" />} |
||||
/> |
||||
</View> |
||||
</ScreenLayout> |
||||
) |
||||
} |
||||
const createStyles = (theme: PartialTheme) => |
||||
StyleSheet.create({ |
||||
container: { |
||||
flex: 1, |
||||
flexGrow: 300, |
||||
}, |
||||
searchContainer: { |
||||
marginBottom: $size(10), |
||||
}, |
||||
contentContainerStyle: { |
||||
paddingHorizontal: $size(18, 16), |
||||
minHeight: '60%', |
||||
}, |
||||
smallContainer: { |
||||
maxHeight: '52%', |
||||
}, |
||||
searchBtn: { |
||||
backgroundColor: theme?.chats?.selectItems?.$addAllBtnBg, |
||||
}, |
||||
searchBtnTitle: { |
||||
color: theme?.chats?.selectItems?.$addAllBtnTxt, |
||||
}, |
||||
}) |
@ -1,31 +0,0 @@
@@ -1,31 +0,0 @@
|
||||
import { NavigationModuleKey } from '@/shared/enums' |
||||
import { SetNavigationModule } from '@/store/shared' |
||||
import { simpleDispatch } from '@/store/store-helpers' |
||||
// import { checkInternetConnection } from 'react-native-offline'
|
||||
|
||||
const TEST_CONNECTION_LINK = 'https://www.google.com/' |
||||
|
||||
const init = async (): Promise<boolean> => { |
||||
// const isConnected = await checkInternetConnection(
|
||||
// TEST_CONNECTION_LINK,
|
||||
// 3000,
|
||||
// false,
|
||||
// )
|
||||
|
||||
// if (!isConnected) onOffline()
|
||||
|
||||
// return isConnected
|
||||
return true |
||||
} |
||||
|
||||
// const onOffline = () => {
|
||||
// simpleDispatch(
|
||||
// new SetNavigationModule({
|
||||
// module: NavigationModuleKey.NoInternetConnection,
|
||||
// }),
|
||||
// )
|
||||
// }
|
||||
|
||||
export const networkService = { |
||||
init, |
||||
} |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
export * from './mime-types.config' |
@ -0,0 +1,607 @@
@@ -0,0 +1,607 @@
|
||||
export const mimeTypes = { |
||||
'.323': 'text/h323', |
||||
'.3g2': 'video/3gpp2', |
||||
'.3gp': 'video/3gpp', |
||||
'.3gp2': 'video/3gpp2', |
||||
'.3gpp': 'video/3gpp', |
||||
'.7z': 'application/x-7z-compressed', |
||||
'.aa': 'audio/audible', |
||||
'.AAC': 'audio/aac', |
||||
'.aaf': 'application/octet-stream', |
||||
'.aax': 'audio/vnd.audible.aax', |
||||
'.ac3': 'audio/ac3', |
||||
'.aca': 'application/octet-stream', |
||||
'.accda': 'application/msaccess.addin', |
||||
'.accdb': 'application/msaccess', |
||||
'.accdc': 'application/msaccess.cab', |
||||
'.accde': 'application/msaccess', |
||||
'.accdr': 'application/msaccess.runtime', |
||||
'.accdt': 'application/msaccess', |
||||
'.accdw': 'application/msaccess.webapplication', |
||||
'.accft': 'application/msaccess.ftemplate', |
||||
'.acx': 'application/internet-property-stream', |
||||
'.AddIn': 'text/xml', |
||||
'.ade': 'application/msaccess', |
||||
'.adobebridge': 'application/x-bridge-url', |
||||
'.adp': 'application/msaccess', |
||||
'.ADT': 'audio/vnd.dlna.adts', |
||||
'.ADTS': 'audio/aac', |
||||
'.afm': 'application/octet-stream', |
||||
'.ai': 'application/postscript', |
||||
'.aif': 'audio/aiff', |
||||
'.aifc': 'audio/aiff', |
||||
'.aiff': 'audio/aiff', |
||||
'.air': 'application/vnd.adobe.air-application-installer-package+zip', |
||||
'.amc': 'application/mpeg', |
||||
'.anx': 'application/annodex', |
||||
'.apk': 'application/vnd.android.package-archive', |
||||
'.application': 'application/x-ms-application', |
||||
'.art': 'image/x-jg', |
||||
'.asa': 'application/xml', |
||||
'.asax': 'application/xml', |
||||
'.ascx': 'application/xml', |
||||
'.asd': 'application/octet-stream', |
||||
'.asf': 'video/x-ms-asf', |
||||
'.ashx': 'application/xml', |
||||
'.asi': 'application/octet-stream', |
||||
'.asm': 'text/plain', |
||||
'.asmx': 'application/xml', |
||||
'.aspx': 'application/xml', |
||||
'.asr': 'video/x-ms-asf', |
||||
'.asx': 'video/x-ms-asf', |
||||
'.atom': 'application/atom+xml', |
||||
'.au': 'audio/basic', |
||||
'.avi': 'video/x-msvideo', |
||||
'.axa': 'audio/annodex', |
||||
'.axs': 'application/olescript', |
||||
'.axv': 'video/annodex', |
||||
'.bas': 'text/plain', |
||||
'.bcpio': 'application/x-bcpio', |
||||
'.bin': 'application/octet-stream', |
||||
'.bmp': 'image/bmp', |
||||
'.c': 'text/plain', |
||||
'.cab': 'application/octet-stream', |
||||
'.caf': 'audio/x-caf', |
||||
'.calx': 'application/vnd.ms-office.calx', |
||||
'.cat': 'application/vnd.ms-pki.seccat', |
||||
'.cc': 'text/plain', |
||||
'.cd': 'text/plain', |
||||
'.cdda': 'audio/aiff', |
||||
'.cdf': 'application/x-cdf', |
||||
'.cer': 'application/x-x509-ca-cert', |
||||
'.cfg': 'text/plain', |
||||
'.chm': 'application/octet-stream', |
||||
'.class': 'application/x-java-applet', |
||||
'.clp': 'application/x-msclip', |
||||
'.cmd': 'text/plain', |
||||
'.cmx': 'image/x-cmx', |
||||
'.cnf': 'text/plain', |
||||
'.cod': 'image/cis-cod', |
||||
'.config': 'application/xml', |
||||
'.contact': 'text/x-ms-contact', |
||||
'.coverage': 'application/xml', |
||||
'.cpio': 'application/x-cpio', |
||||
'.cpp': 'text/plain', |
||||
'.crd': 'application/x-mscardfile', |
||||
'.crl': 'application/pkix-crl', |
||||
'.crt': 'application/x-x509-ca-cert', |
||||
'.cs': 'text/plain', |
||||
'.csdproj': 'text/plain', |
||||
'.csh': 'application/x-csh', |
||||
'.csproj': 'text/plain', |
||||
'.css': 'text/css', |
||||
'.csv': 'text/csv', |
||||
'.cur': 'application/octet-stream', |
||||
'.cxx': 'text/plain', |
||||
'.dat': 'application/octet-stream', |
||||
'.datasource': 'application/xml', |
||||
'.dbproj': 'text/plain', |
||||
'.dcr': 'application/x-director', |
||||
'.def': 'text/plain', |
||||
'.deploy': 'application/octet-stream', |
||||
'.der': 'application/x-x509-ca-cert', |
||||
'.dgml': 'application/xml', |
||||
'.dib': 'image/bmp', |
||||
'.dif': 'video/x-dv', |
||||
'.dir': 'application/x-director', |
||||
'.disco': 'text/xml', |
||||
'.divx': 'video/divx', |
||||
'.dll': 'application/x-msdownload', |
||||
'.dll.config': 'text/xml', |
||||
'.dlm': 'text/dlm', |
||||
'.doc': 'application/msword', |
||||
'.docm': 'application/vnd.ms-word.document.macroEnabled.12', |
||||
'.docx': |
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document', |
||||
'.dot': 'application/msword', |
||||
'.dotm': 'application/vnd.ms-word.template.macroEnabled.12', |
||||
'.dotx': |
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.template', |
||||
'.dsp': 'application/octet-stream', |
||||
'.dsw': 'text/plain', |
||||
'.dtd': 'text/xml', |
||||
'.dtsConfig': 'text/xml', |
||||
'.dv': 'video/x-dv', |
||||
'.dvi': 'application/x-dvi', |
||||
'.dwf': 'drawing/x-dwf', |
||||
'.dwp': 'application/octet-stream', |
||||
'.dxr': 'application/x-director', |
||||
'.eml': 'message/rfc822', |
||||
'.emz': 'application/octet-stream', |
||||
'.eot': 'application/vnd.ms-fontobject', |
||||
'.eps': 'application/postscript', |
||||
'.etl': 'application/etl', |
||||
'.etx': 'text/x-setext', |
||||
'.evy': 'application/envoy', |
||||
'.exe': 'application/octet-stream', |
||||
'.exe.config': 'text/xml', |
||||
'.fdf': 'application/vnd.fdf', |
||||
'.fif': 'application/fractals', |
||||
'.filters': 'application/xml', |
||||
'.fla': 'application/octet-stream', |
||||
'.flac': 'audio/flac', |
||||
'.flr': 'x-world/x-vrml', |
||||
'.flv': 'video/x-flv', |
||||
'.fsscript': 'application/fsharp-script', |
||||
'.fsx': 'application/fsharp-script', |
||||
'.generictest': 'application/xml', |
||||
'.gif': 'image/gif', |
||||
'.gpx': 'application/gpx+xml', |
||||
'.group': 'text/x-ms-group', |
||||
'.gsm': 'audio/x-gsm', |
||||
'.gtar': 'application/x-gtar', |
||||
'.gz': 'application/x-gzip', |
||||
'.h': 'text/plain', |
||||
'.hdf': 'application/x-hdf', |
||||
'.hdml': 'text/x-hdml', |
||||
'.hhc': 'application/x-oleobject', |
||||
'.hhk': 'application/octet-stream', |
||||
'.hhp': 'application/octet-stream', |
||||
'.hlp': 'application/winhlp', |
||||
'.hpp': 'text/plain', |
||||
'.hqx': 'application/mac-binhex40', |
||||
'.hta': 'application/hta', |
||||
'.htc': 'text/x-component', |
||||
'.htm': 'text/html', |
||||
'.html': 'text/html', |
||||
'.htt': 'text/webviewhtml', |
||||
'.hxa': 'application/xml', |
||||
'.hxc': 'application/xml', |
||||
'.hxd': 'application/octet-stream', |
||||
'.hxe': 'application/xml', |
||||
'.hxf': 'application/xml', |
||||
'.hxh': 'application/octet-stream', |
||||
'.hxi': 'application/octet-stream', |
||||
'.hxk': 'application/xml', |
||||
'.hxq': 'application/octet-stream', |
||||
'.hxr': 'application/octet-stream', |
||||
'.hxs': 'application/octet-stream', |
||||
'.hxt': 'text/html', |
||||
'.hxv': 'application/xml', |
||||
'.hxw': 'application/octet-stream', |
||||
'.hxx': 'text/plain', |
||||
'.i': 'text/plain', |
||||
'.ico': 'image/x-icon', |
||||
'.ics': 'application/octet-stream', |
||||
'.idl': 'text/plain', |
||||
'.ief': 'image/ief', |
||||
'.iii': 'application/x-iphone', |
||||
'.inc': 'text/plain', |
||||
'.inf': 'application/octet-stream', |
||||
'.ini': 'text/plain', |
||||
'.inl': 'text/plain', |
||||
'.ins': 'application/x-internet-signup', |
||||
'.ipa': 'application/x-itunes-ipa', |
||||
'.ipg': 'application/x-itunes-ipg', |
||||
'.ipproj': 'text/plain', |
||||
'.ipsw': 'application/x-itunes-ipsw', |
||||
'.iqy': 'text/x-ms-iqy', |
||||
'.isp': 'application/x-internet-signup', |
||||
'.ite': 'application/x-itunes-ite', |
||||
'.itlp': 'application/x-itunes-itlp', |
||||
'.itms': 'application/x-itunes-itms', |
||||
'.itpc': 'application/x-itunes-itpc', |
||||
'.IVF': 'video/x-ivf', |
||||
'.jar': 'application/java-archive', |
||||
'.java': 'application/octet-stream', |
||||
'.jck': 'application/liquidmotion', |
||||
'.jcz': 'application/liquidmotion', |
||||
'.jfif': 'image/pjpeg', |
||||
'.jnlp': 'application/x-java-jnlp-file', |
||||
'.jpb': 'application/octet-stream', |
||||
'.jpe': 'image/jpeg', |
||||
'.jpeg': 'image/jpeg', |
||||
'.jpg': 'image/jpeg', |
||||
'.js': 'application/javascript', |
||||
'.json': 'application/json', |
||||
'.jsx': 'text/jscript', |
||||
'.jsxbin': 'text/plain', |
||||
'.latex': 'application/x-latex', |
||||
'.library-ms': 'application/windows-library+xml', |
||||
'.lit': 'application/x-ms-reader', |
||||
'.loadtest': 'application/xml', |
||||
'.lpk': 'application/octet-stream', |
||||
'.lsf': 'video/x-la-asf', |
||||
'.lst': 'text/plain', |
||||
'.lsx': 'video/x-la-asf', |
||||
'.lzh': 'application/octet-stream', |
||||
'.m13': 'application/x-msmediaview', |
||||
'.m14': 'application/x-msmediaview', |
||||
'.m1v': 'video/mpeg', |
||||
'.m2t': 'video/vnd.dlna.mpeg-tts', |
||||
'.m2ts': 'video/vnd.dlna.mpeg-tts', |
||||
'.m2v': 'video/mpeg', |
||||
'.m3u': 'audio/x-mpegurl', |
||||
'.m3u8': 'audio/x-mpegurl', |
||||
'.m4a': 'audio/m4a', |
||||
'.m4b': 'audio/m4b', |
||||
'.m4p': 'audio/m4p', |
||||
'.m4r': 'audio/x-m4r', |
||||
'.m4v': 'video/x-m4v', |
||||
'.mac': 'image/x-macpaint', |
||||
'.mak': 'text/plain', |
||||
'.man': 'application/x-troff-man', |
||||
'.manifest': 'application/x-ms-manifest', |
||||
'.map': 'text/plain', |
||||
'.master': 'application/xml', |
||||
'.mda': 'application/msaccess', |
||||
'.mdb': 'application/x-msaccess', |
||||
'.mde': 'application/msaccess', |
||||
'.mdp': 'application/octet-stream', |
||||
'.me': 'application/x-troff-me', |
||||
'.mfp': 'application/x-shockwave-flash', |
||||
'.mht': 'message/rfc822', |
||||
'.mhtml': 'message/rfc822', |
||||
'.mid': 'audio/mid', |
||||
'.midi': 'audio/mid', |
||||
'.mix': 'application/octet-stream', |
||||
'.mk': 'text/plain', |
||||
'.mmf': 'application/x-smaf', |
||||
'.mno': 'text/xml', |
||||
'.mny': 'application/x-msmoney', |
||||
'.mod': 'video/mpeg', |
||||
'.mov': 'video/quicktime', |
||||
'.movie': 'video/x-sgi-movie', |
||||
'.mp2': 'video/mpeg', |
||||
'.mp2v': 'video/mpeg', |
||||
'.mp3': 'audio/mpeg', |
||||
'.mp4': 'video/mp4', |
||||
'.mp4v': 'video/mp4', |
||||
'.mpa': 'video/mpeg', |
||||
'.mpe': 'video/mpeg', |
||||
'.mpeg': 'video/mpeg', |
||||
'.mpf': 'application/vnd.ms-mediapackage', |
||||
'.mpg': 'video/mpeg', |
||||
'.mpp': 'application/vnd.ms-project', |
||||
'.mpv2': 'video/mpeg', |
||||
'.mqv': 'video/quicktime', |
||||
'.ms': 'application/x-troff-ms', |
||||
'.msi': 'application/octet-stream', |
||||
'.mso': 'application/octet-stream', |
||||
'.mts': 'video/vnd.dlna.mpeg-tts', |
||||
'.mtx': 'application/xml', |
||||
'.mvb': 'application/x-msmediaview', |
||||
'.mvc': 'application/x-miva-compiled', |
||||
'.mxp': 'application/x-mmxp', |
||||
'.nc': 'application/x-netcdf', |
||||
'.nsc': 'video/x-ms-asf', |
||||
'.nws': 'message/rfc822', |
||||
'.ocx': 'application/octet-stream', |
||||
'.oda': 'application/oda', |
||||
'.odb': 'application/vnd.oasis.opendocument.database', |
||||
'.odc': 'application/vnd.oasis.opendocument.chart', |
||||
'.odf': 'application/vnd.oasis.opendocument.formula', |
||||
'.odg': 'application/vnd.oasis.opendocument.graphics', |
||||
'.odh': 'text/plain', |
||||
'.odi': 'application/vnd.oasis.opendocument.image', |
||||
'.odl': 'text/plain', |
||||
'.odm': 'application/vnd.oasis.opendocument.text-master', |
||||
'.odp': 'application/vnd.oasis.opendocument.presentation', |
||||
'.ods': 'application/vnd.oasis.opendocument.spreadsheet', |
||||
'.odt': 'application/vnd.oasis.opendocument.text', |
||||
'.oga': 'audio/ogg', |
||||
'.ogg': 'audio/ogg', |
||||
'.ogv': 'video/ogg', |
||||
'.ogx': 'application/ogg', |
||||
'.one': 'application/onenote', |
||||
'.onea': 'application/onenote', |
||||
'.onepkg': 'application/onenote', |
||||
'.onetmp': 'application/onenote', |
||||
'.onetoc': 'application/onenote', |
||||
'.onetoc2': 'application/onenote', |
||||
'.opus': 'audio/ogg', |
||||
'.orderedtest': 'application/xml', |
||||
'.osdx': 'application/opensearchdescription+xml', |
||||
'.otf': 'application/font-sfnt', |
||||
'.otg': 'application/vnd.oasis.opendocument.graphics-template', |
||||
'.oth': 'application/vnd.oasis.opendocument.text-web', |
||||
'.otp': 'application/vnd.oasis.opendocument.presentation-template', |
||||
'.ots': 'application/vnd.oasis.opendocument.spreadsheet-template', |
||||
'.ott': 'application/vnd.oasis.opendocument.text-template', |
||||
'.oxt': 'application/vnd.openofficeorg.extension', |
||||
'.p10': 'application/pkcs10', |
||||
'.p12': 'application/x-pkcs12', |
||||
'.p7b': 'application/x-pkcs7-certificates', |
||||
'.p7c': 'application/pkcs7-mime', |
||||
'.p7m': 'application/pkcs7-mime', |
||||
'.p7r': 'application/x-pkcs7-certreqresp', |
||||
'.p7s': 'application/pkcs7-signature', |
||||
'.pbm': 'image/x-portable-bitmap', |
||||
'.pcast': 'application/x-podcast', |
||||
'.pct': 'image/pict', |
||||
'.pcx': 'application/octet-stream', |
||||
'.pcz': 'application/octet-stream', |
||||
'.pdf': 'application/pdf', |
||||
'.pfb': 'application/octet-stream', |
||||
'.pfm': 'application/octet-stream', |
||||
'.pfx': 'application/x-pkcs12', |
||||
'.pgm': 'image/x-portable-graymap', |
||||
'.pic': 'image/pict', |
||||
'.pict': 'image/pict', |
||||
'.pkgdef': 'text/plain', |
||||
'.pkgundef': 'text/plain', |
||||
'.pko': 'application/vnd.ms-pki.pko', |
||||
'.pls': 'audio/scpls', |
||||
'.pma': 'application/x-perfmon', |
||||
'.pmc': 'application/x-perfmon', |
||||
'.pml': 'application/x-perfmon', |
||||
'.pmr': 'application/x-perfmon', |
||||
'.pmw': 'application/x-perfmon', |
||||
'.png': 'image/png', |
||||
'.pnm': 'image/x-portable-anymap', |
||||
'.pnt': 'image/x-macpaint', |
||||
'.pntg': 'image/x-macpaint', |
||||
'.pnz': 'image/png', |
||||
'.pot': 'application/vnd.ms-powerpoint', |
||||
'.potm': 'application/vnd.ms-powerpoint.template.macroEnabled.12', |
||||
'.potx': |
||||
'application/vnd.openxmlformats-officedocument.presentationml.template', |
||||
'.ppa': 'application/vnd.ms-powerpoint', |
||||
'.ppam': 'application/vnd.ms-powerpoint.addin.macroEnabled.12', |
||||
'.ppm': 'image/x-portable-pixmap', |
||||
'.pps': 'application/vnd.ms-powerpoint', |
||||
'.ppsm': 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', |
||||
'.ppsx': |
||||
'application/vnd.openxmlformats-officedocument.presentationml.slideshow', |
||||
'.ppt': 'application/vnd.ms-powerpoint', |
||||
'.pptm': 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', |
||||
'.pptx': |
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation', |
||||
'.prf': 'application/pics-rules', |
||||
'.prm': 'application/octet-stream', |
||||
'.prx': 'application/octet-stream', |
||||
'.ps': 'application/postscript', |
||||
'.psc1': 'application/PowerShell', |
||||
'.psd': 'application/octet-stream', |
||||
'.psess': 'application/xml', |
||||
'.psm': 'application/octet-stream', |
||||
'.psp': 'application/octet-stream', |
||||
'.pub': 'application/x-mspublisher', |
||||
'.pwz': 'application/vnd.ms-powerpoint', |
||||
'.qht': 'text/x-html-insertion', |
||||
'.qhtm': 'text/x-html-insertion', |
||||
'.qt': 'video/quicktime', |
||||
'.qti': 'image/x-quicktime', |
||||
'.qtif': 'image/x-quicktime', |
||||
'.qtl': 'application/x-quicktimeplayer', |
||||
'.qxd': 'application/octet-stream', |
||||
'.ra': 'audio/x-pn-realaudio', |
||||
'.ram': 'audio/x-pn-realaudio', |
||||
'.rar': 'application/x-rar-compressed', |
||||
'.ras': 'image/x-cmu-raster', |
||||
'.rat': 'application/rat-file', |
||||
'.rc': 'text/plain', |
||||
'.rc2': 'text/plain', |
||||
'.rct': 'text/plain', |
||||
'.rdlc': 'application/xml', |
||||
'.reg': 'text/plain', |
||||
'.resx': 'application/xml', |
||||
'.rf': 'image/vnd.rn-realflash', |
||||
'.rgb': 'image/x-rgb', |
||||
'.rgs': 'text/plain', |
||||
'.rm': 'application/vnd.rn-realmedia', |
||||
'.rmi': 'audio/mid', |
||||
'.rmp': 'application/vnd.rn-rn_music_package', |
||||
'.roff': 'application/x-troff', |
||||
'.rpm': 'audio/x-pn-realaudio-plugin', |
||||
'.rqy': 'text/x-ms-rqy', |
||||
'.rtf': 'application/rtf', |
||||
'.rtx': 'text/richtext', |
||||
'.ruleset': 'application/xml', |
||||
'.s': 'text/plain', |
||||
'.safariextz': 'application/x-safari-safariextz', |
||||
'.scd': 'application/x-msschedule', |
||||
'.scr': 'text/plain', |
||||
'.sct': 'text/scriptlet', |
||||
'.sd2': 'audio/x-sd2', |
||||
'.sdp': 'application/sdp', |
||||
'.sea': 'application/octet-stream', |
||||
'.searchConnector-ms': 'application/windows-search-connector+xml', |
||||
'.setpay': 'application/set-payment-initiation', |
||||
'.setreg': 'application/set-registration-initiation', |
||||
'.settings': 'application/xml', |
||||
'.sgimb': 'application/x-sgimb', |
||||
'.sgml': 'text/sgml', |
||||
'.sh': 'application/x-sh', |
||||
'.shar': 'application/x-shar', |
||||
'.shtml': 'text/html', |
||||
'.sit': 'application/x-stuffit', |
||||
'.sitemap': 'application/xml', |
||||
'.skin': 'application/xml', |
||||
'.sldm': 'application/vnd.ms-powerpoint.slide.macroEnabled.12', |
||||
'.sldx': |
||||
'application/vnd.openxmlformats-officedocument.presentationml.slide', |
||||
'.slk': 'application/vnd.ms-excel', |
||||
'.sln': 'text/plain', |
||||
'.slupkg-ms': 'application/x-ms-license', |
||||
'.smd': 'audio/x-smd', |
||||
'.smi': 'application/octet-stream', |
||||
'.smx': 'audio/x-smd', |
||||
'.smz': 'audio/x-smd', |
||||
'.snd': 'audio/basic', |
||||
'.snippet': 'application/xml', |
||||
'.snp': 'application/octet-stream', |
||||
'.sol': 'text/plain', |
||||
'.sor': 'text/plain', |
||||
'.spc': 'application/x-pkcs7-certificates', |
||||
'.spl': 'application/futuresplash', |
||||
'.spx': 'audio/ogg', |
||||
'.src': 'application/x-wais-source', |
||||
'.srf': 'text/plain', |
||||
'.SSISDeploymentManifest': 'text/xml', |
||||
'.ssm': 'application/streamingmedia', |
||||
'.sst': 'application/vnd.ms-pki.certstore', |
||||
'.stl': 'application/vnd.ms-pki.stl', |
||||
'.sv4cpio': 'application/x-sv4cpio', |
||||
'.sv4crc': 'application/x-sv4crc', |
||||
'.svc': 'application/xml', |
||||
'.svg': 'image/svg+xml', |
||||
'.swf': 'application/x-shockwave-flash', |
||||
'.step': 'application/step', |
||||
'.stp': 'application/step', |
||||
'.t': 'application/x-troff', |
||||
'.tar': 'application/x-tar', |
||||
'.tcl': 'application/x-tcl', |
||||
'.testrunconfig': 'application/xml', |
||||
'.testsettings': 'application/xml', |
||||
'.tex': 'application/x-tex', |
||||
'.texi': 'application/x-texinfo', |
||||
'.texinfo': 'application/x-texinfo', |
||||
'.tgz': 'application/x-compressed', |
||||
'.thmx': 'application/vnd.ms-officetheme', |
||||
'.thn': 'application/octet-stream', |
||||
'.tif': 'image/tiff', |
||||
'.tiff': 'image/tiff', |
||||
'.tlh': 'text/plain', |
||||
'.tli': 'text/plain', |
||||
'.toc': 'application/octet-stream', |
||||
'.tr': 'application/x-troff', |
||||
'.trm': 'application/x-msterminal', |
||||
'.trx': 'application/xml', |
||||
'.ts': 'video/vnd.dlna.mpeg-tts', |
||||
'.tsv': 'text/tab-separated-values', |
||||
'.ttf': 'application/font-sfnt', |
||||
'.tts': 'video/vnd.dlna.mpeg-tts', |
||||
'.txt': 'text/plain', |
||||
'.u32': 'application/octet-stream', |
||||
'.uls': 'text/iuls', |
||||
'.user': 'text/plain', |
||||
'.ustar': 'application/x-ustar', |
||||
'.vb': 'text/plain', |
||||
'.vbdproj': 'text/plain', |
||||
'.vbk': 'video/mpeg', |
||||
'.vbproj': 'text/plain', |
||||
'.vbs': 'text/vbscript', |
||||
'.vcf': 'text/x-vcard', |
||||
'.vcproj': 'application/xml', |
||||
'.vcs': 'text/plain', |
||||
'.vcxproj': 'application/xml', |
||||
'.vddproj': 'text/plain', |
||||
'.vdp': 'text/plain', |
||||
'.vdproj': 'text/plain', |
||||
'.vdx': 'application/vnd.ms-visio.viewer', |
||||
'.vml': 'text/xml', |
||||
'.vscontent': 'application/xml', |
||||
'.vsct': 'text/xml', |
||||
'.vsd': 'application/vnd.visio', |
||||
'.vsi': 'application/ms-vsi', |
||||
'.vsix': 'application/vsix', |
||||
'.vsixlangpack': 'text/xml', |
||||
'.vsixmanifest': 'text/xml', |
||||
'.vsmdi': 'application/xml', |
||||
'.vspscc': 'text/plain', |
||||
'.vss': 'application/vnd.visio', |
||||
'.vsscc': 'text/plain', |
||||
'.vssettings': 'text/xml', |
||||
'.vssscc': 'text/plain', |
||||
'.vst': 'application/vnd.visio', |
||||
'.vstemplate': 'text/xml', |
||||
'.vsto': 'application/x-ms-vsto', |
||||
'.vsw': 'application/vnd.visio', |
||||
'.vsx': 'application/vnd.visio', |
||||
'.vtx': 'application/vnd.visio', |
||||
'.wav': 'audio/wav', |
||||
'.wave': 'audio/wav', |
||||
'.wax': 'audio/x-ms-wax', |
||||
'.wbk': 'application/msword', |
||||
'.wbmp': 'image/vnd.wap.wbmp', |
||||
'.wcm': 'application/vnd.ms-works', |
||||
'.wdb': 'application/vnd.ms-works', |
||||
'.wdp': 'image/vnd.ms-photo', |
||||
'.webarchive': 'application/x-safari-webarchive', |
||||
'.webm': 'video/webm', |
||||
'.webp': 'image/webp', |
||||
'.webtest': 'application/xml', |
||||
'.wiq': 'application/xml', |
||||
'.wiz': 'application/msword', |
||||
'.wks': 'application/vnd.ms-works', |
||||
'.WLMP': 'application/wlmoviemaker', |
||||
'.wlpginstall': 'application/x-wlpg-detect', |
||||
'.wlpginstall3': 'application/x-wlpg3-detect', |
||||
'.wm': 'video/x-ms-wm', |
||||
'.wma': 'audio/x-ms-wma', |
||||
'.wmd': 'application/x-ms-wmd', |
||||
'.wmf': 'application/x-msmetafile', |
||||
'.wml': 'text/vnd.wap.wml', |
||||
'.wmlc': 'application/vnd.wap.wmlc', |
||||
'.wmls': 'text/vnd.wap.wmlscript', |
||||
'.wmlsc': 'application/vnd.wap.wmlscriptc', |
||||
'.wmp': 'video/x-ms-wmp', |
||||
'.wmv': 'video/x-ms-wmv', |
||||
'.wmx': 'video/x-ms-wmx', |
||||
'.wmz': 'application/x-ms-wmz', |
||||
'.woff': 'application/font-woff', |
||||
'.wpl': 'application/vnd.ms-wpl', |
||||
'.wps': 'application/vnd.ms-works', |
||||
'.wri': 'application/x-mswrite', |
||||
'.wrl': 'x-world/x-vrml', |
||||
'.wrz': 'x-world/x-vrml', |
||||
'.wsc': 'text/scriptlet', |
||||
'.wsdl': 'text/xml', |
||||
'.wvx': 'video/x-ms-wvx', |
||||
'.x': 'application/directx', |
||||
'.xaf': 'x-world/x-vrml', |
||||
'.xaml': 'application/xaml+xml', |
||||
'.xap': 'application/x-silverlight-app', |
||||
'.xbap': 'application/x-ms-xbap', |
||||
'.xbm': 'image/x-xbitmap', |
||||
'.xdr': 'text/plain', |
||||
'.xht': 'application/xhtml+xml', |
||||
'.xhtml': 'application/xhtml+xml', |
||||
'.xla': 'application/vnd.ms-excel', |
||||
'.xlam': 'application/vnd.ms-excel.addin.macroEnabled.12', |
||||
'.xlc': 'application/vnd.ms-excel', |
||||
'.xld': 'application/vnd.ms-excel', |
||||
'.xlk': 'application/vnd.ms-excel', |
||||
'.xll': 'application/vnd.ms-excel', |
||||
'.xlm': 'application/vnd.ms-excel', |
||||
'.xls': 'application/vnd.ms-excel', |
||||
'.xlsb': 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', |
||||
'.xlsm': 'application/vnd.ms-excel.sheet.macroEnabled.12', |
||||
'.xlsx': |
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', |
||||
'.xlt': 'application/vnd.ms-excel', |
||||
'.xltm': 'application/vnd.ms-excel.template.macroEnabled.12', |
||||
'.xltx': |
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.template', |
||||
'.xlw': 'application/vnd.ms-excel', |
||||
'.xml': 'text/xml', |
||||
'.xmta': 'application/xml', |
||||
'.xof': 'x-world/x-vrml', |
||||
'.XOML': 'text/plain', |
||||
'.xpm': 'image/x-xpixmap', |
||||
'.xps': 'application/vnd.ms-xpsdocument', |
||||
'.xrm-ms': 'text/xml', |
||||
'.xsc': 'application/xml', |
||||
'.xsd': 'text/xml', |
||||
'.xsf': 'text/xml', |
||||
'.xsl': 'text/xml', |
||||
'.xslt': 'text/xml', |
||||
'.xsn': 'application/octet-stream', |
||||
'.xss': 'application/xml', |
||||
'.xspf': 'application/xspf+xml', |
||||
'.xtp': 'application/octet-stream', |
||||
'.xwd': 'image/x-xwindowdump', |
||||
'.z': 'application/x-compress', |
||||
'.zip': 'application/zip', |
||||
} |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
import { mimeTypes } from '../configs' |
||||
|
||||
export const getMimeTypeByExtension = (ext: string) => { |
||||
if (!ext) return '' |
||||
|
||||
const extension = prepareExtension(ext) |
||||
const mimeType = mimeTypes[extension] |
||||
|
||||
if (!mimeType) return extension |
||||
return mimeType |
||||
} |
||||
|
||||
function prepareExtension(ext: string) { |
||||
if (ext.startsWith('.')) return ext.toLowerCase() |
||||
|
||||
return `.${ext.toLowerCase()}` |
||||
} |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
import { useEffect, useState } from 'react' |
||||
import ReceiveSharingIntent from 'react-native-receive-sharing-intent' |
||||
import { ISharedFile } from '../interfaces' |
||||
import { NavigationModuleKey, RouteKey } from '../enums' |
||||
import _ from 'lodash' |
||||
import { useSelector } from 'react-redux' |
||||
import { Alert } from 'react-native' |
||||
import { NavigationService } from '@/services/system' |
||||
import { selectActiveNavigationModule } from '@/store/shared' |
||||
|
||||
export const useSharedFiles = () => { |
||||
const activeModule = useSelector(selectActiveNavigationModule) |
||||
|
||||
const [files, setFiles] = useState<ISharedFile[]>([]) |
||||
|
||||
useEffect(() => { |
||||
ReceiveSharingIntent.getReceivedFiles( |
||||
(receivedFiles: ISharedFile[]) => { |
||||
setFiles(receivedFiles) |
||||
}, |
||||
(error: unknown) => { |
||||
console.log('Error on receive shared files', error) |
||||
}, |
||||
'ShareMediaTaskme', |
||||
) |
||||
}, []) |
||||
|
||||
useEffect(() => { |
||||
if (activeModule === NavigationModuleKey.User && !_.isEmpty(files)) { |
||||
NavigationService.navigate(RouteKey.SendSharedFiles, { |
||||
files, |
||||
}) |
||||
setFiles([]) |
||||
} else if ( |
||||
activeModule === NavigationModuleKey.Auth && |
||||
!_.isEmpty(files) |
||||
) { |
||||
Alert.alert( |
||||
'Ви не авторизовані', |
||||
'Авторизуйтесь та спробуйте ще раз поширити файли', |
||||
) |
||||
setFiles([]) |
||||
} |
||||
}, [files, activeModule]) |
||||
} |
Loading…
Reference in new issue