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

[2] Add pinch to zoom in and out to new media view #2617

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
3a1e055
WIP
mpivchev Aug 28, 2023
7e8e0b7
WIP
mpivchev Aug 28, 2023
2a6cb22
Make view model
mpivchev Aug 28, 2023
2abe5a8
WIP
mpivchev Aug 31, 2023
8890bcc
WIP
mpivchev Sep 4, 2023
61aa890
WIP
mpivchev Sep 5, 2023
a92d9fc
WIP
mpivchev Sep 5, 2023
dcd3f83
Separate components
mpivchev Sep 5, 2023
17f7ba7
WIP
mpivchev Sep 5, 2023
8d4a2ba
Add top header
mpivchev Sep 5, 2023
63182e7
Add notifications
mpivchev Sep 11, 2023
5327311
Try to get first cell in list
mpivchev Sep 11, 2023
d2c5707
Add date update
mpivchev Sep 12, 2023
aa0a189
Refactor
mpivchev Sep 12, 2023
6526e65
WIP
mpivchev Sep 12, 2023
1c64989
Reload when switching accounts
mpivchev Sep 12, 2023
c7cd3e0
Add shimmer and old and new media loading
mpivchev Sep 13, 2023
ecc4ef6
Work on top section
mpivchev Sep 13, 2023
c2a43d7
Mark no thumbnails
mpivchev Sep 14, 2023
5cee6a6
Add pull to refresh
mpivchev Sep 15, 2023
5e4a83f
Add animated color change on top bar
mpivchev Sep 15, 2023
0cf382b
Adjust
mpivchev Sep 15, 2023
366461d
Adjust
mpivchev Sep 15, 2023
64bc0a6
Add actions to some options
mpivchev Sep 18, 2023
32280fa
Design work
mpivchev Sep 18, 2023
887988b
WIP with pushing VCs (kill me)
mpivchev Sep 19, 2023
6f9d622
WIP
mpivchev Sep 19, 2023
f755cfe
WIP
mpivchev Sep 19, 2023
1bc1b84
WIP
mpivchev Sep 19, 2023
fcbb6e3
WIP
mpivchev Sep 19, 2023
1812bfb
WIP
mpivchev Sep 19, 2023
c65c5dd
move rightBarButtonItems in viewWillAppear
marinofaggiana Sep 19, 2023
fc9d15a
WIP
mpivchev Sep 19, 2023
c2ea504
Merge branch '2399-aspect-ratio-in-media-view' of https://github.com/…
marinofaggiana Sep 19, 2023
3459e8d
Update NCViewerMediaPage.swift
marinofaggiana Sep 19, 2023
0145666
Add sorting
mpivchev Sep 19, 2023
d5db2d3
Merge branch '2399-aspect-ratio-in-media-view' of https://github.com/…
mpivchev Sep 19, 2023
1ec093e
Fix toolbar icons, add trash icon
mpivchev Sep 20, 2023
ab91eab
WIP
mpivchev Aug 28, 2023
6fcfd5b
WIP
mpivchev Aug 28, 2023
4e6ba95
Make view model
mpivchev Aug 28, 2023
663c7d4
WIP
mpivchev Aug 31, 2023
00e29a9
WIP
mpivchev Sep 4, 2023
fdb8d2e
WIP
mpivchev Sep 5, 2023
8e346db
WIP
mpivchev Sep 5, 2023
e8b4230
Separate components
mpivchev Sep 5, 2023
a31932b
WIP
mpivchev Sep 5, 2023
083a4b0
Add top header
mpivchev Sep 5, 2023
506bd46
Add notifications
mpivchev Sep 11, 2023
98cffdb
Try to get first cell in list
mpivchev Sep 11, 2023
3667c95
Add date update
mpivchev Sep 12, 2023
1cb48e2
Refactor
mpivchev Sep 12, 2023
0227e6c
WIP
mpivchev Sep 12, 2023
d467029
Reload when switching accounts
mpivchev Sep 12, 2023
190322e
Add shimmer and old and new media loading
mpivchev Sep 13, 2023
f0e1949
Work on top section
mpivchev Sep 13, 2023
71b967a
Mark no thumbnails
mpivchev Sep 14, 2023
d2ebc67
Add pull to refresh
mpivchev Sep 15, 2023
063447c
Add animated color change on top bar
mpivchev Sep 15, 2023
56a7b22
Adjust
mpivchev Sep 15, 2023
e5ac7b8
Adjust
mpivchev Sep 15, 2023
019f09b
Add actions to some options
mpivchev Sep 18, 2023
a46c312
Design work
mpivchev Sep 18, 2023
a2ad767
WIP with pushing VCs (kill me)
mpivchev Sep 19, 2023
46039bd
WIP
mpivchev Sep 19, 2023
8c592b3
WIP
mpivchev Sep 19, 2023
1368edc
WIP
mpivchev Sep 19, 2023
d4fd429
WIP
mpivchev Sep 19, 2023
27e2563
WIP
mpivchev Sep 19, 2023
783d7c3
WIP
mpivchev Sep 19, 2023
18ee310
Add sorting
mpivchev Sep 19, 2023
9363466
move rightBarButtonItems in viewWillAppear
marinofaggiana Sep 19, 2023
bd6e384
Update NCViewerMediaPage.swift
marinofaggiana Sep 19, 2023
62262c2
Fix toolbar icons, add trash icon
mpivchev Sep 20, 2023
44eb2a3
Delete photos support
mpivchev Sep 20, 2023
7469234
Merge branch 'develop' of https://github.com/nextcloud/ios into 2399-…
mpivchev Sep 20, 2023
111afc7
Remove lib
mpivchev Sep 20, 2023
487a194
cleaning
marinofaggiana Sep 20, 2023
b96101c
Update NCViewerMediaPage.storyboard
marinofaggiana Sep 20, 2023
297f668
revert
marinofaggiana Sep 20, 2023
656b9b2
Update NCViewerMediaPage.storyboard
marinofaggiana Sep 20, 2023
3dabb14
Update Main.storyboard
marinofaggiana Sep 20, 2023
2d0d7ce
Update Main.storyboard
marinofaggiana Sep 20, 2023
cbbb946
new
marinofaggiana Sep 20, 2023
f0730ed
test
marinofaggiana Sep 20, 2023
2060365
test
marinofaggiana Sep 20, 2023
aa67d2b
Fix build
mpivchev Sep 20, 2023
7087459
WIP
mpivchev Sep 20, 2023
5afac05
Merge branch 'hide-tabbar-media' into 2399-aspect-ratio-in-media-view
mpivchev Sep 20, 2023
8d0d2c1
WIP
mpivchev Sep 20, 2023
2b7e2fc
Fix merge issues
mpivchev Sep 20, 2023
74dd1a0
Refactor
mpivchev Sep 21, 2023
8ce1e3d
Refactor
mpivchev Sep 21, 2023
059f430
Add pull to refresh
mpivchev Sep 22, 2023
2f4da2c
WIP
mpivchev Sep 22, 2023
ac04b01
Solve thread issues
mpivchev Sep 22, 2023
b1120d7
WIP
mpivchev Sep 22, 2023
5137790
WIP
mpivchev Sep 25, 2023
2c3368e
Enable select media folder
mpivchev Sep 25, 2023
3d2b45a
Add other context options
mpivchev Sep 26, 2023
200a6cc
WIP
mpivchev Sep 26, 2023
4b65327
WIP
mpivchev Sep 26, 2023
95ac588
Add snapshot test
mpivchev Sep 26, 2023
13b45df
WIP
mpivchev Sep 26, 2023
244c5d5
WIP
mpivchev Sep 26, 2023
c9ca700
WIP
mpivchev Oct 2, 2023
8be9b8c
Fix
mpivchev Oct 2, 2023
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
182 changes: 181 additions & 1 deletion Nextcloud.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,27 @@
import Foundation
import SwiftUI

