Skip to content

Commit

Permalink
[milestone/12.0.1] Milestone 12.0.1 (#1220)
Browse files Browse the repository at this point in the history
* - BrowserNavigationViewController:
	- add ability to show/hide navigation bar (with or without animation)
	- add convenience accessor to UIViewController to access the enclosing browserNavigationViewController
- Branding+App: fix SwiftLint warnings
- PDFViewerViewController: hide navigation bar via browserNavigationController rather than navigationController (fix finding (7))

* - UIView+EmbedLayout: add new .safeAreaWithKeyboardAnchorSet property for laying out the view in a keyboard-responsive manner
- CollectionViewController: add .compressForKeyboard property that layouts the UICollectionView in a keyboard-responsive manner
- ShareViewController: adopt compressForKeyboard
- ClientItemViewController: adopt compressForKeyboard
- fixes finding (1) in #1095

* - fix finding (9) in #1095

* - fix finding (12) in #1095

* - ComposedMessageView: apply syntactic sugar
- MediaDisplayViewController: when streaming, show a loading indicator (fixing finding (5) in #1095)

* - fix localization typo

* - MediaDisplayViewController: show download indicator when downloading video files (fixing part 2 of finding (5) in #1095)

* - BottomButtonBar: vertically align also the prompt label to selectButton.centerYAnchor
- ClientLocationPicker: prevent usage of .keyboardLayoutGuide to fix finding (13) in #1220 (misplaced select button after navigating to Files view)
- CollectionViewController: use the .safeAreaWithKeyboardAnchorSet for the whole stack view rather than just the collection view

* - new build and version number
- added in-app release notes
- added calens release notes

* Calens changelog updated

* updated fastlane release notes

---------

Co-authored-by: Matthias Hühne <github@hosy.de>
Co-authored-by: hosy <hosy@users.noreply.github.com>
Co-authored-by: Matthias Hühne <mhuehne@owncloud.com>
  • Loading branch information
4 people authored Jun 20, 2023
1 parent 0b6ffaa commit b242f83
Show file tree
Hide file tree
Showing 21 changed files with 277 additions and 145 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
Changelog for ownCloud iOS Client [12.0.1] (2023-06-15)
=======================================
The following sections list the changes in ownCloud iOS Client 12.0.1 relevant to
ownCloud admins and users.

[12.0.1]: https://github.com/owncloud/ios-app/compare/milestone/12.0.0...milestone/12.0.1

Summary
-------

* Bugfix - Several Bug Fixes: [#1220](https://github.com/owncloud/ios-app/pull/1220)

Details
-------

* Bugfix - Several Bug Fixes: [#1220](https://github.com/owncloud/ios-app/pull/1220)

Fixed keyboard, media streaming, full screen mode, offline indicator, duplicated sharing
option, and UI issues.

https://github.com/owncloud/ios-app/pull/1220

Changelog for ownCloud iOS Client [12.0.0] (2023-06-12)
=======================================
The following sections list the changes in ownCloud iOS Client 12.0.0 relevant to
Expand Down
5 changes: 5 additions & 0 deletions changelog/12.0.1_2023-06-15/1220
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Bugfix: Several Bug Fixes

Fixed keyboard, media streaming, full screen mode, offline indicator, duplicated sharing option, and UI issues.

https://github.com/owncloud/ios-app/pull/1220
27 changes: 2 additions & 25 deletions fastlane/metadata-emm/en-US/release_notes.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,3 @@
Version 12 Major Release
Rearchitectured for iOS 15 and later.
Bug Fixes
Fixed keyboard, media streaming, full screen mode, offline indicator, duplicated sharing option, and UI issues.

• ownCloud Infinite Scale support
Support for Spaces, Authenticated WebFinger and other new oCIS features.

• New Search Capabilities
Powerful new search UI, saved searches and search templates.

• New Navigation
Navigate via the new sidebar, breadcrumbs and browser controls.

• Role-based Sharing Interface
The new role-based sharing user interface makes creating and editing shares and links even easier.

• Grid View Modes
Switch between list and several, different grid modes to display your folder's contents in new ways.

• App Provider support
Create and edit new documents through app providers on servers that support them.

• Improved Theming
The updated dark and light themes make use of a new, CSS-based theming system.

• MDM Enhancements
Many new MDM parameters.
27 changes: 2 additions & 25 deletions fastlane/metadata-owncloud-online/en-US/release_notes.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,3 @@
Version 12 Major Release
Rearchitectured for iOS 15 and later.
Bug Fixes
Fixed keyboard, media streaming, full screen mode, offline indicator, duplicated sharing option, and UI issues.

• ownCloud Infinite Scale support
Support for Spaces, Authenticated WebFinger and other new oCIS features.

• New Search Capabilities
Powerful new search UI, saved searches and search templates.

• New Navigation
Navigate via the new sidebar, breadcrumbs and browser controls.

• Role-based Sharing Interface
The new role-based sharing user interface makes creating and editing shares and links even easier.

• Grid View Modes
Switch between list and several, different grid modes to display your folder's contents in new ways.

• App Provider support
Create and edit new documents through app providers on servers that support them.

• Improved Theming
The updated dark and light themes make use of a new, CSS-based theming system.

• MDM Enhancements
Many new MDM parameters.
27 changes: 2 additions & 25 deletions fastlane/metadata/en-US/release_notes.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,3 @@
Version 12 Major Release
Rearchitectured for iOS 15 and later.
Bug Fixes
Fixed keyboard, media streaming, full screen mode, offline indicator, duplicated sharing option, and UI issues.

• ownCloud Infinite Scale support
Support for Spaces, Authenticated WebFinger and other new oCIS features.

• New Search Capabilities
Powerful new search UI, saved searches and search templates.

• New Navigation
Navigate via the new sidebar, breadcrumbs and browser controls.

• Role-based Sharing Interface
The new role-based sharing user interface makes creating and editing shares and links even easier.

• Grid View Modes
Switch between list and several, different grid modes to display your folder's contents in new ways.

• App Provider support
Create and edit new documents through app providers on servers that support them.

• Improved Theming
The updated dark and light themes make use of a new, CSS-based theming system.

• MDM Enhancements
Many new MDM parameters.
2 changes: 1 addition & 1 deletion ownCloud File Provider UI/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<key>NSExtensionFileProviderActionIdentifier</key>
<string>com.owncloud.FileProviderUI.Share</string>
<key>NSExtensionFileProviderActionName</key>
<string>Share</string>
<string>Share by cloud</string>
</dict>
</array>
<key>NSExtensionMainStoryboard</key>
Expand Down
8 changes: 4 additions & 4 deletions ownCloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -5137,8 +5137,8 @@
APP_BUILD_FLAGS = "$(inherited)";
APP_BUILD_FLAGS_SWIFT = "$(APP_BUILD_FLAGS)";
APP_PRODUCT_NAME = ownCloud;
APP_SHORT_VERSION = 12.0;
APP_VERSION = 267;
APP_SHORT_VERSION = 12.0.1;
APP_VERSION = 268;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
Expand Down Expand Up @@ -5207,8 +5207,8 @@
APP_BUILD_FLAGS = "$(inherited)";
APP_BUILD_FLAGS_SWIFT = "$(APP_BUILD_FLAGS)";
APP_PRODUCT_NAME = ownCloud;
APP_SHORT_VERSION = 12.0;
APP_VERSION = 267;
APP_SHORT_VERSION = 12.0.1;
APP_VERSION = 268;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
Expand Down
176 changes: 125 additions & 51 deletions ownCloud/Client/Viewer/Media/MediaDisplayViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,25 +71,43 @@ class MediaDisplayViewController : DisplayViewController {
NotificationCenter.default.removeObserver(self, name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
}

override func viewDidLoad() {
super.viewDidLoad()

playerViewController = AVPlayerViewController()

guard let playerViewController = playerViewController else { return }

addChild(playerViewController)
self.view.addSubview(playerViewController.view)
playerViewController.didMove(toParent: self)
var showLoadingIndicator: Bool = false {
didSet {
if oldValue != showLoadingIndicator {
if showLoadingIndicator {
// Show loading indicator
let indeterminateProgress: Progress = .indeterminate()
indeterminateProgress.isCancellable = false

let messageView = ComposedMessageView.infoBox(additionalElements: [
.spacing(25),
.progressCircle(with: indeterminateProgress),
.spacing(25),
.title("Loading…".localized, alignment: .centered)
], withRoundedBackgroundView: true)

loadingIndicator = messageView
} else {
// Remove loading indicator
loadingIndicator = nil
}
}
}
}

playerViewController.view.translatesAutoresizingMaskIntoConstraints = false
private var loadingIndicator: ComposedMessageView? {
willSet {
loadingIndicator?.removeFromSuperview()
}
didSet {
if let loadingIndicator {
view.embed(centered: loadingIndicator)
}
}
}

NSLayoutConstraint.activate([
playerViewController.view.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
playerViewController.view.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),
playerViewController.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
playerViewController.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor)
])
override func viewDidLoad() {
super.viewDidLoad()

NotificationCenter.default.addObserver(self, selector: #selector(handleDidEnterBackgroundNotification), name: UIApplication.didEnterBackgroundNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleWillEnterForegroundNotification), name: UIApplication.willEnterForegroundNotification, object: nil)
Expand Down Expand Up @@ -131,7 +149,28 @@ class MediaDisplayViewController : DisplayViewController {
return (OCAppIdentity.shared.userDefaults?.downloadMediaFiles ?? false)
}

private var timeControlStatusObservation: NSKeyValueObservation?

override func renderItem(completion: @escaping (Bool) -> Void) {
if playerViewController == nil {
playerViewController = AVPlayerViewController()

if let playerViewController {
addChild(playerViewController)
self.view.addSubview(playerViewController.view)
playerViewController.didMove(toParent: self)

playerViewController.view.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
playerViewController.view.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
playerViewController.view.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),
playerViewController.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
playerViewController.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor)
])
}
}

if let directURL = itemDirectURL {
playerItemStatusObservation?.invalidate()
playerItemStatusObservation = nil
Expand All @@ -149,58 +188,38 @@ class MediaDisplayViewController : DisplayViewController {
if player == nil {
player = AVPlayer(playerItem: playerItem)
player?.allowsExternalPlayback = true
if let playerViewController = self.playerViewController {
if let playerViewController {
playerViewController.updatesNowPlayingInfoCenter = false

if UIApplication.shared.applicationState == .active {
playerViewController.player = player
}
}

// Add artwork to the player overlay if corresponding meta data item is available in the asset
if !(player?.isVideoAvailable ?? false), let artworkMetadataItem = asset.commonMetadata.filter({$0.commonKey == AVMetadataKey.commonKeyArtwork}).first,
let imageData = artworkMetadataItem.dataValue,
let overlayView = playerViewController?.contentOverlayView {

if let artworkImage = UIImage(data: imageData) {

// Construct image view overlay for AVPlayerViewController
let imageView = UIImageView(image: artworkImage)
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
playerViewController?.contentOverlayView?.addSubview(imageView)

NSLayoutConstraint.activate([
imageView.leadingAnchor.constraint(equalTo: overlayView.leadingAnchor),
imageView.trailingAnchor.constraint(equalTo: overlayView.trailingAnchor),
imageView.topAnchor.constraint(equalTo: overlayView.topAnchor),
imageView.bottomAnchor.constraint(equalTo: overlayView.bottomAnchor)
])

// Create MPMediaItemArtwork to be shown in 'now playing' in the lock screen
mediaItemArtwork = MPMediaItemArtwork(boundsSize: artworkImage.size, requestHandler: { (_) -> UIImage in
return artworkImage
})
}
}

// Extract title meta-data item
mediaItemTitle = asset.commonMetadata.filter({$0.commonKey == AVMetadataKey.commonKeyTitle}).first?.value as? String
// Start with the loading indicator active
showLoadingIndicator = true

// Extract artist meta-data item
mediaItemArtist = asset.commonMetadata.filter({$0.commonKey == AVMetadataKey.commonKeyArtist}).first?.value as? String
// .. it will be updated as soon as the player starts playing ..
timeControlStatusObservation = player?.observe(\AVPlayer.timeControlStatus, changeHandler: { [weak self] player, change in
self?.updateLoadingIndicator()
})

// Setup player status observation handler
playerStatusObservation = player!.observe(\AVPlayer.status, options: [.initial, .new], changeHandler: { [weak self] (player, _) in
if player.status == .readyToPlay {
self?.updateMediaMetadata()

self?.setupRemoteTransportControls()

try? AVAudioSession.sharedInstance().setCategory(.playback)
try? AVAudioSession.sharedInstance().setActive(true)

if (self?.hasFocus)! {
// .. with playback starting here.
self?.player?.play()
} else {
// .. or the loading indicator being updated when the file is ready to play, here.
self?.updateLoadingIndicator()
}

self?.updateNowPlayingInfoCenter()
Expand All @@ -218,6 +237,55 @@ class MediaDisplayViewController : DisplayViewController {
}
}

private func updateLoadingIndicator() {
if let player {
let showLoadingIndicator = (player.timeControlStatus == .waitingToPlayAtSpecifiedRate)

OnMainThread(inline: true) {
self.showLoadingIndicator = showLoadingIndicator
}
}
}

private func updateMediaMetadata() {
guard let asset = playerItem?.asset else { return }

// Add artwork to the player overlay if corresponding meta data item is available in the asset
if !(player?.isVideoAvailable ?? false), let artworkMetadataItem = asset.commonMetadata.filter({$0.commonKey == AVMetadataKey.commonKeyArtwork}).first,
let imageData = artworkMetadataItem.dataValue,
let overlayView = playerViewController?.contentOverlayView {

if let artworkImage = UIImage(data: imageData) {

// Construct image view overlay for AVPlayerViewController
OnMainThread(inline: true) { [weak self] in
let imageView = UIImageView(image: artworkImage)
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
self?.playerViewController?.contentOverlayView?.addSubview(imageView)

NSLayoutConstraint.activate([
imageView.leadingAnchor.constraint(equalTo: overlayView.leadingAnchor),
imageView.trailingAnchor.constraint(equalTo: overlayView.trailingAnchor),
imageView.topAnchor.constraint(equalTo: overlayView.topAnchor),
imageView.bottomAnchor.constraint(equalTo: overlayView.bottomAnchor)
])
}

// Create MPMediaItemArtwork to be shown in 'now playing' in the lock screen
mediaItemArtwork = MPMediaItemArtwork(boundsSize: artworkImage.size, requestHandler: { (_) -> UIImage in
return artworkImage
})
}
}

// Extract title meta-data item
mediaItemTitle = asset.commonMetadata.filter({$0.commonKey == AVMetadataKey.commonKeyTitle}).first?.value as? String

// Extract artist meta-data item
mediaItemArtist = asset.commonMetadata.filter({$0.commonKey == AVMetadataKey.commonKeyArtist}).first?.value as? String
}

private func present(error:Error?) {
guard let error = error else { return }

Expand All @@ -230,12 +298,18 @@ class MediaDisplayViewController : DisplayViewController {
}
}

private var isInBackground: Bool = false {
didSet {
playerViewController?.player = isInBackground ? nil : player
}
}

@objc private func handleDidEnterBackgroundNotification() {
playerViewController?.player = nil
isInBackground = true
}

@objc private func handleWillEnterForegroundNotification() {
playerViewController?.player = player
isInBackground = false
}

@objc private func handleAVPlayerItem(notification:Notification) {
Expand Down
2 changes: 1 addition & 1 deletion ownCloud/Client/Viewer/PDF/PDFViewerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class PDFViewerViewController: DisplayViewController, DisplayExtension, UIPopove

private var fullScreen: Bool = false {
didSet {
self.navigationController?.setNavigationBarHidden(fullScreen, animated: true)
browserNavigationViewController?.setNavigationBarHidden(fullScreen, animated: true)
isFullScreenModeEnabled = fullScreen
pageCountButton.isHidden = fullScreen
pageCountContainerView.isHidden = fullScreen
Expand Down
Loading

0 comments on commit b242f83

Please sign in to comment.