Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: android lib tests #6099

Draft
wants to merge 7 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ android {

signingConfigs {
release {
v1SigningEnabled false
if (project.hasProperty('KEYSTORE')) {
storeFile file(KEYSTORE)
storePassword KEYSTORE_PASSWORD
Expand Down Expand Up @@ -185,8 +186,11 @@ android {

dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
implementation("com.facebook.react:flipper-integration")
implementation("com.facebook.react:react-android") {
exclude group: "com.facebook.fresco"
exclude group: "com.facebook.fresco", module: "fresco"
}
// implementation("com.facebook.react:flipper-integration")

if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
Expand All @@ -210,8 +214,9 @@ dependencies {
androidTestImplementation('com.wix:detox:+')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.facebook.soloader:soloader:0.10.4'
implementation("com.facebook.fresco:animated-gif:2.5.0")
implementation "com.facebook.fresco:imagepipeline-okhttp3:3.1.3"
// implementation 'com.facebook.fresco:fresco:3.2.0'
// implementation("com.facebook.fresco:animated-gif:3.2.0")
// implementation "com.facebook.fresco:imagepipeline-okhttp3:3.1.3"
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.react.flipper.ReactNativeFlipper
// import com.facebook.react.flipper.ReactNativeFlipper
import com.facebook.soloader.SoLoader
import com.nozbe.watermelondb.jsi.WatermelonDBJSIPackage;
import com.facebook.react.bridge.JSIModulePackage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import com.facebook.react.modules.network.CustomClientBuilder;
import com.facebook.react.modules.network.ReactCookieJarContainer;
import com.facebook.react.modules.websocket.WebSocketModule;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory;
// import com.facebook.drawee.backends.pipeline.Fresco;
// import com.facebook.imagepipeline.core.ImagePipelineConfig;
// import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;

Expand Down Expand Up @@ -104,10 +104,10 @@ public void setCertificate(String data, Promise promise) {
// Websocket react-native layer
WebSocketModule.setCustomClientBuilder(new CustomClient());
// Image networking react-native layer
ImagePipelineConfig config = OkHttpImagePipelineConfigFactory
.newBuilder(this.reactContext, getOkHttpClient())
.build();
Fresco.initialize(this.reactContext, config);
// ImagePipelineConfig config = OkHttpImagePipelineConfigFactory
// .newBuilder(this.reactContext, getOkHttpClient())
// .build();
// Fresco.initialize(this.reactContext, config);
// RNCWebView onReceivedClientCertRequest
RNCWebViewManager.setCertificateAlias(data);
// FastImage Glide network layer
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ buildscript {

ext {
buildToolsVersion = "34.0.0"
minSdkVersion = 23
minSdkVersion = 30
compileSdkVersion = 34
targetSdkVersion = 34
ndkVersion = "25.1.8937393"
Expand Down
31 changes: 17 additions & 14 deletions app/containers/MessageComposer/constants.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import { Options } from 'react-native-image-crop-picker';
// import { Options } from 'react-native-image-crop-picker';
import { ImagePickerOptions, MediaTypeOptions } from 'expo-image-picker';

import { TMarkdownStyle } from './interfaces';

export const IMAGE_PICKER_CONFIG = {
cropping: true,
avoidEmptySpaceAroundImage: false,
freeStyleCropEnabled: true,
forceJpg: true,
includeExif: true
export const IMAGE_PICKER_CONFIG: ImagePickerOptions = {
// cropping: true,
// avoidEmptySpaceAroundImage: false,
// freeStyleCropEnabled: true,
// forceJpg: true,
// includeExif: true
quality: 1
};

export const LIBRARY_PICKER_CONFIG: Options = {
multiple: true,
compressVideoPreset: 'Passthrough',
mediaType: 'any',
includeExif: true
export const LIBRARY_PICKER_CONFIG: ImagePickerOptions = {
allowsMultipleSelection: true,
// multiple: true,
// compressVideoPreset: 'Passthrough',
// mediaType: 'any',
exif: true
};

export const VIDEO_PICKER_CONFIG: Options = {
mediaType: 'video'
export const VIDEO_PICKER_CONFIG: ImagePickerOptions = {
mediaTypes: MediaTypeOptions.Videos
};

export const TIMEOUT_CLOSE_EMOJI_KEYBOARD = 300;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Image } from 'react-native-image-crop-picker';

import { forceJpgExtension } from './forceJpgExtension';

const attachment: Image = {
const attachment = {
exif: null,
filename: 'IMG_0040.PNG',
path: 'tmp/temp',
Expand Down
4 changes: 2 additions & 2 deletions app/containers/MessageComposer/helpers/forceJpgExtension.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ImageOrVideo } from 'react-native-image-crop-picker';
// import { ImageOrVideo } from 'react-native-image-crop-picker';

import { isIOS } from '../../../lib/methods/helpers';

const regex = new RegExp(/\.[^/.]+$/); // Check from last '.' of the string

export const forceJpgExtension = (attachment: ImageOrVideo): ImageOrVideo => {
export const forceJpgExtension = (attachment: any): any => {
if (isIOS && attachment.mime === 'image/jpeg' && attachment.filename) {
// Replace files extension that mime type is 'image/jpeg' to .jpg;
attachment.filename = attachment.filename.replace(regex, '.jpg');
Expand Down
32 changes: 23 additions & 9 deletions app/containers/MessageComposer/hooks/useChooseMedia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Alert } from 'react-native';
import * as DocumentPicker from 'expo-document-picker';

import { IMAGE_PICKER_CONFIG, LIBRARY_PICKER_CONFIG, VIDEO_PICKER_CONFIG } from '../constants';
import { forceJpgExtension } from '../helpers';
// import { forceJpgExtension } from '../helpers';
import I18n from '../../../i18n';
import { canUploadFile } from '../../../lib/methods/helpers';
import log from '../../../lib/methods/helpers/log';
Expand All @@ -11,7 +11,7 @@ import { getThreadById } from '../../../lib/database/services/Thread';
import Navigation from '../../../lib/navigation/appNavigation';
import { useAppSelector } from '../../../lib/hooks';
import { useRoomContext } from '../../../views/RoomView/context';
import ImagePicker, { ImageOrVideo } from '../../../lib/methods/helpers/ImagePicker/ImagePicker';
import ImagePicker from '../../../lib/methods/helpers/ImagePicker/ImagePicker';

export const useChooseMedia = ({
rid,
Expand All @@ -34,15 +34,21 @@ export const useChooseMedia = ({

const takePhoto = async () => {
try {
let image = await ImagePicker.openCamera({ ...IMAGE_PICKER_CONFIG, ...libPickerLabels });
image = forceJpgExtension(image);
const result = await ImagePicker.launchCameraAsync({ ...IMAGE_PICKER_CONFIG, ...libPickerLabels });
if (result.canceled) {
return;
}
const image = result.assets[0];
console.log('🚀 ~ takePhoto ~ image:', image);
// image = forceJpgExtension(image);
const file = image as any; // FIXME: unify those types to remove the need for any
const canUploadResult = canUploadFile({
file,
allowList,
maxFileSize,
permissionToUploadFile: permissionToUpload
});
console.log('🚀 ~ takePhoto ~ canUploadResult:', canUploadResult);
if (canUploadResult.success) {
return openShareView([image]);
}
Expand All @@ -55,7 +61,11 @@ export const useChooseMedia = ({

const takeVideo = async () => {
try {
const video = await ImagePicker.openCamera({ ...VIDEO_PICKER_CONFIG, ...libPickerLabels });
const result = await ImagePicker.launchCameraAsync({ ...VIDEO_PICKER_CONFIG, ...libPickerLabels });
if (result.canceled) {
return;
}
const video = result.assets[0];
const file = video as any; // FIXME: unify those types to remove the need for any
const canUploadResult = canUploadFile({
file,
Expand All @@ -76,12 +86,16 @@ export const useChooseMedia = ({
const chooseFromLibrary = async () => {
try {
// The type can be video or photo, however the lib understands that it is just one of them.
let attachments = (await ImagePicker.openPicker({
const result = await ImagePicker.launchImageLibraryAsync({
...LIBRARY_PICKER_CONFIG,
...libPickerLabels
})) as unknown as ImageOrVideo[]; // FIXME: type this
attachments = attachments.map(att => forceJpgExtension(att));
openShareView(attachments);
});
if (result.canceled) {
return;
}
console.log('🚀 ~ chooseFromLibrary ~ attachments:', result);
// const assets = result.assets.map(att => forceJpgExtension(att));
openShareView(result.assets);
} catch (e) {
log(e);
}
Expand Down
118 changes: 60 additions & 58 deletions app/containers/RoomTypeIcon/OmnichannelRoomIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,60 @@
import React, { useState } from 'react';
import { StyleProp, ViewStyle } from 'react-native';
import { SvgUri } from 'react-native-svg';

import { OmnichannelSourceType, IOmnichannelSource, TUserStatus } from '../../definitions';
import { useAppSelector } from '../../lib/hooks';
import { CustomIcon, TIconsName } from '../CustomIcon';
import { useUserStatusColor } from '../../lib/hooks/useUserStatusColor';

interface IIconMap {
[key: string]: TIconsName;
}

const iconMap: IIconMap = {
widget: 'livechat-monochromatic',
email: 'mail',
sms: 'sms',
app: 'omnichannel',
api: 'omnichannel',
other: 'omnichannel'
};

interface IOmnichannelRoomIconProps {
size: number;
type: string;
style?: StyleProp<ViewStyle>;
status?: TUserStatus;
sourceType?: IOmnichannelSource;
}

export const OmnichannelRoomIcon = ({ size, style, sourceType, status }: IOmnichannelRoomIconProps) => {
const [loading, setLoading] = useState(true);
const [svgError, setSvgError] = useState(false);
const baseUrl = useAppSelector(state => state.server?.server);
const connected = useAppSelector(state => state.meteor?.connected);
const userStatusColor = useUserStatusColor(status || 'offline');

const customIcon = <CustomIcon name={iconMap[sourceType?.type || 'other']} size={size} style={style} color={userStatusColor} />;

if (!svgError && sourceType?.type === OmnichannelSourceType.APP && sourceType.id && sourceType.sidebarIcon && connected) {
return (
<>
<SvgUri
height={size}
width={size}
color={userStatusColor}
uri={`${baseUrl}/api/apps/public/${sourceType.id}/get-sidebar-icon?icon=${sourceType.sidebarIcon}`}
style={style}
onError={() => setSvgError(true)}
onLoad={() => setLoading(false)}
/>
{loading ? customIcon : null}
</>
);
}

return customIcon;
};
// import React, { useState } from 'react';
// import { StyleProp, ViewStyle } from 'react-native';
// // import { SvgUri } from 'react-native-svg';

// import { OmnichannelSourceType, IOmnichannelSource, TUserStatus } from '../../definitions';
// import { useAppSelector } from '../../lib/hooks';
// import { CustomIcon, TIconsName } from '../CustomIcon';
// import { useUserStatusColor } from '../../lib/hooks/useUserStatusColor';

// interface IIconMap {
// [key: string]: TIconsName;
// }

// const iconMap: IIconMap = {
// widget: 'livechat-monochromatic',
// email: 'mail',
// sms: 'sms',
// app: 'omnichannel',
// api: 'omnichannel',
// other: 'omnichannel'
// };

// interface IOmnichannelRoomIconProps {
// size: number;
// type: string;
// style?: StyleProp<ViewStyle>;
// status?: TUserStatus;
// sourceType?: IOmnichannelSource;
// }

// export const OmnichannelRoomIcon = ({ size, style, sourceType, status }: IOmnichannelRoomIconProps) => {
// // const [loading, setLoading] = useState(true);
// // const [svgError, setSvgError] = useState(false);
// // const baseUrl = useAppSelector(state => state.server?.server);
// // const connected = useAppSelector(state => state.meteor?.connected);
// // const userStatusColor = useUserStatusColor(status || 'offline');

// // const customIcon = <CustomIcon name={iconMap[sourceType?.type || 'other']} size={size} style={style} color={userStatusColor} />;

// // if (!svgError && sourceType?.type === OmnichannelSourceType.APP && sourceType.id && sourceType.sidebarIcon && connected) {
// // return (
// // <>
// // <SvgUri
// // height={size}
// // width={size}
// // color={userStatusColor}
// // uri={`${baseUrl}/api/apps/public/${sourceType.id}/get-sidebar-icon?icon=${sourceType.sidebarIcon}`}
// // style={style}
// // onError={() => setSvgError(true)}
// // onLoad={() => setLoading(false)}
// // />
// // {loading ? customIcon : null}
// // </>
// // );
// // }

// // return customIcon;
// return null
// };
export const OmnichannelRoomIcon = () => null;
Loading