Skip to content

Commit

Permalink
Merge pull request #173 in MA/avito-ios-media-picker from develop to …
Browse files Browse the repository at this point in the history
…master

* commit '93bf2fe92857ddea6a013ecd8664e24608e2eb5e': (111 commits)
  SEL-512: Update changelog
  SEL-512: Move changelog
  SEL-512: Add link to readme
  SEL-512: Add github link
  SEL-512: Add changelog
  SEL-512: Improve readme
  SEL-512: Improve docs
  SEL-512: Bump version
  SEL-512: Improve library docs
  SEL-512: Add docs for crop
  SEL-512: Update readme
  SEL-496: Prevent focus animation if user denied access to camera
  SEL-473: Add new item to onAutocorrect callback
  SEL-384: Fix bug with full resolution image fetching (appeared on iOS 11)
  SEL-419: Add support of autocorrection event
  AI-6098: Move removeAll image cache to AppDelegate
  AI-6098: Add error to save file assert
  SEL-361: `add support of expose point select
  AI-6098: Remove unnecessary space
  AI-6098: Remove unnecessary space
  ...
  • Loading branch information
khomTima committed Sep 12, 2017
2 parents 509c934 + 93bf2fe commit 12b4159
Show file tree
Hide file tree
Showing 134 changed files with 3,667 additions and 795 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## 2.0.0 (2017-09-12)
[Compare]:https://github.com/avito-tech/Paparazzo/compare/1.1.0...2.0.0

##### Enhancements

* Add support for photo filters
[Timofey Khomutnikov](https://github.com/khomTima)

* Add supprot for mask cropping
[Vladimir Kaltyrin](https://github.com/vkaltyrin)

* Add support for photo reordering
[Artem Peskishev](https://github.com/peskish)

* Add support for cache cleaning
[Vadim Smal](https://github.com/CognitiveDisson)

##### Bug Fixes

* Minor fixes and improvements
22 changes: 18 additions & 4 deletions Example/PaparazzoExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
088535F351074F52B19B1688 /* Pods_PaparazzoExample_NoMarshroute.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9A4E214165A8FB30A7CE203 /* Pods_PaparazzoExample_NoMarshroute.framework */; };
08BB7920D2F1F31E8D8C1760 /* Pods_PaparazzoExample_Storyboard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B16F0AF7B8CAAE81DB10090 /* Pods_PaparazzoExample_Storyboard.framework */; };
136F1C7C1F4EDE2B00C5CCA1 /* AutoAdjustmentFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136F1C7A1F4EDDF500C5CCA1 /* AutoAdjustmentFilter.swift */; };
251E57C41E65651F0009A288 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 251E57C31E65651F0009A288 /* AppDelegate.swift */; };
251E57F01E6565890009A288 /* AppSpecificUITheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 251E57D51E6565890009A288 /* AppSpecificUITheme.swift */; };
251E57F21E6565890009A288 /* ExampleAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 251E57D91E6565890009A288 /* ExampleAssembly.swift */; };
Expand Down Expand Up @@ -59,6 +60,7 @@

/* Begin PBXFileReference section */
0CD08CDB3C698AABC02FE1C4 /* Pods-PaparazzoExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PaparazzoExample.release.xcconfig"; path = "Pods/Target Support Files/Pods-PaparazzoExample/Pods-PaparazzoExample.release.xcconfig"; sourceTree = "<group>"; };
136F1C7A1F4EDDF500C5CCA1 /* AutoAdjustmentFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoAdjustmentFilter.swift; sourceTree = "<group>"; };
251E57C01E65651F0009A288 /* PaparazzoExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PaparazzoExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
251E57C31E65651F0009A288 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
251E57CF1E65651F0009A288 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -92,8 +94,8 @@
8EC973CB836BAD3EDC80CABA /* Pods-PaparazzoExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PaparazzoExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PaparazzoExample/Pods-PaparazzoExample.debug.xcconfig"; sourceTree = "<group>"; };
AD2DAC113521ADEBFF8A22F1 /* Pods_PaparazzoExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PaparazzoExample.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B9A4E214165A8FB30A7CE203 /* Pods_PaparazzoExample_NoMarshroute.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PaparazzoExample_NoMarshroute.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EFA7610D1E829434000EB296 /* ItemProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemProvider.swift; sourceTree = "<group>"; };
E747D4112A5EEA41675E0267 /* Pods-PaparazzoExample_Storyboard.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PaparazzoExample_Storyboard.release.xcconfig"; path = "Pods/Target Support Files/Pods-PaparazzoExample_Storyboard/Pods-PaparazzoExample_Storyboard.release.xcconfig"; sourceTree = "<group>"; };
EFA7610D1E829434000EB296 /* ItemProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemProvider.swift; sourceTree = "<group>"; };
F2F50FC31E6C9F60006F9171 /* PaparazzoExample_Storyboard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PaparazzoExample_Storyboard.app; sourceTree = BUILT_PRODUCTS_DIR; };
F2F50FC51E6C9F60006F9171 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
F2F50FC71E6C9F60006F9171 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -131,6 +133,14 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
136F1C771F4ED91900C5CCA1 /* Filters */ = {
isa = PBXGroup;
children = (
136F1C7A1F4EDDF500C5CCA1 /* AutoAdjustmentFilter.swift */,
);
path = Filters;
sourceTree = "<group>";
};
251E57B71E65651F0009A288 = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -161,6 +171,7 @@
251E57C31E65651F0009A288 /* AppDelegate.swift */,
251E57D51E6565890009A288 /* AppSpecificUITheme.swift */,
251E57EF1E6565890009A288 /* NavigationController.swift */,
136F1C771F4ED91900C5CCA1 /* Filters */,
251E57D71E6565890009A288 /* Example */,
251E57E71E6565890009A288 /* Fonts */,
251E57ED1E6565890009A288 /* MarshrouteHelpers */,
Expand Down Expand Up @@ -479,7 +490,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
6620037BC3D2966EBE230528 /* [CP] Copy Pods Resources */ = {
Expand Down Expand Up @@ -524,7 +535,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
BE84EDEE72F665CE084E60AC /* [CP] Embed Pods Frameworks */ = {
Expand Down Expand Up @@ -554,7 +565,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
E607E68B79D7FA6BB43CDC07 /* [CP] Embed Pods Frameworks */ = {
Expand Down Expand Up @@ -597,6 +608,7 @@
251E57FB1E6565890009A288 /* ExampleViewInput.swift in Sources */,
251E57FA1E6565890009A288 /* ExampleViewController.swift in Sources */,
251E57F21E6565890009A288 /* ExampleAssembly.swift in Sources */,
136F1C7C1F4EDE2B00C5CCA1 /* AutoAdjustmentFilter.swift in Sources */,
251E57F41E6565890009A288 /* ExampleInteractor.swift in Sources */,
251E58011E6565890009A288 /* MarshrouteFacade.swift in Sources */,
251E58021E6565890009A288 /* NavigationController.swift in Sources */,
Expand Down Expand Up @@ -757,6 +769,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = PaparazzoExample/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
Expand All @@ -773,6 +786,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = PaparazzoExample/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
Expand Down
11 changes: 10 additions & 1 deletion Example/PaparazzoExample/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
cleanTemporaryDirectory()

window = UIWindow(frame: UIScreen.main.bounds)

let photoStorage = PhotoStorageImpl()
photoStorage.removeAll()
let mediaPickerAssemblyFactory = Paparazzo.MarshrouteAssemblyFactory(
theme: PaparazzoUITheme.appSpecificTheme(),
photoStorage: photoStorage
)
let exampleAssembly = ExampleAssemblyImpl(mediaPickerAssemblyFactory: mediaPickerAssemblyFactory)

window?.rootViewController = MarshrouteFacade().navigationController(NavigationController()) { routerSeed in
ExampleAssemblyImpl().viewController(routerSeed: routerSeed)
exampleAssembly.viewController(routerSeed: routerSeed)
}
window?.makeKeyAndVisible()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import UIKit
import Marshroute
import Paparazzo

final class ExampleAssemblyImpl: ExampleAssembly {

private let mediaPickerAssemblyFactory: MarshrouteAssemblyFactory

init(mediaPickerAssemblyFactory: MarshrouteAssemblyFactory) {
self.mediaPickerAssemblyFactory = mediaPickerAssemblyFactory
}

// MARK: - ExampleAssembly

func viewController(routerSeed: RouterSeed) -> UIViewController {

let interactor = ExampleInteractorImpl()

let router = ExampleRouterImpl(
mediaPickerAssemblyFactory: mediaPickerAssemblyFactory,
routerSeed: routerSeed
)

Expand Down
83 changes: 78 additions & 5 deletions Example/PaparazzoExample/Example/Presenter/ExamplePresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import ImageSource

final class ExamplePresenter {

// MARK: - Dependencies

private let interactor: ExampleInteractor
private let router: ExampleRouter

Expand All @@ -21,10 +23,18 @@ final class ExamplePresenter {

private var items: [MediaPickerItem] = []

private let cropCanvasSize = CGSize(width: 1280, height: 960)

// MARK: - Private

private let croppingOverlayProvidersFactory = Paparazzo.CroppingOverlayProvidersFactoryImpl()

private func setUpView() {

view?.setMediaPickerButtonTitle("Media Picker")
view?.setMaskCropperButtonTitle("Mask Cropper")
view?.setPhotoLibraryButtonTitle("Photo Library")

view?.onShowMediaPickerButtonTap = { [weak self] in
self?.interactor.remoteItems { remoteItems in
self?.showMediaPicker(remoteItems: remoteItems)
Expand All @@ -48,21 +58,76 @@ final class ExamplePresenter {
}
}
}

view?.onMaskCropperButtonTap = { [weak self] in
self?.showMaskCropperCamera()
}
}

func showMaskCropperCamera() {
let data = MediaPickerData(
items: items,
selectedItem: nil,
maxItemsCount: 1,
cropEnabled: true,
cropCanvasSize: cropCanvasSize,
initialActiveCameraType: .front
)

self.router.showMediaPicker(
data: data,
configure: { module in
weak var module = module
module?.setContinueButtonVisible(false)
module?.setCropMode(.custom(croppingOverlayProvidersFactory.circleCroppingOverlayProvider()))
module?.onCancel = {
module?.dismissModule()
}
module?.onFinish = { items in
module?.dismissModule()
}
}
)
}

private func showMaskCropperIn(rootModule: MediaPickerModule?, photo: MediaPickerItem) {

let data = MaskCropperData(
imageSource: photo.image,
cropCanvasSize: cropCanvasSize
)
router.showMaskCropper(
data: data,
croppingOverlayProvider: croppingOverlayProvidersFactory.heartShapeCroppingOverlayProvider(),
configure: { module in
weak var module = module
module?.onDiscard = {
module?.dismissModule()
}
module?.onConfirm = { _ in
rootModule?.dismissModule()
}
})
}

func showMediaPicker(remoteItems: [MediaPickerItem]) {

var items = self.items
items.append(contentsOf: remoteItems)

let cropCanvasSize = CGSize(width: 1280, height: 960)

self.router.showMediaPicker(
let data = MediaPickerData(
items: items,
autocorrectionFilters: [AutoAdjustmentFilter()],
selectedItem: items.last,
maxItemsCount: 20,
cropCanvasSize: cropCanvasSize,
configuration: { [weak self] module in
cropEnabled: true,
autocorrectEnabled: true,
cropCanvasSize: cropCanvasSize
)

self.router.showMediaPicker(
data: data,
configure: { [weak self] module in
self?.configureMediaPicker(module: module)
}
)
Expand All @@ -72,13 +137,21 @@ final class ExamplePresenter {
module.onItemsAdd = { _ in debugPrint("mediaPickerDidAddItems") }
module.onItemUpdate = { _ in debugPrint("mediaPickerDidUpdateItem") }
module.onItemRemove = { _ in debugPrint("mediaPickerDidRemoveItem") }
module.onItemAutocorrect = { _, isAutocorrected, _ in debugPrint("mediaPickerDidAutocorrectItem: \(isAutocorrected)") }

module.setContinueButtonTitle("Готово")

module.onCancel = { [weak module] in
module?.dismissModule()
}

module.onContinueButtonTap = { [weak module] in
module?.setContinueButtonStyle(.spinner)
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
module?.finish()
}
}

module.onFinish = { [weak module] items in
debugPrint("media picker did finish with \(items.count) items:")
items.forEach { debugPrint($0) }
Expand Down
15 changes: 9 additions & 6 deletions Example/PaparazzoExample/Example/Router/ExampleRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ import Paparazzo
protocol ExampleRouter: class, RouterFocusable, RouterDismissable {

func showMediaPicker(
items: [MediaPickerItem],
selectedItem: MediaPickerItem?,
maxItemsCount: Int?,
cropCanvasSize: CGSize,
configuration: (MediaPickerModule) -> ()
data: MediaPickerData,
configure: (MediaPickerModule) -> ()
)

func showMaskCropper(
data: MaskCropperData,
croppingOverlayProvider: CroppingOverlayProvider,
configure: (MaskCropperModule) -> ()
)

func showPhotoLibrary(
selectedItems: [PhotoLibraryItem],
maxSelectedItemsCount: Int?,
configuration: (PhotoLibraryModule) -> ()
configure: (PhotoLibraryModule) -> ()
)
}

0 comments on commit 12b4159

Please sign in to comment.