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

[milestone/12.0.1] Milestone 12.0.1 #1220

Merged
merged 12 commits into from
Jun 20, 2023
Merged
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