// Custom view modifier to track rotation and call an action
struct DeviceOrientationViewModifier: ViewModifier {
let action: (UIDeviceOrientation) -> Void

func body(content: Content) -> some View {
content
.onAppear()
.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
action(UIDevice.current.orientation)
}
}
}

extension SwiftUI.View {
func toVC() -> UIViewController {
let vc = UIHostingController (rootView: self)
vc.view.frame = UIScreen.main.bounds
return vc
}

func onRotate(perform action: @escaping (UIDeviceOrientation) -> Void) -> some View {
self.modifier(DeviceOrientationViewModifier(action: action))
}
}
4 changes: 4 additions & 0 deletions Tests/NextcloudSnapshotTests/NextcloudSnapshotTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ final class NextcloudSnapshotTests: XCTestCase {
func test_CapalitiesView() {
NCCapabilitiesView_Previews.snapshots.assertSnapshots(as: .imageHEIC)
}

func test_MediaView() {
NCMediaNew_Previews.snapshots.assertSnapshots(as: .imageHEIC)
}
}
7 changes: 6 additions & 1 deletion iOSClient/Extensions/Array+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import Foundation

// https://stackoverflow.com/questions/33861036/unique-objects-inside-a-array-swift/45023247#45023247
extension Array {

func unique<T: Hashable>(map: ((Element) -> (T))) -> [Element] {
var set = Set<T>() // the unique list kept in a Set for fast retrieval
var arrayOrdered = [Element]() // keeping the unique list of elements but ordered
Expand All @@ -37,4 +36,10 @@ extension Array {

return arrayOrdered
}

func chunked(into size: Int) -> [[Element]] {
return stride(from: 0, to: count, by: size).map {
Array(self[$0..<Swift.min($0 + size, count)])
}
}
}
16 changes: 16 additions & 0 deletions iOSClient/Extensions/Binding+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// Binding+Extension.swift
// Nextcloud
//
// Created by Milen on 20.09.23.
// Copyright © 2023 Marino Faggiana. All rights reserved.
//

import SwiftUI

prefix func ! (value: Binding<Bool>) -> Binding<Bool> {
Binding<Bool>(
get: { !value.wrappedValue },
set: { value.wrappedValue = !$0 }
)
}
66 changes: 33 additions & 33 deletions iOSClient/Main/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="FkP-Lh-8zt">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="FkP-Lh-8zt">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21678"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22129"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--NCMedia.storyboard-->
<scene sceneID="udp-lL-CYh">
<objects>
<viewControllerPlaceholder storyboardName="NCMedia" referencedIdentifier="NCMedia.storyboard" id="kO6-hz-Gsq" sceneMemberID="viewController">
<navigationItem key="navigationItem" id="3mJ-L2-Cmt"/>
</viewControllerPlaceholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="6gG-SV-Hvv" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="7770" y="899"/>
</scene>
<!--Tab Bar Controller-->
<scene sceneID="gY3-Ur-rTC">
<objects>
Expand All @@ -34,13 +24,13 @@
<segue destination="bSZ-tE-FEj" kind="relationship" relationship="viewControllers" id="qbu-nX-qCk"/>
<segue destination="hwM-4d-Afb" kind="relationship" relationship="viewControllers" id="tds-0Q-7Zf"/>
<segue destination="Cc7-4O-z6Q" kind="relationship" relationship="viewControllers" id="YKg-LH-tor"/>
<segue destination="Npr-vu-PSD" kind="relationship" relationship="viewControllers" id="XeU-GF-etm"/>
<segue destination="RF7-gD-gsF" kind="relationship" relationship="viewControllers" id="rvt-kL-0eL"/>
<segue destination="1Z8-Bx-Dqo" kind="relationship" relationship="viewControllers" id="z6l-ei-IMY"/>
</connections>
</tabBarController>
<placeholder placeholderIdentifier="IBFirstResponder" id="d2B-Yg-rp2" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="7071" y="-556"/>
<point key="canvasLocation" x="6929" y="-527"/>
</scene>
<!--File-->
<scene sceneID="dMv-43-hWy">
Expand Down Expand Up @@ -80,25 +70,6 @@
</objects>
<point key="canvasLocation" x="6367" y="327"/>
</scene>
<!--Media-->
<scene sceneID="IuY-Iu-oAm">
<objects>
<navigationController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="Npr-vu-PSD" sceneMemberID="viewController">
<tabBarItem key="tabBarItem" title="Media" id="5cw-bP-7It"/>
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" largeTitles="YES" id="ixg-Pw-TNO">
<rect key="frame" x="0.0" y="48" width="414" height="96"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="kO6-hz-Gsq" kind="relationship" relationship="rootViewController" id="9zw-1n-Dhk"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="cZf-pk-3Bd" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="7771" y="327"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="cip-AF-Ks2">
<objects>
Expand Down Expand Up @@ -263,6 +234,35 @@
</objects>
<point key="canvasLocation" x="8458" y="899"/>
</scene>
<!--Media-->
<scene sceneID="cqe-8g-lRj">
<objects>
<navigationController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="RF7-gD-gsF" sceneMemberID="viewController">
<tabBarItem key="tabBarItem" title="Media" id="Zte-Jp-EJV"/>
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" largeTitles="YES" id="Qwq-ub-joD">
<rect key="frame" x="0.0" y="48" width="414" height="96"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="CW8-KW-0pe" kind="relationship" relationship="rootViewController" id="Vb9-OI-DkF"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="L2K-7e-6T0" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="7768" y="327"/>
</scene>
<!--MediaUI Kit Wrapper-->
<scene sceneID="MtR-w7-Wmy">
<objects>
<viewController id="CW8-KW-0pe" customClass="NCMediaUIKitWrapper" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController">
<navigationItem key="navigationItem" id="oRV-lm-zC3"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="alF-L6-HqO" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="7852" y="1447"/>
</scene>
</scenes>
<resources>
<image name="tabBarPlus" width="80" height="80"/>
Expand Down
158 changes: 158 additions & 0 deletions iOSClient/Media/Cell/NCMediaCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
//
// NCMediaCellView.swift
// Nextcloud
//
// Created by Milen on 05.09.23.
// Copyright © 2023 Marino Faggiana. All rights reserved.
//

import SwiftUI
import VisibilityTrackingScrollView
import Shimmer
import NextcloudKit

enum ContextMenuSelection {
case addToFavorites, details, openIn, saveToPhotos, viewInFolder, modify, delete
}

struct NCMediaCell: View {
let thumbnail: ScaledThumbnail
let shrinkRatio: CGFloat
@Binding var isInSelectMode: Bool
@State private var isSelected = false
let onSelected: (ScaledThumbnail, Bool) -> Void
let onContextMenuItemSelected: (ScaledThumbnail, ContextMenuSelection) -> Void

@State var isFavorite: Bool

@State private var showDeleteConfirmation = false

var body: some View {
let image = Image(uiImage: thumbnail.image)
.resizable()

ZStack(alignment: .center) {
if thumbnail.isPlaceholderImage {
image
.foregroundColor(Color(uiColor: .systemGray4))
.scaledToFit()
.frame(width: 40)
} else {
image
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.overlay(alignment: .bottomLeading) {
if thumbnail.metadata.isVideo, !thumbnail.isPlaceholderImage {
Image(systemName: "play.fill")
.resizable()
.foregroundColor(Color(uiColor: .white))
.scaledToFit()
.frame(width: 16)
.padding([.leading, .bottom], 10)
}
}
.overlay {
if isInSelectMode, isSelected {
Color.black.opacity(0.6).frame(maxWidth: .infinity)
}
}
.overlay(alignment: .bottomTrailing) {
if isInSelectMode, isSelected {
Image(systemName: "checkmark.circle.fill")
.resizable()
.foregroundColor(.blue)
.background(.white)
.clipShape(Circle())
.scaledToFit()
.frame(width: 20)
.padding([.trailing, .bottom], 10)
}
}
.frame(width: CGFloat(thumbnail.scaledSize.width * shrinkRatio), height: CGFloat(thumbnail.scaledSize.height * shrinkRatio))
.background(Color(uiColor: .systemGray6))
.onTapGesture {
if isInSelectMode { isSelected.toggle() }
onSelected(thumbnail, isSelected)
}
.onChange(of: isInSelectMode) { newValue in
isSelected = !newValue
}
.contextMenu(menuItems: {
Button {
onContextMenuItemSelected(thumbnail, .details)
} label: {
Label(NSLocalizedString("_details_", comment: ""), systemImage: "info")
}

Button {
isFavorite.toggle()
onContextMenuItemSelected(thumbnail, .addToFavorites)
} label: {
Label(isFavorite ?
NSLocalizedString("_remove_favorites_", comment: "") :
NSLocalizedString("_add_favorites_", comment: ""), systemImage: "star.fill")
}

Button {
onContextMenuItemSelected(thumbnail, .openIn)
} label: {
Label(NSLocalizedString("_open_in_", comment: ""), systemImage: "square.and.arrow.up")
}

Button {
onContextMenuItemSelected(thumbnail, .saveToPhotos)
} label: {
Label(NSLocalizedString("_save_selected_files_", comment: ""), systemImage: "square.and.arrow.down")
}

Button {
onContextMenuItemSelected(thumbnail, .viewInFolder)
} label: {
Label(NSLocalizedString("_view_in_folder_", comment: ""), systemImage: "folder.fill")
}

Button {
onContextMenuItemSelected(thumbnail, .modify)
} label: {
Label(NSLocalizedString("_modify_", comment: ""), systemImage: "pencil.tip.crop.circle")
}

Button(role: .destructive) {
showDeleteConfirmation = true
} label: {
Label(NSLocalizedString("_delete_file_", comment: ""), systemImage: "trash")
}
})
.confirmationDialog("", isPresented: $showDeleteConfirmation) {
Button(NSLocalizedString("_delete_file_", comment: ""), role: .destructive) {
onContextMenuItemSelected(thumbnail, .delete)
}
}
}
}

struct NCMediaLoadingCell: View {
let itemsInRow: Int
let metadata: tableMetadata
let geometryProxy: GeometryProxy
let spacing: CGFloat

let gradient = Gradient(colors: [
.black.opacity(0.4),
.black.opacity(0.7),
.black.opacity(0.4)
])

var body: some View {
ZStack {
Image(uiImage: UIImage())
.resizable()
.trackVisibility(id: CCUtility.getTitleSectionDate(metadata.date as Date) ?? "")// TODO: Fix spacing

Check warning on line 151 in iOSClient/Media/Cell/NCMediaCell.swift

View workflow job for this annotation

GitHub Actions / Lint

Todo Violation: TODOs should be resolved (Fix spacing) (todo)
.aspectRatio(1.5, contentMode: .fit)
.frame(width: (geometryProxy.size.width - spacing) / CGFloat(itemsInRow))
.redacted(reason: .placeholder)
.shimmering(gradient: gradient, bandSize: 0.7)
}
}
}
Loading
Loading