diff --git a/android/app/build.gradle b/android/app/build.gradle index faf4134..700db09 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -142,6 +142,7 @@ android { dependencies { + implementation project(':rn-fetch-blob') implementation project(':react-native-image-crop-picker') implementation project(':react-native-image-resizer') diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 3e0612b..014be91 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ package="com.timepill"> + @@ -24,6 +25,7 @@ + diff --git a/android/app/src/main/java/com/timepill/MainApplication.java b/android/app/src/main/java/com/timepill/MainApplication.java index 6d578b8..78fbdfa 100644 --- a/android/app/src/main/java/com/timepill/MainApplication.java +++ b/android/app/src/main/java/com/timepill/MainApplication.java @@ -3,6 +3,7 @@ package com.timepill; import android.app.Application; import com.facebook.react.ReactApplication; +import com.RNFetchBlob.RNFetchBlobPackage; import com.reactnative.ivpusic.imagepicker.PickerPackage; import fr.bamlab.rnimageresizer.ImageResizerPackage; import com.learnium.RNDeviceInfo.RNDeviceInfo; @@ -43,6 +44,7 @@ public class MainApplication extends NavigationApplication { // No need to add RnnPackage and MainReactPackage return Arrays.asList( // eg. new VectorIconsPackage() + new RNFetchBlobPackage(), new RNDeviceInfo(), new VectorIconsPackage(), new AsyncStoragePackage(), diff --git a/android/settings.gradle b/android/settings.gradle index 1ac57d6..4ec7cf7 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,4 +1,6 @@ rootProject.name = 'Timepill' +include ':rn-fetch-blob' +project(':rn-fetch-blob').projectDir = new File(rootProject.projectDir, '../node_modules/rn-fetch-blob/android') include ':react-native-image-crop-picker' project(':react-native-image-crop-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-crop-picker/android') include ':react-native-image-resizer' diff --git a/index.js b/index.js index 60f42be..27b645d 100644 --- a/index.js +++ b/index.js @@ -15,7 +15,7 @@ import BottomNav from './src/nav/bottomNav'; Navigation.registerComponent('Timepill', () => App); // regist screens automatically -for (let pageName in PageList) { +for(let pageName in PageList) { Navigation.registerComponent(pageName, () => PageList[pageName]); } @@ -29,7 +29,7 @@ Navigation.events().registerAppLaunchedListener(async () => { let token = await Token.getUserToken(); // let token; - if (!token) { + if(!token) { Navigation.setRoot({ root: { stack: { @@ -38,7 +38,11 @@ Navigation.events().registerAppLaunchedListener(async () => { name: 'Timepill', options: { topBar: { - visible: false + visible: false, + + // hide top bar for android + drawBehind: true, + animate: true } } } diff --git a/ios/Timepill.xcodeproj/project.pbxproj b/ios/Timepill.xcodeproj/project.pbxproj index c1cc86b..b8be9ae 100644 --- a/ios/Timepill.xcodeproj/project.pbxproj +++ b/ios/Timepill.xcodeproj/project.pbxproj @@ -38,6 +38,7 @@ 2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D16E6891FA4F8E400B85C8A /* libReact.a */; }; 2DCD954D1E0B4F2C00145EB5 /* TimepillTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* TimepillTests.m */; }; 2DF0FFEE2056DD460020B375 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; }; + 35DCFF50947D4FCBBF5A8921 /* libRNFetchBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B2E8AA4B1D85497E86DAA92C /* libRNFetchBlob.a */; }; 4156314B2297CFA5009EB583 /* RSKImageCropper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4156314A2297CFA5009EB583 /* RSKImageCropper.framework */; }; 4156314C2297CFA5009EB583 /* RSKImageCropper.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4156314A2297CFA5009EB583 /* RSKImageCropper.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 4156314F2297CFBE009EB583 /* QBImagePicker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4156314E2297CFBE009EB583 /* QBImagePicker.framework */; }; @@ -304,6 +305,13 @@ remoteGlobalIDString = 7B49FEBB1E95090800DEB3EA; remoteInfo = ReactNativeNavigationTests; }; + 41CDC8D022A0351700485467 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 99151F1A82BD48E0B5416458 /* RNFetchBlob.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A15C300E1CD25C330074CB35; + remoteInfo = RNFetchBlob; + }; 41EC7C5622809E1800779391 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; @@ -453,10 +461,12 @@ 7FC4807EA1FA42A4A55BDAE5 /* libRNVectorIcons-tvOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = "libRNVectorIcons-tvOS.a"; sourceTree = ""; }; 81F0243DD71F467A964CAD89 /* Entypo.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Entypo.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Entypo.ttf"; sourceTree = ""; }; 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; + 99151F1A82BD48E0B5416458 /* RNFetchBlob.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNFetchBlob.xcodeproj; path = "../node_modules/rn-fetch-blob/ios/RNFetchBlob.xcodeproj"; sourceTree = ""; }; 996469B8096342559A8F98D6 /* libimageCropPicker.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libimageCropPicker.a; sourceTree = ""; }; A333F2A12D224289B26028D1 /* libRNVectorIcons.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNVectorIcons.a; sourceTree = ""; }; ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTBlob.xcodeproj; path = "../node_modules/react-native/Libraries/Blob/RCTBlob.xcodeproj"; sourceTree = ""; }; ADDB7A9FC7044DF48E9BA080 /* Octicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Octicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Octicons.ttf"; sourceTree = ""; }; + B2E8AA4B1D85497E86DAA92C /* libRNFetchBlob.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFetchBlob.a; sourceTree = ""; }; BDBA91D5680B4ACA83A7844B /* imageCropPicker.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = imageCropPicker.xcodeproj; path = "../node_modules/react-native-image-crop-picker/ios/imageCropPicker.xcodeproj"; sourceTree = ""; }; C558ABC6E5C94D939958E5F9 /* FontAwesome.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome.ttf; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf"; sourceTree = ""; }; C988095E6478452AAAF73E23 /* libRCTImageResizer.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRCTImageResizer.a; sourceTree = ""; }; @@ -503,6 +513,7 @@ 505DDEF9B17C4B93A7D4C4B0 /* libRCTImageResizer.a in Frameworks */, 9678DE108DEC4C5A9D92EA1D /* libimageCropPicker.a in Frameworks */, 4156314F2297CFBE009EB583 /* QBImagePicker.framework in Frameworks */, + 35DCFF50947D4FCBBF5A8921 /* libRNFetchBlob.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -686,6 +697,14 @@ name = Products; sourceTree = ""; }; + 41CDC8CD22A0351700485467 /* Products */ = { + isa = PBXGroup; + children = ( + 41CDC8D122A0351700485467 /* libRNFetchBlob.a */, + ); + name = Products; + sourceTree = ""; + }; 41EC7C2E22809E1600779391 /* Recovered References */ = { isa = PBXGroup; children = ( @@ -696,6 +715,7 @@ 784C7C58E2B04EECBD71EF5E /* libRNDeviceInfo-tvOS.a */, C988095E6478452AAAF73E23 /* libRCTImageResizer.a */, 996469B8096342559A8F98D6 /* libimageCropPicker.a */, + B2E8AA4B1D85497E86DAA92C /* libRNFetchBlob.a */, ); name = "Recovered References"; sourceTree = ""; @@ -764,6 +784,7 @@ D16AA0DE1A4348A8B86F08A1 /* RNDeviceInfo.xcodeproj */, DE970E03BCC84CE8A281A103 /* RCTImageResizer.xcodeproj */, BDBA91D5680B4ACA83A7844B /* imageCropPicker.xcodeproj */, + 99151F1A82BD48E0B5416458 /* RNFetchBlob.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -1014,6 +1035,10 @@ ProductGroup = 41FCEABF22818DAE009A3DD7 /* Products */; ProjectRef = D16AA0DE1A4348A8B86F08A1 /* RNDeviceInfo.xcodeproj */; }, + { + ProductGroup = 41CDC8CD22A0351700485467 /* Products */; + ProjectRef = 99151F1A82BD48E0B5416458 /* RNFetchBlob.xcodeproj */; + }, { ProductGroup = 41EC7D4D22815DCA00779391 /* Products */; ProjectRef = 000EDE6A5D7D497FB251CC09 /* RNVectorIcons.xcodeproj */; @@ -1254,6 +1279,13 @@ remoteRef = 4166A0E522895B4C0086277D /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 41CDC8D122A0351700485467 /* libRNFetchBlob.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRNFetchBlob.a; + remoteRef = 41CDC8D022A0351700485467 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 41EC7C5722809E1800779391 /* libjsi.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -1501,6 +1533,7 @@ "$(SRCROOT)/../node_modules/react-native-device-info/ios/RNDeviceInfo", "$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer", "$(SRCROOT)/../node_modules/react-native-image-crop-picker/ios/**", + "$(SRCROOT)/../node_modules/rn-fetch-blob/ios/**", ); INFOPLIST_FILE = TimepillTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -1514,6 +1547,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1537,6 +1571,7 @@ "$(SRCROOT)/../node_modules/react-native-device-info/ios/RNDeviceInfo", "$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer", "$(SRCROOT)/../node_modules/react-native-image-crop-picker/ios/**", + "$(SRCROOT)/../node_modules/rn-fetch-blob/ios/**", ); INFOPLIST_FILE = TimepillTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -1550,6 +1585,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1574,6 +1610,7 @@ "$(SRCROOT)/../node_modules/react-native-device-info/ios/RNDeviceInfo", "$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer", "$(SRCROOT)/../node_modules/react-native-image-crop-picker/ios/**", + "$(SRCROOT)/../node_modules/rn-fetch-blob/ios/**", ); INFOPLIST_FILE = Timepill/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1600,6 +1637,7 @@ "$(SRCROOT)/../node_modules/react-native-device-info/ios/RNDeviceInfo", "$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer", "$(SRCROOT)/../node_modules/react-native-image-crop-picker/ios/**", + "$(SRCROOT)/../node_modules/rn-fetch-blob/ios/**", ); INFOPLIST_FILE = Timepill/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1633,6 +1671,7 @@ "$(SRCROOT)/../node_modules/react-native-device-info/ios/RNDeviceInfo", "$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer", "$(SRCROOT)/../node_modules/react-native-image-crop-picker/ios/**", + "$(SRCROOT)/../node_modules/rn-fetch-blob/ios/**", ); INFOPLIST_FILE = "Timepill-tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1645,6 +1684,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1677,6 +1717,7 @@ "$(SRCROOT)/../node_modules/react-native-device-info/ios/RNDeviceInfo", "$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer", "$(SRCROOT)/../node_modules/react-native-image-crop-picker/ios/**", + "$(SRCROOT)/../node_modules/rn-fetch-blob/ios/**", ); INFOPLIST_FILE = "Timepill-tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1689,6 +1730,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1720,6 +1762,7 @@ "$(SRCROOT)/../node_modules/react-native-device-info/ios/RNDeviceInfo", "$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer", "$(SRCROOT)/../node_modules/react-native-image-crop-picker/ios/**", + "$(SRCROOT)/../node_modules/rn-fetch-blob/ios/**", ); INFOPLIST_FILE = "Timepill-tvOSTests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1732,6 +1775,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1763,6 +1807,7 @@ "$(SRCROOT)/../node_modules/react-native-device-info/ios/RNDeviceInfo", "$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer", "$(SRCROOT)/../node_modules/react-native-image-crop-picker/ios/**", + "$(SRCROOT)/../node_modules/rn-fetch-blob/ios/**", ); INFOPLIST_FILE = "Timepill-tvOSTests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1775,6 +1820,7 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", diff --git a/ios/Timepill/Info.plist b/ios/Timepill/Info.plist index 3bf4e25..f2e8b13 100644 --- a/ios/Timepill/Info.plist +++ b/ios/Timepill/Info.plist @@ -3,9 +3,9 @@ NSCameraUsageDescription - + NSPhotoLibraryUsageDescription - + CFBundleDevelopmentRegion en CFBundleDisplayName @@ -29,7 +29,7 @@ LSRequiresIPhoneOS NSLocationWhenInUseUsageDescription - + UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities diff --git a/package-lock.json b/package-lock.json index 841b235..a76e885 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10850,6 +10850,19 @@ "resolved": "https://registry.npm.taobao.org/react-native-image-crop-picker/download/react-native-image-crop-picker-0.24.0.tgz", "integrity": "sha1-3xAVSPcpUb9m5WCIevc7EfMovdA=" }, + "react-native-image-pan-zoom": { + "version": "2.1.11", + "resolved": "http://registry.npm.taobao.org/react-native-image-pan-zoom/download/react-native-image-pan-zoom-2.1.11.tgz", + "integrity": "sha1-Yby2khnZXnapeX0j5KLo4L1lSuk=" + }, + "react-native-image-progress": { + "version": "1.1.1", + "resolved": "http://registry.npm.taobao.org/react-native-image-progress/download/react-native-image-progress-1.1.1.tgz", + "integrity": "sha1-lbvgh1x+vVQobfacs3tZi5TFTrA=", + "requires": { + "prop-types": "^15.5.10" + } + }, "react-native-image-resizer": { "version": "1.0.0", "resolved": "http://registry.npm.taobao.org/react-native-image-resizer/download/react-native-image-resizer-1.0.0.tgz", @@ -11191,6 +11204,30 @@ "glob": "^7.1.3" } }, + "rn-fetch-blob": { + "version": "0.10.15", + "resolved": "https://registry.npm.taobao.org/rn-fetch-blob/download/rn-fetch-blob-0.10.15.tgz", + "integrity": "sha1-NSaGDBxX4L9MCb2+QJyRkmSv/7o=", + "requires": { + "base-64": "0.1.0", + "glob": "7.0.6" + }, + "dependencies": { + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npm.taobao.org/glob/download/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "rsvp": { "version": "3.6.2", "resolved": "http://registry.npm.taobao.org/rsvp/download/rsvp-3.6.2.tgz", diff --git a/package.json b/package.json index 442cac5..6827916 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,16 @@ "react-native-device-info": "^1.6.1", "react-native-elements": "^0.19.0", "react-native-image-crop-picker": "^0.24.0", + "react-native-image-pan-zoom": "^2.1.11", + "react-native-image-progress": "^1.1.1", "react-native-image-resizer": "^1.0.0", "react-native-iphone-x-helper": "^1.0.2", "react-native-keyboard-spacer": "^0.4.1", "react-native-navigation": "^2.18.5", "react-native-root-toast": "^3.0.0", "react-native-tab-view": "^1.3.0", - "react-native-vector-icons": "^4.5.0" + "react-native-vector-icons": "^4.5.0", + "rn-fetch-blob": "^0.10.15" }, "devDependencies": { "@babel/core": "^7.4.3", diff --git a/src/component/diary/diaryBrief.js b/src/component/diary/diaryBrief.js index 5fc8f19..6032310 100644 --- a/src/component/diary/diaryBrief.js +++ b/src/component/diary/diaryBrief.js @@ -65,7 +65,7 @@ export default class DiaryBrief extends Component { {diary.content} - + { diff --git a/src/component/diary/diaryFull.js b/src/component/diary/diaryFull.js index ad310f9..4724351 100644 --- a/src/component/diary/diaryFull.js +++ b/src/component/diary/diaryFull.js @@ -1,5 +1,6 @@ import React, {Component} from 'react'; import {Platform, StyleSheet, Text, View} from 'react-native'; +import {Navigation} from 'react-native-navigation'; import moment from 'moment'; import Color from '../../style/color'; @@ -35,6 +36,38 @@ export default class DiaryFull extends Component { await this.commentList.refresh(); } + _onUserIconPress() { + Navigation.push(this.props.componentId, { + component: { + name: 'User', + options: { + bottomTabs: { + visible: false, + + // hide bottom tab for android + drawBehind: true, + animate: true + } + }, + passProps: { + user: this.state.diary.user + } + } + }); + } + + _onPhotoPress(photoUrl) { + Navigation.push(this.props.componentId, { + component: { + name: 'Photo', + passProps: { + url: photoUrl + } + } + }) + } + + render() { let diary = this.state.diary; if(!diary) { @@ -47,7 +80,7 @@ export default class DiaryFull extends Component { {user && user.iconUrl - ? : null} + ? : null} @@ -69,7 +102,7 @@ export default class DiaryFull extends Component { {diary.content.trim()} - + this._onPhotoPress(diary.photoUrl)}> diff --git a/src/component/diary/diaryList.js b/src/component/diary/diaryList.js index c1c02be..536b9d6 100644 --- a/src/component/diary/diaryList.js +++ b/src/component/diary/diaryList.js @@ -144,6 +144,17 @@ export default class DiaryList extends Component { }); } + _onPhotoPress(photoUrl) { + Navigation.push(this.props.componentId, { + component: { + name: 'Photo', + passProps: { + url: photoUrl + } + } + }) + } + async refresh() { if (this.state.refreshing) { return; @@ -239,6 +250,7 @@ export default class DiaryList extends Component { onUserIconPress={() => this._onUserIconPress(item)} onDiaryAction={() => this._onDiaryAction(item)} + onPhotoPress={() => this._onPhotoPress(item.photoUrl)} > diff --git a/src/component/photo.js b/src/component/photo.js index cbc3a05..4d34877 100644 --- a/src/component/photo.js +++ b/src/component/photo.js @@ -17,7 +17,7 @@ export default class Photo extends Component { render() { return this.formatUri ? ( {}} + onPress={this.props.onPress} style={localStyle.photoBox}> diff --git a/src/page/DiaryDetailPage.js b/src/page/DiaryDetailPage.js index 3b3dade..61acece 100644 --- a/src/page/DiaryDetailPage.js +++ b/src/page/DiaryDetailPage.js @@ -134,6 +134,7 @@ export default class DiaryDetailPage extends Component { diary={this.state.diary} refreshData={() => this.state.diary} editable={this.state.editable} + {...this.props} > diff --git a/src/page/PhotoPage.js b/src/page/PhotoPage.js new file mode 100644 index 0000000..b7b6505 --- /dev/null +++ b/src/page/PhotoPage.js @@ -0,0 +1,154 @@ +import React, { Component } from 'react'; +import { + Text, + View, + ActivityIndicator, + TouchableWithoutFeedback, + CameraRoll +} from "react-native"; +import {Navigation} from 'react-native-navigation'; +import ActionSheet from 'react-native-actionsheet-api'; +import moment from "moment"; +import Toast from 'react-native-root-toast'; +import RNFetchBlob from "rn-fetch-blob"; +import ImageZoom from 'react-native-image-pan-zoom'; +import Image from 'react-native-image-progress'; + +import Msg from '../util/msg'; +import Api from '../util/api'; + + +export default class PhotoPage extends Component { + + constructor(props) { + super(props); + + this.state = { + loading: true, + + width: 0, + height: 0 + }; + } + + static options(passProps) { + return { + topBar: { + visible: false, + + // hide top bar for android + drawBehind: true, + animate: true + }, + statusBar: { + backgroundColor: 'black' + }, + bottomTabs: { + visible: false, + + // hide bottom tab for android + drawBehind: true, + animate: true + } + }; + } + + close() { + Navigation.pop(this.props.componentId); + } + + onLongPress() { + ActionSheet.showActionSheetWithOptions({ + options:['保存照片', '取消'], + cancelButtonIndex:1 + + }, (index) => { + if(index == 0) { + this.savePhoto(); + } + }); + } + + async savePhoto() { + let msgOption = { + duration: 2000, + position: Toast.positions.BOTTOM, + shadow: false, + hideOnPress: true, + } + + try { + if(Api.IS_ANDROID) { + let dirs = RNFetchBlob.fs.dirs; + let path = dirs.DownloadDir + '/timepill/' + moment().format('YYYYMMDD-hhmmss') + '.jpg'; + let res = await RNFetchBlob + .config({path}) + .fetch('GET', this.props.url, {}); + + await RNFetchBlob.fs.scanFile([{ + path: res.path() + }]); + + } else { + await CameraRoll.saveToCameraRoll(this.props.url); + } + + Msg.showMsg('照片已保存', msgOption); + + } catch (err) { + Msg.showMsg('照片保存失败', msgOption); + } + } + + render() { + return ( + { + let {x, y, width, height} = event.nativeEvent.layout; + this.setState({ + width: width, + height: height + }) + }} + > + this.close()} + onLongPress={this.onLongPress.bind(this)} + > + + + + ); + } +} + +function loadingView(props) { + let process = Math.floor(props.progress * 100); + let text = process > 0 ? process + '%' : ''; + return ( + + + {text} + + ) +} + +function errorView(props) { + return ( + 加载失败 + ); +} \ No newline at end of file diff --git a/src/page/_list.js b/src/page/_list.js index 48f290e..e23ff01 100644 --- a/src/page/_list.js +++ b/src/page/_list.js @@ -8,6 +8,7 @@ NotebookDetail: require("./NotebookDetailPage.js").default, NotebookEdit: require("./NotebookEditPage.js").default, NotificationHistory: require("./NotificationHistoryPage.js").default, Notification: require("./NotificationPage.js").default, +Photo: require("./PhotoPage.js").default, User: require("./UserPage.js").default, Write: require("./WritePage.js").default } \ No newline at end of file diff --git a/src/util/msg.js b/src/util/msg.js index 94e6f8c..c6c4b49 100644 --- a/src/util/msg.js +++ b/src/util/msg.js @@ -1,16 +1,20 @@ import Toast from 'react-native-root-toast'; -function showMsg(msg) { +function showMsg(msg, option) { if (!msg) { return; } - Toast.show(msg, { - duration: 2500, - position: -75, - shadow: false, - hideOnPress: true, - }); + if(!option) { + option = { + duration: 2500, + position: -75, + shadow: false, + hideOnPress: true + } + } + + Toast.show(msg, option); } export default {