diff --git a/GraphTableViewController.swift b/GraphTableViewController.swift
new file mode 100644
index 0000000000000000000000000000000000000000..793f4b02cbb56ce999bcecfc03376d10e515f6d3
--- /dev/null
+++ b/GraphTableViewController.swift
@@ -0,0 +1,294 @@
+/*****************************************************************************
+ * GraphTableViewController.swift
+ *
+ * Copyright © 2022 VLC authors and VideoLAN
+ *
+ * Authors: Diogo Simao Marques <diogo.simaomarquespro@gmail.com>
+ *
+ * Refer to the COPYING file of the official project for license.
+ *****************************************************************************/
+
+import UIKit
+import MSGraphClientModels
+
+@objc (VLCGraphTableViewController)
+class GraphTableViewController: VLCCloudStorageTableViewController {
+    // MARK: - Properties
+    private lazy var graphViewController: GraphViewController = {
+        let graphViewController = GraphViewController.sharedObject
+        graphViewController.setPresentingViewController(with: self)
+        graphViewController.delegate = self
+        return graphViewController
+    }()
+
+    // MARK: - Init
+    override func viewDidLoad() {
+        super.viewDidLoad()
+
+        prepareMSGraphControllerIfNeeded()
+
+        navigationItem.titleView = UIImageView(image: UIImage(named: "OneDriveWhite"))
+        cloudStorageLogo.image = UIImage(named: "OneDriveWhite")
+        cloudStorageLogo.sizeToFit()
+        cloudStorageLogo.center = view.center
+    }
+
+    override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
+
+        if #available(iOS 11.0, *) {
+            navigationController?.navigationBar.prefersLargeTitles = false
+        }
+
+        updateViewAfterSessionChange()
+        authorizationInProgress = false
+        prepareMSGraphControllerIfNeeded()
+        tableView.dataSource = self
+    }
+
+    // MARK: - Overriding methods
+    override func goBack() {
+        let currentItemID = graphViewController.currentItem?.entityId
+
+        if let currentItemID = currentItemID,
+           let rootItemID = graphViewController.getRootItemID(),
+           currentItemID != rootItemID {
+            if graphViewController.parentItem == nil
+                || rootItemID == graphViewController.parentItem?.entityId {
+                graphViewController.currentItem = nil
+            } else {
+                graphViewController.currentItem = graphViewController.parentItem
+                graphViewController.loadParentItem()
+            }
+
+            if let itemName = graphViewController.currentItem?.name {
+                title = itemName
+            }
+
+            activityIndicator.startAnimating()
+            graphViewController.loadCurrentItem()
+        } else {
+            navigationController?.popViewController(animated: true)
+        }
+    }
+
+    override func playAllAction(_ sender: Any!) {
+        let mediaList = createMediaList()
+        streamMediaList(mediaList: mediaList)
+    }
+
+    override func loginAction(_ sender: Any!) {
+        if !graphViewController.isAuthorized {
+            authorizationInProgress = true
+            graphViewController.loginWithViewController(presentingViewController: self)
+        } else {
+            graphViewController.logout()
+        }
+    }
+
+    override func sessionWasUpdated() {
+        DispatchQueue.main.async {
+            self.updateViewAfterSessionChange()
+            self.mediaListUpdated()
+        }
+    }
+
+    override func operationWithProgressInformationStarted() {
+        super.operationWithProgressInformationStarted()
+    }
+
+    override func operationWithProgressInformationStopped() {
+        super.operationWithProgressInformationStopped()
+    }
+
+    override func currentProgressInformation(_ progress: CGFloat) {
+        super.currentProgressInformation(progress)
+    }
+
+    override func updateProgressLabel(_ mediaName: String!) {
+        super.updateProgressLabel(mediaName)
+    }
+
+    // MARK: - Private helpers
+    private func prepareMSGraphControllerIfNeeded() {
+        if controller == nil {
+            controller = graphViewController
+        }
+    }
+
+    private func streamMediaList(mediaList: VLCMediaList) {
+///        Chunk of code to replace when the .isEmpty property will be available on VLCKit.
+//        if mediaList.isEmpty {
+        if mediaList.count < 1 {
+            return
+        }
+
+        let vpc: PlaybackService = PlaybackService.sharedInstance()
+        vpc.playMediaList(mediaList, firstIndex: 0, subtitlesFilePath: nil)
+    }
+
+    private func addMedia(to mediaList: VLCMediaList, itemName: String?, downloadUrl: String) {
+        let url = URL(string: downloadUrl)
+        if let url = url {
+            let media: VLCMedia = graphViewController.setMediaNameMetadata(VLCMedia(url: url), withName: itemName)
+            mediaList.add(media)
+        }
+    }
+
+    private func createMediaListWithMSGraphDriveItem(item: MSGraphDriveItem? = nil) -> VLCMediaList {
+        let folderItems = graphViewController.getCurrentListFiles()
+        let mediaList: VLCMediaList = VLCMediaList()
+        let downloadUrlDictionary = graphViewController.getDownloadUrlDictionary()
+
+        if let item = item,
+           let downloadUrl = downloadUrlDictionary[item] {
+            addMedia(to: mediaList, itemName: item.name, downloadUrl: downloadUrl)
+        }
+
+        for folderItem in folderItems {
+            if folderItem.folder != nil || folderItem == item {
+                continue
+            }
+
+            if let downloadUrl = downloadUrlDictionary[folderItem] {
+                addMedia(to: mediaList, itemName: folderItem.name, downloadUrl: downloadUrl)
+            }
+        }
+
+        return mediaList
+    }
+
+    private func createMediaList() -> VLCMediaList {
+        return createMediaListWithMSGraphDriveItem()
+    }
+}
+
+// MARK: - VLCCloudStorageTableViewCellProtocol
+extension GraphTableViewController: VLCCloudStorageTableViewCellProtocol {
+    func triggerDownload(for cell: VLCCloudStorageTableViewCell!) {
+        let indexPath: IndexPath? = tableView.indexPath(for: cell)
+        let currentItems: [MSGraphDriveItem] = graphViewController.getCurrentListFiles()
+
+        guard let indexPath = indexPath,
+              indexPath.row < currentItems.count else {
+            preconditionFailure("GraphTableViewController: Invalid range.")
+        }
+
+        let selectedItem: MSGraphDriveItem = currentItems[indexPath.row]
+        var selectedItemName: String = ""
+        if let name = selectedItem.name {
+            selectedItemName = name
+        }
+
+        if selectedItem.size < UIDevice.current.freeDiskSpace.int64Value {
+            let alertController = UIAlertController(title: NSLocalizedString("DROPBOX_DOWNLOAD", comment: ""),
+                                                    message: String(format: NSLocalizedString("DROPBOX_DL_LONG", comment: ""),
+                                                                    selectedItemName, UIDevice.current.model),
+                                                    preferredStyle: .alert)
+
+            let downloadAction = UIAlertAction(title: NSLocalizedString("BUTTON_DOWNLOAD", comment: ""),
+                                               style: .default,
+                                               handler: { _ in
+                self.graphViewController.startDownloadingDriveItem(item: selectedItem)
+            })
+
+            let cancelAction = UIAlertAction(title: NSLocalizedString("BUTTON_CANCEL", comment: ""),
+                                             style: .cancel,
+                                             handler: nil)
+
+            alertController.addAction(downloadAction)
+            alertController.addAction(cancelAction)
+            present(alertController, animated: true)
+        } else {
+            let alertController = UIAlertController(title: NSLocalizedString("DISK_FULL", comment: ""),
+                                                    message: String(format: NSLocalizedString("DISK_FULL_FORMAT", comment: ""),
+                                                                    selectedItemName, UIDevice.current.model),
+                                                    preferredStyle: .alert)
+
+            let okAction = UIAlertAction(title: NSLocalizedString("BUTTON_OK", comment: ""),
+                                         style: .cancel,
+                                         handler: nil)
+
+            alertController.addAction(okAction)
+            present(alertController, animated: true)
+        }
+    }
+}
+
+// MARK: - UITableViewDataSource
+extension GraphTableViewController: UITableViewDataSource {
+    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return graphViewController.getCurrentListFiles().count
+    }
+
+    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        let cellIdentifier: String = "OneDriveCell"
+
+        var cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)
+
+        if cell == nil {
+            cell = VLCCloudStorageTableViewCell(reuseIdentifier: cellIdentifier)
+        }
+
+        if let cell = cell as? VLCCloudStorageTableViewCell,
+           indexPath.row < graphViewController.getCurrentListFiles().count {
+            cell.delegate = self
+            cell.oneDriveFile = graphViewController.getCurrentListFiles()[indexPath.row]
+            cell.titleLabel.text = graphViewController.getCurrentListFiles()[indexPath.row].name
+            return cell
+        }
+
+        return VLCCloudStorageTableViewCell(reuseIdentifier: cellIdentifier)
+    }
+}
+
+// MARK: - UITableViewDelegate
+extension GraphTableViewController: UITableViewDelegate {
+    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        let currentItems = graphViewController.getCurrentListFiles()
+        let row = indexPath.row
+
+        guard row < currentItems.count else {
+            return
+        }
+
+        let selectedItem: MSGraphDriveItem = currentItems[row]
+
+        if selectedItem.folder != nil {
+            self.activityIndicator.startAnimating()
+            graphViewController.parentItem = graphViewController.currentItem
+            graphViewController.currentItem = selectedItem
+            graphViewController.loadCurrentItem()
+            self.title = selectedItem.name
+            tableView.reloadData()
+        } else {
+            let downloadUrlDictionary = graphViewController.getDownloadUrlDictionary()
+            if let downloadUrl = downloadUrlDictionary[selectedItem] {
+                var mediaList: VLCMediaList
+                let url = URL(string: downloadUrl)
+                var mediaToPlay: VLCMedia = VLCMedia(url: url!)
+                mediaToPlay = graphViewController.setMediaNameMetadata(mediaToPlay, withName: selectedItem.name)
+
+                if !UserDefaults.standard.bool(forKey: kVLCAutomaticallyPlayNextItem) {
+                    mediaList = VLCMediaList(array: [mediaToPlay])
+                } else {
+                    mediaList = createMediaListWithMSGraphDriveItem(item: selectedItem)
+                }
+                streamMediaList(mediaList: mediaList)
+            } else {
+                let alertController = UIAlertController(title: NSLocalizedString("ERROR", comment: ""),
+                                                        message: NSLocalizedString("ONEDRIVE_MEDIA_WITHOUT_URL", comment: ""),
+                                                        preferredStyle: .alert)
+
+                let okAction = UIAlertAction(title: NSLocalizedString("BUTTON_OK", comment: ""),
+                                             style: .cancel,
+                                             handler: nil)
+
+                alertController.addAction(okAction)
+                present(alertController, animated: true)
+            }
+        }
+
+        self.tableView.deselectRow(at: indexPath, animated: false)
+    }
+}
diff --git a/GraphViewController.swift b/GraphViewController.swift
new file mode 100644
index 0000000000000000000000000000000000000000..d702208e340637c5c2b6d5ce02cd1b0103dcc751
--- /dev/null
+++ b/GraphViewController.swift
@@ -0,0 +1,618 @@
+/*****************************************************************************
+ * GraphViewController.swift
+ *
+ * Copyright © 2022 VLC authors and VideoLAN
+ *
+ * Authors: Diogo Simao Marques <diogo.simaomarquespro@gmail.com>
+ *
+ * Refer to the COPYING file of the official project for license.
+ *****************************************************************************/
+
+import UIKit
+import MSAL
+import MSGraphClientSDK
+import MSGraphClientModels
+import MSGraphMSALAuthProvider
+
+@objc (VLCGraphViewController)
+class GraphViewController: VLCCloudStorageController {
+    // MARK: - Properties
+    private let kClientID = "c7fbceea-ef4a-4a2e-9e54-72a3c333aa0b"
+    private let kRedirectUri = "msauth.com.example.vlc-ios://auth"
+    private let kAuthority = "https://login.microsoftonline.com/common"
+    private let kGraphEndpoint = "https://graph.microsoft.com/"
+
+    private let kScopes: [String] = ["user.read", "files.read"]
+
+    private var accessToken = String()
+    private var applicationContext: MSALPublicClientApplication?
+    private var webViewParameters: MSALWebviewParameters?
+
+    private var currentAccount: MSALAccount?
+
+    private var authenticationProvider: MSAuthenticationProvider?
+
+    lazy var currentItem: MSGraphDriveItem? = nil
+    lazy var parentItem: MSGraphDriveItem? = nil
+    private lazy var currentItems: [MSGraphDriveItem] = []
+    private lazy var downloadUrlDictionary: [MSGraphDriveItem: String] = [:]
+    private lazy var rootItemID: String? = nil
+    private var presentingViewController: UIViewController?
+
+    private lazy var pendingDownloads: [MSGraphDriveItem] = []
+    private var downloadInProgress: Bool = false
+    private var progress: Progress = Progress()
+
+    @objc static var sharedObject: GraphViewController = {
+        let sharedInstance = GraphViewController()
+        return sharedInstance
+    }()
+
+    // MARK: - Overriding properties
+    override var currentListFiles: [Any]! {
+        get { return currentItems }
+    }
+
+    override var isAuthorized: Bool {
+        get { return super.isAuthorized }
+        set { super.isAuthorized = newValue }
+    }
+
+    override var canPlayAll: Bool {
+        get { return !currentItems.isEmpty }
+    }
+
+    // MARK: - Overriding methods
+    override func logout() {
+        guard let applicationContext = applicationContext else {
+            return
+        }
+
+        guard let currentAccount = currentAccount else {
+            return
+        }
+
+        do {
+            let signoutParameters = MSALSignoutParameters(webviewParameters: webViewParameters!)
+            signoutParameters.signoutFromBrowser = false
+
+            applicationContext.signout(with: currentAccount, signoutParameters: signoutParameters, completionBlock: { (success, error) in
+                if let error = error {
+                    preconditionFailure("GraphViewController: Couldn't sign out account: \(error).")
+                }
+
+                self.accessToken = ""
+                self.updateCurrentAccount(account: nil)
+            })
+        }
+
+        delegate.mediaListUpdated()
+        if let presentingViewController = presentingViewController {
+            presentingViewController.navigationController?.popViewController(animated: true)
+        }
+
+        resetSession()
+    }
+
+    override func requestDirectoryListing(atPath path: String!) {
+        loadCurrentItem()
+    }
+
+    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
+        DispatchQueue.main.async {
+            if let progress: Progress = object as? Progress {
+                let expectedDowloadSize = CGFloat(progress.totalUnitCount)
+                let percentage = (progress.fractionCompleted * expectedDowloadSize) / 100
+                self.delegate.currentProgressInformation?(percentage)
+            }
+        }
+    }
+
+    // MARK: - Public helpers
+    func getCurrentListFiles() -> [MSGraphDriveItem] {
+        return currentItems
+    }
+
+    func getDownloadUrlDictionary() -> [MSGraphDriveItem: String] {
+        return downloadUrlDictionary
+    }
+
+    func getRootItemID() -> String? {
+        return rootItemID
+    }
+
+    func setPresentingViewController(with viewController: UIViewController) {
+        presentingViewController = viewController
+    }
+
+    // MARK: - Private helpers
+    private func resetSession() {
+        parentItem = nil
+        currentItem = nil
+        rootItemID = nil
+        isAuthorized = false
+        currentItems.removeAll()
+        downloadUrlDictionary.removeAll()
+        pendingDownloads.removeAll()
+    }
+
+    private func checkFileExtension(for item: MSGraphDriveItem) -> Bool {
+        if item.folder != nil || item.audio != nil || item.video != nil {
+            return true
+        } else if let itemName = item.name as? NSString,
+           itemName.isSupportedMediaFormat() {
+            return true
+        } else {
+            return false
+        }
+    }
+
+    @objc private func sessionWasUpdated() {
+        delegate.responds(to: #selector(sessionWasUpdated))
+        delegate.perform(#selector(sessionWasUpdated))
+    }
+
+    private func platformViewDidLoadSetup() {
+        NotificationCenter.default.addObserver(self,
+                                               selector: #selector(appCameToForeGround(notification:)),
+                                               name: UIApplication.willEnterForegroundNotification,
+                                               object: nil)
+    }
+
+    @objc private func appCameToForeGround(notification: Notification) {
+        loadCurrentAccount()
+    }
+
+    // MARK: - Authentication
+    func loginWithViewController(presentingViewController: UIViewController) {
+        self.presentingViewController = presentingViewController
+
+        if #available(iOS 11.0, *) {
+            UINavigationBar.appearance().prefersLargeTitles = false
+        }
+
+        do {
+            try initMSAL()
+        } catch let error {
+            preconditionFailure("GraphViewController: Unable to create the application context: \(error).")
+        }
+
+        webViewParameters = MSALWebviewParameters(authPresentationViewController: presentingViewController)
+
+        loadCurrentAccount()
+        platformViewDidLoadSetup()
+        callGraphAPI()
+    }
+
+    private func initMSAL() throws {
+        guard let authorityURL = URL(string: kAuthority) else {
+            preconditionFailure("GraphViewController: Unable to create authority URL.")
+        }
+
+        let authority = try MSALAADAuthority(url: authorityURL)
+        let msalConfiguration = MSALPublicClientApplicationConfig(clientId: kClientID, redirectUri: kRedirectUri, authority: authority)
+        applicationContext = try MSALPublicClientApplication(configuration: msalConfiguration)
+    }
+
+    private func callGraphAPI() {
+        loadCurrentAccount { (account) in
+            guard let currentAccount = account else {
+                self.acquireTokenInteractively()
+                return
+            }
+
+            self.acquireTokenSilently(currentAccount)
+        }
+    }
+
+    private func acquireTokenInteractively() {
+        guard let applicationContext = applicationContext else {
+            return
+        }
+
+        guard let webViewParameters = webViewParameters else {
+            return
+        }
+
+        let parameters = MSALInteractiveTokenParameters(scopes: kScopes, webviewParameters: webViewParameters)
+        parameters.promptType = .selectAccount
+
+        applicationContext.acquireToken(with: parameters) { (result, error) in
+            if let error = error {
+                preconditionFailure("GraphViewController: Couldn't acquire token: \(error).")
+            }
+
+            guard let result = result else {
+                preconditionFailure("GraphViewController: Couldn't retrieve token result.")
+            }
+
+            self.accessToken = result.accessToken
+            self.updateCurrentAccount(account: result.account)
+            self.load()
+        }
+    }
+
+    private func acquireTokenSilently(_ account: MSALAccount) {
+        guard let applicationContext = applicationContext else {
+            return
+        }
+
+        let parameters = MSALSilentTokenParameters(scopes: kScopes, account: account)
+        applicationContext.acquireTokenSilent(with: parameters) { (result, error) in
+            if let error = error {
+                let nsError = error as NSError
+                if nsError.domain == MSALErrorDomain {
+                    if nsError.code == MSALError.interactionRequired.rawValue {
+                        DispatchQueue.main.async {
+                            self.acquireTokenInteractively()
+                        }
+
+                        return
+                    }
+                }
+
+                return
+            }
+
+            guard let result = result else {
+                preconditionFailure("GraphViewController: Couldn't retrieve token result.")
+            }
+
+            self.accessToken = result.accessToken
+            self.load()
+        }
+    }
+
+    private func getGraphEndpoint() -> String {
+        if let currentItem = currentItem,
+           let rootItemID = rootItemID {
+            return kGraphEndpoint + "v1.0/drives/\(rootItemID)/items/\(currentItem.entityId)/children"
+        }
+
+        return kGraphEndpoint + "v1.0/me/drive/root/children"
+    }
+
+    typealias AccountCompletion = (MSALAccount?) -> Void
+
+    private func loadCurrentAccount(completion: AccountCompletion? = nil) {
+        guard let applicationContext = applicationContext else {
+            return
+        }
+
+        let msalParameters = MSALParameters()
+        msalParameters.completionBlockQueue = DispatchQueue.main
+
+        applicationContext.getCurrentAccount(with: msalParameters, completionBlock: { (currentAccount, previousAccount, error) in
+            if let error = error {
+                preconditionFailure("GraphViewController: Couldn't acquire current account: \(error).")
+            }
+
+            if let currentAccount = currentAccount {
+                self.updateCurrentAccount(account: currentAccount)
+
+                if let completion = completion {
+                    completion(self.currentAccount)
+                }
+
+                return
+            }
+
+            self.accessToken = ""
+            self.updateCurrentAccount(account: nil)
+
+            if let completion = completion {
+                completion(nil)
+            }
+        })
+    }
+
+    private func updateCurrentAccount(account: MSALAccount?) {
+        currentAccount = account
+    }
+
+    private func authSuccess() {
+        isAuthorized = true
+        DispatchQueue.main.async {
+            self.sessionWasUpdated()
+        }
+    }
+
+    private func authFailed() {
+        isAuthorized = false
+        DispatchQueue.main.async {
+            self.sessionWasUpdated()
+        }
+    }
+
+    // MARK: - Content load
+    func loadParentItem() {
+        guard let applicationContext = applicationContext else {
+            return
+        }
+
+        guard let parentId = parentItem?.parentReference?.itemReferenceId else {
+            currentItem = nil
+            parentItem = nil
+            return
+        }
+
+        var rootID: String = "root"
+        if let rootItemID = rootItemID {
+            rootID = rootItemID
+        }
+
+        let stringUrl: String = kGraphEndpoint + "v1.0/drives/\(rootID)/items/\(parentId)"
+        let url = URL(string: stringUrl)
+
+        guard let url = url else {
+            return
+        }
+
+        let urlRequest = NSMutableURLRequest(url: url)
+        urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
+        urlRequest.httpMethod = "GET"
+
+        let parameters = MSALAuthenticationProviderOptions(scopes: kScopes)
+
+        authenticationProvider = MSALAuthenticationProvider(publicClientApplication: applicationContext, andOptions: parameters)
+        let httpClient: MSHTTPClient = MSClientFactory.createHTTPClient(with: authenticationProvider)
+
+        var driveItem: MSGraphDriveItem? = nil
+
+        let meDataTask: MSURLSessionDataTask = httpClient.dataTask(with: urlRequest, completionHandler: { (data, response, error) in
+            if error != nil {
+                self.authFailed()
+                return
+            }
+
+            guard let data = data else {
+                preconditionFailure("GraphViewController: Couldn't retrieve data.")
+            }
+
+            driveItem = try! MSGraphDriveItem(data: data)
+            self.parentItem = driveItem
+        })
+        meDataTask.execute()
+    }
+
+    func loadCurrentItem() {
+        let itemID: String
+        if let currentItem = currentItem {
+            itemID = currentItem.entityId
+        } else {
+            itemID = "root"
+        }
+
+        guard let rootItemID = rootItemID else {
+            return
+        }
+
+        let stringUrl: String = kGraphEndpoint + "v1.0/drives/\(rootItemID)/items/\(itemID)/children"
+        let url = URL(string: stringUrl)
+
+        guard let url = url else {
+            return
+        }
+
+        let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: url)
+        urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
+        urlRequest.httpMethod = "GET"
+
+        load(with: urlRequest)
+    }
+
+    private func load(with request: NSMutableURLRequest? = nil) {
+        guard let applicationContext = applicationContext else {
+            return
+        }
+
+        let parameters = MSALAuthenticationProviderOptions(scopes: kScopes)
+
+        authenticationProvider = MSALAuthenticationProvider(publicClientApplication: applicationContext, andOptions: parameters)
+        let httpClient: MSHTTPClient = MSClientFactory.createHTTPClient(with: authenticationProvider)
+
+        let urlRequest: NSMutableURLRequest
+        if let request = request {
+            urlRequest = request
+        } else {
+            let url = URL(string: getGraphEndpoint())
+
+            guard let url = url else {
+                return
+            }
+
+            urlRequest = NSMutableURLRequest(url: url)
+            urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
+            urlRequest.httpMethod = "GET"
+        }
+
+        let meDataTask: MSURLSessionDataTask = httpClient.dataTask(with: urlRequest, completionHandler: { (data, response, error) in
+            if error != nil {
+                self.authFailed()
+                return
+            }
+
+            guard let data = data else {
+                preconditionFailure("GraphViewController: Couldn't retrieve data.")
+            }
+
+            let collection: MSCollection? = try? MSCollection(data: data)
+
+            guard let collection = collection else {
+                return
+            }
+
+            guard let collectionValue = collection.value else {
+                return
+            }
+
+            self.currentItems.removeAll()
+
+            for object in collectionValue {
+                let driveItem: MSGraphDriveItem? = MSGraphDriveItem(dictionary: object as? [AnyHashable: Any])
+                if let driveItem = driveItem,
+                   self.checkFileExtension(for: driveItem) {
+                    self.currentItems.append(driveItem)
+                    self.getDownloadURL(for: driveItem)
+
+                    if self.rootItemID == nil {
+                        self.rootItemID = driveItem.parentReference?.driveId
+                    }
+                }
+            }
+
+            self.authSuccess()
+        })
+        meDataTask.execute()
+    }
+
+    // MARK: - Download
+    func startDownloadingDriveItem(item: MSGraphDriveItem) {
+        pendingDownloads.append(item)
+        triggerNextDownload()
+    }
+
+    private func triggerNextDownload() {
+        if !pendingDownloads.isEmpty && !downloadInProgress {
+            downloadInProgress = true
+            guard let firstItem = pendingDownloads.first else {
+                return
+            }
+
+            downloadDriveItem(item: firstItem)
+        }
+    }
+
+    private func downloadStarted() {
+        delegate.operationWithProgressInformationStarted?()
+    }
+
+    private func downloadEnded() {
+        delegate.operationWithProgressInformationStopped?()
+        downloadInProgress = false
+        pendingDownloads.remove(at: 0)
+        triggerNextDownload()
+    }
+
+    private func downloadDriveItem(item: MSGraphDriveItem) {
+        guard let downloadUrl = downloadUrlDictionary[item] else {
+            return
+        }
+
+        let url = URL(string: downloadUrl)
+
+        guard let url = url else {
+            return
+        }
+
+        downloadStarted()
+
+        loadData(item: item, url: url) { (data, error) in
+            self.downloadEnded()
+        }
+    }
+
+    private func loadData(item: MSGraphDriveItem, url: URL, completion: @escaping (Data?, Error?) -> Void) {
+        let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
+        let fileCachePath = documentDirectory.appendingPathComponent(item.name!, isDirectory: true)
+
+        if FileManager().fileExists(atPath: fileCachePath.path) {
+            downloadEnded()
+            return
+        }
+
+        if let data = try? Data(contentsOf: fileCachePath) {
+            completion(data, nil)
+            return
+        }
+
+        download(url: url, toFile: fileCachePath, item: item) { (error) in
+            let data = try? Data(contentsOf: fileCachePath)
+            completion(data, error)
+        }
+    }
+
+    private func download(url: URL, toFile file: URL, item: MSGraphDriveItem, completion: @escaping (Error?) -> Void) {
+        let task = URLSession.shared.downloadTask(with: url) { (tempUrl, response, error) in
+            guard let tempUrl = tempUrl else {
+                completion(error)
+                return
+            }
+
+            do {
+                if FileManager.default.fileExists(atPath: file.path) {
+                    try FileManager.default.removeItem(at: file)
+                }
+
+                try FileManager.default.copyItem(at: tempUrl, to: file)
+
+                completion(nil)
+            }
+
+            catch let fileError {
+                completion(fileError)
+            }
+        }
+
+        if #available(iOS 11.0, *) {
+            task.progress.totalUnitCount = item.size
+            showProgress(progress: task.progress)
+            delegate.updateProgressLabel?(item.name!)
+        }
+        task.resume()
+    }
+
+    private func showProgress(progress: Progress) {
+        self.progress = progress
+        progress.addObserver(self, forKeyPath: NSStringFromSelector(#selector(getter: self.progress.fractionCompleted)), options: .init(rawValue: 0), context: nil)
+    }
+
+    private func getDownloadURL(for driveItem: MSGraphDriveItem) {
+        guard let applicationContext = applicationContext else {
+            return
+        }
+
+        downloadUrlDictionary.removeAll()
+
+        let driveItemID: String = driveItem.entityId
+
+        let stringUrl: String = kGraphEndpoint + "v1.0/drive/items/\(driveItemID)/?select=id,@microsoft.graph.downloadUrl"
+        let url = URL(string: stringUrl)
+
+        guard let url = url else {
+            return
+        }
+
+        let urlRequest = NSMutableURLRequest(url: url)
+        urlRequest.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
+        urlRequest.httpMethod = "GET"
+
+        let parameters = MSALAuthenticationProviderOptions(scopes: kScopes)
+
+        authenticationProvider = MSALAuthenticationProvider(publicClientApplication: applicationContext, andOptions: parameters)
+        let httpClient: MSHTTPClient = MSClientFactory.createHTTPClient(with: authenticationProvider)
+
+        let meDataTask: MSURLSessionDataTask = httpClient.dataTask(with: urlRequest, completionHandler: { (data, response, error) in
+            if error != nil {
+                self.authFailed()
+                return
+            }
+
+            guard let data = data else {
+                preconditionFailure("GraphViewController: Couldn't retrieve data.")
+            }
+
+            guard let result = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: Any] else {
+                return
+            }
+
+            guard let url = result["@microsoft.graph.downloadUrl"] as? String else {
+                self.downloadUrlDictionary[driveItem] = nil
+                return
+            }
+
+            self.downloadUrlDictionary.updateValue(url, forKey: driveItem)
+        })
+        meDataTask.execute()
+    }
+}
diff --git a/Podfile b/Podfile
index 143c40a24e82f197c68e06ca11299c266fa01e6f..bd58da23198064a36c48c2f84df283f748af4f7f 100644
--- a/Podfile
+++ b/Podfile
@@ -3,6 +3,7 @@ install! 'cocoapods', :deterministic_uuids => false
 inhibit_all_warnings!
 
 def shared_pods
+  use_modular_headers!
   pod 'XKKeychain', '~>1.0'
   pod 'box-ios-sdk-v2', :git => 'https://github.com/fkuehne/box-ios-sdk-v2.git', :commit => '08161e74' #has a our fixes
   pod 'CocoaHTTPServer', :git => 'https://github.com/fkuehne/CocoaHTTPServer.git' # has our fixes
@@ -23,13 +24,17 @@ target 'VLC-iOS' do
   pod 'VLCMediaLibraryKit', '0.11.0b2'
   pod 'GTMAppAuth', '0.7.1'
   pod 'ADAL', :git => 'https://code.videolan.org/fkuehne/azure-activedirectory-library-for-objc.git', :commit => '348e94df'
-  pod 'OneDriveSDK', :git => 'https://code.videolan.org/fkuehne/onedrive-sdk-ios.git', :commit => '810f82da'
   pod 'MarqueeLabel', '4.0.2'
   pod 'ObjectiveDropboxOfficial'
 
   target 'VLC-iOSTests' do
       inherit! :search_paths
   end
+
+  use_modular_headers!
+  pod 'MSGraphClientSDK'
+  pod 'MSGraphClientModels'
+  pod 'MSGraphMSALAuthProvider', :git => 'https://github.com/Mikanbu/msgraph-sdk-objc-auth'
 end
 
 target 'VLC-iOS-Screenshots' do
diff --git a/Podfile.lock b/Podfile.lock
index 64870c868f2f53fdd81bc4ba86b16cde8e8479bc..fe4ff43ad43441c2fdc606e4f58b33bc119a3a0c 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -16,7 +16,6 @@ PODS:
   - AFNetworking/UIKit (4.0.0):
     - AFNetworking/NSURLSession
   - AppAuth (0.95.1)
-  - Base32 (1.1.2)
   - box-ios-sdk-v2 (1.2.3):
     - box-ios-sdk-v2/no-arc (= 1.2.3)
   - box-ios-sdk-v2/no-arc (1.2.3)
@@ -40,31 +39,25 @@ PODS:
   - MetaDataFetcherKit (0.5.0):
     - AFNetworking (= 4.0.0)
   - MobileVLCKit (3.4.1b11)
+  - MSGraphClientModels (1.3.0)
+  - MSGraphClientSDK (1.0.0):
+    - MSGraphClientSDK/Authentication (= 1.0.0)
+    - MSGraphClientSDK/Common (= 1.0.0)
+  - MSGraphClientSDK/Authentication (1.0.0)
+  - MSGraphClientSDK/Common (1.0.0):
+    - MSGraphClientSDK/Authentication
+  - MSGraphMSALAuthProvider (0.2.0):
+    - MSGraphClientSDK (~> 1.0.0)
+    - VLC-MSAL
   - "NSData+Base64 (1.0.0)"
   - ObjectiveDropboxOfficial (6.3.2)
   - OBSlider (1.1.0)
-  - OneDriveSDK (1.3.0):
-    - OneDriveSDK/Auth (= 1.3.0)
-    - OneDriveSDK/Common (= 1.3.0)
-    - OneDriveSDK/Extensions (= 1.3.0)
-    - OneDriveSDK/Implementations (= 1.3.0)
-    - OneDriveSDK/OneDriveCoreSDK (= 1.3.0)
-  - OneDriveSDK/Auth (1.3.0):
-    - ADAL (~> 1.2.10)
-    - Base32 (~> 1.1)
-    - OneDriveSDK/Common
-  - OneDriveSDK/Common (1.3.0)
-  - OneDriveSDK/Extensions (1.3.0):
-    - OneDriveSDK/Auth
-    - OneDriveSDK/Implementations
-    - OneDriveSDK/OneDriveCoreSDK
-  - OneDriveSDK/Implementations (1.3.0):
-    - OneDriveSDK/Common
-  - OneDriveSDK/OneDriveCoreSDK (1.3.0):
-    - OneDriveSDK/Common
   - SimulatorStatusMagic (2.6)
   - SwiftLint (0.47.1)
   - TVVLCKit (3.4.1b11)
+  - VLC-MSAL (1.2.2):
+    - VLC-MSAL/app-lib (= 1.2.2)
+  - VLC-MSAL/app-lib (1.2.2)
   - VLCMediaLibraryKit (0.11.0b2):
     - MobileVLCKit
   - XKKeychain (1.0.1)
@@ -83,9 +76,11 @@ DEPENDENCIES:
   - MarqueeLabel (= 4.0.2)
   - MetaDataFetcherKit (~> 0.5.0)
   - MobileVLCKit (= 3.4.1b11)
+  - MSGraphClientModels
+  - MSGraphClientSDK
+  - MSGraphMSALAuthProvider (from `https://github.com/Mikanbu/msgraph-sdk-objc-auth`)
   - ObjectiveDropboxOfficial
   - OBSlider (= 1.1.0)
-  - OneDriveSDK (from `https://code.videolan.org/fkuehne/onedrive-sdk-ios.git`, commit `810f82da`)
   - SimulatorStatusMagic
   - SwiftLint (~> 0.47.1)
   - TVVLCKit (= 3.4.1b11)
@@ -97,7 +92,6 @@ SPEC REPOS:
   trunk:
     - AFNetworking
     - AppAuth
-    - Base32
     - GoogleAPIClientForREST
     - GRKArrayDiff
     - GTMAppAuth
@@ -105,12 +99,15 @@ SPEC REPOS:
     - MarqueeLabel
     - MetaDataFetcherKit
     - MobileVLCKit
+    - MSGraphClientModels
+    - MSGraphClientSDK
     - "NSData+Base64"
     - ObjectiveDropboxOfficial
     - OBSlider
     - SimulatorStatusMagic
     - SwiftLint
     - TVVLCKit
+    - VLC-MSAL
     - VLCMediaLibraryKit
     - XKKeychain
 
@@ -126,9 +123,8 @@ EXTERNAL SOURCES:
   InAppSettingsKit:
     :commit: a429840
     :git: https://github.com/Mikanbu/InAppSettingsKit.git
-  OneDriveSDK:
-    :commit: 810f82da
-    :git: https://code.videolan.org/fkuehne/onedrive-sdk-ios.git
+  MSGraphMSALAuthProvider:
+    :git: https://github.com/Mikanbu/msgraph-sdk-objc-auth
   xmlrpc:
     :commit: 3f8ce3a8
     :git: https://github.com/fkuehne/xmlrpc.git
@@ -146,9 +142,9 @@ CHECKOUT OPTIONS:
   InAppSettingsKit:
     :commit: a429840
     :git: https://github.com/Mikanbu/InAppSettingsKit.git
-  OneDriveSDK:
-    :commit: 810f82da
-    :git: https://code.videolan.org/fkuehne/onedrive-sdk-ios.git
+  MSGraphMSALAuthProvider:
+    :commit: f3e91a7e4d9ba82206c3c1d7e8d7def201507f67
+    :git: https://github.com/Mikanbu/msgraph-sdk-objc-auth
   xmlrpc:
     :commit: 3f8ce3a8
     :git: https://github.com/fkuehne/xmlrpc.git
@@ -157,7 +153,6 @@ SPEC CHECKSUMS:
   ADAL: f2eb2158b9bcd2c8416ff2d026c176b98ea6651f
   AFNetworking: d9fdf484a3c723ec3c558a41cc5754c7e845ee77
   AppAuth: cd34aac431e5c77c46ec7f03935377faa8c5808b
-  Base32: 163c298644d184e89ca4e00a996bad6bf5166390
   box-ios-sdk-v2: 9423bd75373350ea40b92f3d2d6e89f81d96d634
   CocoaHTTPServer: 07df8b05a8bde406fe367d22c90a24a2fd4ca49f
   GoogleAPIClientForREST: 2abe83bae1085d28f94ccc30a49fc7950d721fb9
@@ -168,17 +163,20 @@ SPEC CHECKSUMS:
   MarqueeLabel: f762aa681ae201f66c1d511858b171f75d83013a
   MetaDataFetcherKit: c77fa3d0791d406a8cfab43464ed728437bd241b
   MobileVLCKit: 110f1ddc4175a85d911d09f70a58e3cf0c0d48d5
+  MSGraphClientModels: ffef6d0a1cdaa774e1689e38da35301cb74fc72a
+  MSGraphClientSDK: ffc07a58a838e0702c7bf2a856367035d4a335d7
+  MSGraphMSALAuthProvider: cdd3114898fbe43a6e3b4cc0ba7a032c2a1e65a8
   "NSData+Base64": 4e84902c4db907a15673474677e57763ef3903e4
   ObjectiveDropboxOfficial: 1b9ca679750487f770fda3f38c106d6e17fe2d73
   OBSlider: 490f108007bfdd5414a38650b211fe403a95b8a0
-  OneDriveSDK: fbb41c73c36a23a580d172657c67c47dbb8f8e24
   SimulatorStatusMagic: 9f5294c12ca99c6cadb243a60362a66000df540c
   SwiftLint: f80f1be7fa96d30e0aa68e58d45d4ea1ccaac519
   TVVLCKit: 805100cd9b8c62440d0222f9a5696c950df9fd73
+  VLC-MSAL: 752652c8ae6aa352d6452baac202db6b62c98ba5
   VLCMediaLibraryKit: d7a3f1bbcccabddfc5faa010058f92bc96c34ad3
   XKKeychain: 852ef663c56a7194c73d3c68e8d9d4f07b121d4f
   xmlrpc: 2849d2a71cedfab68b1a8c82fb8373ce2ea0d0f3
 
-PODFILE CHECKSUM: 412675d649a1f3e178e8ee10d1c8eac7a9806d5f
+PODFILE CHECKSUM: 9d9a1c842ded6375a0275a2631e8f9a00222cccf
 
-COCOAPODS: 1.11.2
+COCOAPODS: 1.11.3
diff --git a/Resources/en.lproj/Localizable.strings b/Resources/en.lproj/Localizable.strings
index 7405948552f9737c4a1d5c105e947086de609ebe..019cd0c3cddaa43bd235a4adabdcd449796408c6 100644
--- a/Resources/en.lproj/Localizable.strings
+++ b/Resources/en.lproj/Localizable.strings
@@ -154,6 +154,7 @@
 "ONE_FILE" = "1 file";
 "NO_FILES" = "No supported files";
 "DOWNLOADING" = "Downloading...";
+"DOWNLOADING_MEDIA" = "Downloading: %@";
 "REMAINING_TIME" = "Remaining time: %@";
 "BIOMETRIC_UNLOCK" = "Unlock Media Library\nCancel to enter Passcode";
 
diff --git a/Sources/LocalNetworkConnectivity/VLCServerListViewController.m b/Sources/LocalNetworkConnectivity/VLCServerListViewController.m
index cdb2dcf3b0e6a24ada056945383f135aa89ee7c1..7cf4ca1cad268e8e159330d00ac6c3c02c426b96 100644
--- a/Sources/LocalNetworkConnectivity/VLCServerListViewController.m
+++ b/Sources/LocalNetworkConnectivity/VLCServerListViewController.m
@@ -40,8 +40,6 @@
 #import "VLCWiFiUploadTableViewCell.h"
 
 #import "VLCBoxController.h"
-#import <OneDriveSDK.h>
-#import "VLCOneDriveConstants.h"
 #import "VLCDropboxConstants.h"
 
 #import "VLC-Swift.h"
@@ -287,9 +285,6 @@
 
     // Configure Dropbox
     [DBClientsManager setupWithAppKey:kVLCDropboxAppKey];
-
-    // Configure OneDrive
-    [ODClient setMicrosoftAccountAppId:kVLCOneDriveClientID scopes:@[@"onedrive.readwrite", @"offline_access"]];
 }
 
 - (void)boxSessionUpdated
diff --git a/Sources/VLC for iOS-Info.plist b/Sources/VLC for iOS-Info.plist
index e15d5c2045c2ba8c83f73ef039ec49c52b8f0142..873e7ed2cb2b26e16db7d96919df8dae74d20d1f 100644
--- a/Sources/VLC for iOS-Info.plist	
+++ b/Sources/VLC for iOS-Info.plist	
@@ -242,6 +242,12 @@
 				<string>com.googleusercontent.apps.CLIENT</string>
 			</array>
 		</dict>
+		<dict>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>msauth.com.example.vlc-ios</string>
+			</array>
+		</dict>
 	</array>
 	<key>CFBundleVersion</key>
 	<string>$(CURRENT_PROJECT_VERSION)</string>
@@ -253,6 +259,9 @@
 	<array>
 		<string>dbapi-2</string>
 		<string>dbapi-8-emm</string>
+		<string>msauth</string>
+		<string>msauthv2</string>
+		<string>msauthv3</string>
 	</array>
 	<key>LSRequiresIPhoneOS</key>
 	<true/>
diff --git a/Sources/VLCCloudServicesTableViewController.m b/Sources/VLCCloudServicesTableViewController.m
index 9725daa08d47c5267e94a57c12f883e182e39069..9076395a159c05df599a8fbdcc2db4b948813fda 100644
--- a/Sources/VLCCloudServicesTableViewController.m
+++ b/Sources/VLCCloudServicesTableViewController.m
@@ -16,8 +16,6 @@
 #import "VLCGoogleDriveTableViewController.h"
 #import "VLCBoxTableViewController.h"
 #import "VLCBoxController.h"
-#import "VLCOneDriveTableViewController.h"
-#import "VLCOneDriveController.h"
 #import "VLCDocumentPickerController.h"
 #import "VLCCloudServiceCell.h"
 
@@ -29,7 +27,7 @@
 @property (nonatomic) VLCDropboxTableViewController *dropboxTableViewController;
 @property (nonatomic) VLCGoogleDriveTableViewController *googleDriveTableViewController;
 @property (nonatomic) VLCBoxTableViewController *boxTableViewController;
-@property (nonatomic) VLCOneDriveTableViewController *oneDriveTableViewController;
+@property (nonatomic) VLCGraphTableViewController *graphTableViewController;
 @property (nonatomic) VLCDocumentPickerController *documentPickerController;
 
 @end
@@ -41,13 +39,12 @@
 
     [self.tableView registerNib:[UINib nibWithNibName:@"VLCCloudServiceCell" bundle:nil] forCellReuseIdentifier:@"CloudServiceCell"];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(themeDidChange) name:kVLCThemeDidChangeNotification object:nil];
-    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(authenticationSessionsChanged:) name:VLCOneDriveControllerSessionUpdated object:nil];
     [self themeDidChange];
 
     self.dropboxTableViewController = [[VLCDropboxTableViewController alloc] initWithNibName:@"VLCCloudStorageTableViewController" bundle:nil];
     self.googleDriveTableViewController = [[VLCGoogleDriveTableViewController alloc] initWithNibName:@"VLCCloudStorageTableViewController" bundle:nil];
     self.boxTableViewController = [[VLCBoxTableViewController alloc] initWithNibName:@"VLCCloudStorageTableViewController" bundle:nil];
-    self.oneDriveTableViewController = [[VLCOneDriveTableViewController alloc] initWithNibName:@"VLCCloudStorageTableViewController" bundle:nil];
+    self.graphTableViewController = [[VLCGraphTableViewController alloc] initWithNibName:@"VLCCloudStorageTableViewController" bundle:nil];
     self.documentPickerController = [VLCDocumentPickerController new];
 }
 
@@ -99,7 +96,7 @@
     int i = [[VLCDropboxController sharedInstance] isAuthorized] ? 1 : 0;
     i += [[VLCGoogleDriveController sharedInstance] isAuthorized] ? 1 : 0;
     i += [[VLCBoxController sharedInstance] isAuthorized] ? 1 : 0;
-    i += [[VLCOneDriveController sharedInstance] isAuthorized] ? 1 : 0;
+    i += [[VLCGraphViewController sharedObject] isAuthorized] ? 1 : 0;
     return i;
 }
 
@@ -165,7 +162,7 @@
         }
         case 3: {
             //OneDrive
-            BOOL isAuthorized = [[VLCOneDriveController sharedInstance] isAuthorized];
+            BOOL isAuthorized = [VLCGraphViewController.sharedObject isAuthorized];
             cell.icon.image = [UIImage imageNamed:@"OneDriveCell"];
             cell.cloudTitle.text = @"OneDrive";
             cell.cloudInformation.text = isAuthorized ? NSLocalizedString(@"LOGGED_IN", "") : NSLocalizedString(@"LOGIN", "");
@@ -211,7 +208,7 @@
             break;
         case 3:
             //OneDrive
-            [self.navigationController pushViewController:self.oneDriveTableViewController animated:YES];
+            [self.navigationController pushViewController:self.graphTableViewController animated:YES];
             break;
         case 4:
             if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
diff --git a/Sources/VLCCloudStorageController.h b/Sources/VLCCloudStorageController.h
index 1cb8e82b3f6abf52a432cf3860dc4c17ccb5493e..3f4e802120c91774722c3974d92f10532ee8bd9c 100644
--- a/Sources/VLCCloudStorageController.h
+++ b/Sources/VLCCloudStorageController.h
@@ -22,6 +22,7 @@ typedef NS_ENUM (NSInteger, VLCCloudSortingCriteria) {
 - (void)operationWithProgressInformationStarted;
 - (void)currentProgressInformation:(CGFloat)progress;
 - (void)updateRemainingTime:(NSString *)time;
+- (void)updateProgressLabel:(NSString *)mediaName;
 - (void)operationWithProgressInformationStopped;
 - (void)numberOfFilesWaitingToBeDownloadedChanged;
 - (void)sessionWasUpdated;
diff --git a/Sources/VLCCloudStorageTableViewCell.h b/Sources/VLCCloudStorageTableViewCell.h
index 4c4ab3001eb7de576dac3561f815a6cc1880cdc0..6d58c21b037c5c27444a2d9df3ac4521e350b734 100644
--- a/Sources/VLCCloudStorageTableViewCell.h
+++ b/Sources/VLCCloudStorageTableViewCell.h
@@ -15,11 +15,13 @@
 #import <BoxSDK/BoxSDK.h>
 #if TARGET_OS_IOS
 #import "GTLRDrive.h"
-#import <OneDriveSDK/OneDriveSDK.h>
+#import <MSGraphClientModels/MSGraphDriveItem.h>
+#import <MSGraphClientModels/MSGraphAudio.h>
+#import <MSGraphClientModels/MSGraphVideo.h>
 #endif
 
 @class VLCNetworkImageView;
-@class ODItem;
+@class MSGraphDriveItem;
 
 @interface VLCCloudStorageTableViewCell : UITableViewCell
 
@@ -32,7 +34,7 @@
 @property (nonatomic, strong) IBOutlet UIButton *downloadButton;
 
 @property (nonatomic, retain) DBFILESMetadata *dropboxFile;
-@property (nonatomic, retain) ODItem *oneDriveFile;
+@property (nonatomic, retain) MSGraphDriveItem *oneDriveFile;
 @property (nonatomic, retain) BoxItem *boxFile;
 #if TARGET_OS_IOS
 @property (nonatomic, retain) GTLRDrive_File *driveFile;
diff --git a/Sources/VLCCloudStorageTableViewCell.m b/Sources/VLCCloudStorageTableViewCell.m
index 5f68c340aeeda4f8a8aa0f0426d214f541aee3c3..67c105db4c47105a1482057b82e42160c734b30f 100644
--- a/Sources/VLCCloudStorageTableViewCell.m
+++ b/Sources/VLCCloudStorageTableViewCell.m
@@ -75,34 +75,23 @@
 
 - (void)loadThumbnail
 {
-    // The onedrive Api has no way to cancel a request and the ODThumbnail has no back reference to it's item
-    // so this might lead to wrong thumbnails if the cell is reused since we have no way of cancelling requests or check if the completion is still for the set item
-    ODDriveRequestBuilder *drive = [[ODClient loadCurrentClient] drive];
-    ODThumbnailRequest *request = [[[[drive items:_oneDriveFile.id] thumbnails:@"0"] medium] request];
-    __weak typeof(self) weakSelf = self;
-    [request getWithCompletion:^(ODThumbnail *response, NSError *error) {
-        if (error == nil && response.url) {// we don't care about errors for thumbnails
-            dispatch_async(dispatch_get_main_queue(), ^{
-                 [weakSelf.thumbnailView setImageWithURL:[NSURL URLWithString:response.url]];
-            });
-        }
-    }];
+    // Integrate the thumbnail generation for the OneDrive cells.
 }
 
 - (void)updateOneDriveDisplayAsItem
 {
     int64_t duration = 0;
-    NSString *title = self.oneDriveFile.name;
+    NSString *title = _oneDriveFile.name;
     NSMutableString *subtitle = [[NSMutableString alloc] init];
 
     _downloadButton.hidden = NO;
     _titleLabel.text = title;
 
-    if (_oneDriveFile.audio) {
+    if (_oneDriveFile.audio || title.isSupportedAudioMediaFormat) {
         _thumbnailView.image = [UIImage imageNamed:@"audio"];
         duration = _oneDriveFile.audio.duration;
         [self loadThumbnail];
-    } else if (_oneDriveFile.video) {
+    } else if (_oneDriveFile.video || title.isSupportedMediaFormat) {
         _thumbnailView.image = [UIImage imageNamed:@"movie"];
         duration = _oneDriveFile.video.duration;
         [self loadThumbnail];
@@ -135,7 +124,7 @@
     _oneDriveFile.folder ? [self updateOneDriveDisplayAsFolder] : [self updateOneDriveDisplayAsItem];
 }
 
-- (void)setOneDriveFile:(ODItem *)oneDriveFile
+- (void)setOneDriveFile:(MSGraphDriveItem *)oneDriveFile
 {
     if (oneDriveFile != _oneDriveFile) {
         _oneDriveFile = oneDriveFile;
diff --git a/Sources/VLCCloudStorageTableViewController.m b/Sources/VLCCloudStorageTableViewController.m
index 2a1b6df71c42bfbeac20b4c244ba308f44eb2810..0aca7bf9ae2dad8bf42e55d77fde97753869e233 100644
--- a/Sources/VLCCloudStorageTableViewController.m
+++ b/Sources/VLCCloudStorageTableViewController.m
@@ -203,7 +203,9 @@ typedef NS_ENUM(NSInteger, VLCToolbarStyle) {
             [items addObjectsFromArray:@[_numberOfFilesBarButtonItem, [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]]];
             break;
     }
-    [self setToolbarItems:items animated:YES];
+    dispatch_async(dispatch_get_main_queue(), ^{
+        [self setToolbarItems:items animated:YES];
+    });
  }
 
 - (void)updateRemainingTime:(NSString *)time
@@ -211,6 +213,11 @@ typedef NS_ENUM(NSInteger, VLCToolbarStyle) {
     [_progressView updateTime:time];
 }
 
+-(void)updateProgressLabel:(NSString *)mediaName
+{
+    [_progressView updateProgressLabel:mediaName];
+}
+
 - (void)currentProgressInformation:(CGFloat)progress
 {
     [_progressView.progressBar setProgress:progress animated:YES];
@@ -264,7 +271,9 @@ typedef NS_ENUM(NSInteger, VLCToolbarStyle) {
     }
     if (_authorizationInProgress || [self.controller isAuthorized]) {
         if (self.loginToCloudStorageView.superview) {
-            [self.loginToCloudStorageView removeFromSuperview];
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [self.loginToCloudStorageView removeFromSuperview];
+            });
         }
     }
     if (![self.controller isAuthorized]) {
@@ -287,10 +296,6 @@ typedef NS_ENUM(NSInteger, VLCToolbarStyle) {
     if (self.currentPath == nil) {
         self.currentPath = @"";
     }
-
-    if ([self.controller.currentListFiles count] == 0) {
-        [self requestInformationForCurrentPath];
-    }
 }
 
 - (void)logout
diff --git a/Sources/VLCProgressView.h b/Sources/VLCProgressView.h
index 1aabee9dc0ef22e2843d1a722be9e103345d37fd..7edb471b7f537682a96c09437d175a7e169fa04f 100644
--- a/Sources/VLCProgressView.h
+++ b/Sources/VLCProgressView.h
@@ -18,5 +18,6 @@
 @property(nonatomic) UILabel *progressLabel;
 
 - (void)updateTime:(NSString *)time;
+- (void)updateProgressLabel:(NSString *)mediaName;
 
 @end
diff --git a/Sources/VLCProgressView.m b/Sources/VLCProgressView.m
index aadebe83d2627d02751650145a35b75bca6683b4..eec3ef186fc2f8cd13ba5126a5f3ef39213f0ac1 100644
--- a/Sources/VLCProgressView.m
+++ b/Sources/VLCProgressView.m
@@ -49,4 +49,11 @@
     [self.progressLabel setFrame:CGRectMake(self.progressLabel.frame.origin.x, self.progressLabel.frame.origin.y, size.width, size.height)];
 }
 
+- (void)updateProgressLabel:(NSString *)mediaName
+{
+    [self.progressLabel setText:[NSString stringWithFormat:NSLocalizedString(@"DOWNLOADING_MEDIA", nil), mediaName]];
+    CGSize size = [self.progressLabel.text sizeWithAttributes:self.progressLabel.font.fontDescriptor.fontAttributes];
+    [self.progressLabel setFrame:CGRectMake(self.progressLabel.frame.origin.x, self.progressLabel.frame.origin.y, size.width, size.height)];
+}
+
 @end
diff --git a/VLC.xcodeproj/project.pbxproj b/VLC.xcodeproj/project.pbxproj
index 53fee49184ad94861f0aa67d3924f4d828dfa0be..9475eee066f00653d564aaf45f7e45cdbf3866c3 100644
--- a/VLC.xcodeproj/project.pbxproj
+++ b/VLC.xcodeproj/project.pbxproj
@@ -7,8 +7,7 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		14903A768F4E959C0828288C /* libPods-VLC-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 52DDBB38DF22E6BBD19C38C8 /* libPods-VLC-tvOS.a */; };
-		226083AA75B10C9AA36C939A /* libPods-VLC-iOS-Screenshots.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5BE7EF6F028FE82FA278E5E /* libPods-VLC-iOS-Screenshots.a */; };
+		13925DC647EC27EEB2818FD2 /* libPods-VLC-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B0E3BE184ED7B95399C04EB6 /* libPods-VLC-tvOS.a */; };
 		2629C888223991A400F8D080 /* VLCMediaThumbnailerCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2629C887223991A400F8D080 /* VLCMediaThumbnailerCache.swift */; };
 		2663ACB222497D21000FBB95 /* VLCNetworkLoginTVViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2663ACB122497D21000FBB95 /* VLCNetworkLoginTVViewController.swift */; };
 		2663ACB422497D47000FBB95 /* VLCNetworkLoginTVViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2663ACB322497D47000FBB95 /* VLCNetworkLoginTVViewController.xib */; };
@@ -97,6 +96,7 @@
 		44C8BBB224AF36F4003F8940 /* SettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44C8BBAC24AF36F4003F8940 /* SettingsCell.swift */; };
 		44C8BBB324AF36F4003F8940 /* SettingsHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44C8BBAD24AF36F4003F8940 /* SettingsHeaderFooterView.swift */; };
 		44C8BBB524AF51FE003F8940 /* NSObject+SettingsReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44C8BBB424AF51FD003F8940 /* NSObject+SettingsReader.swift */; };
+		4B079F7D58CA85ECBFEE7115 /* libPods-VLC-iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F4D7CA6C946BEC69172FE01C /* libPods-VLC-iOS.a */; };
 		597B403F2625E85000C0D81E /* SliderInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 597B403E2625E85000C0D81E /* SliderInfoView.swift */; };
 		6B4E33D11BF2A39400A35255 /* playerControl.css in Resources */ = {isa = PBXBuildFile; fileRef = 6B4E33CF1BF2A39400A35255 /* playerControl.css */; };
 		6B4E33D21BF2A39400A35255 /* playerControl.js in Resources */ = {isa = PBXBuildFile; fileRef = 6B4E33D01BF2A39400A35255 /* playerControl.js */; };
@@ -132,8 +132,6 @@
 		7AC862A91765E9510011611A /* jquery.ui.widget.js in Resources */ = {isa = PBXBuildFile; fileRef = 7AC862A11765E90C0011611A /* jquery.ui.widget.js */; };
 		7D00161C177056B700649F27 /* main.js in Resources */ = {isa = PBXBuildFile; fileRef = 7D00161A17704DAC00649F27 /* main.js */; };
 		7D0C34E71BD951080058CD19 /* NSString+SupportedMedia.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3784C5183A9972009EE944 /* NSString+SupportedMedia.m */; };
-		7D1052E91A4DCC1100295F08 /* VLCOneDriveTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D1052E81A4DCC1100295F08 /* VLCOneDriveTableViewController.m */; };
-		7D1052EE1A4DCD1E00295F08 /* VLCOneDriveController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D1052ED1A4DCD1E00295F08 /* VLCOneDriveController.m */; };
 		7D1329411BA1F10100BE647E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D1329401BA1F10100BE647E /* main.m */; };
 		7D1329441BA1F10100BE647E /* AppleTVAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D1329431BA1F10100BE647E /* AppleTVAppDelegate.m */; };
 		7D15168B194773630086FB8C /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D15168A194773630086FB8C /* MobileCoreServices.framework */; };
@@ -283,7 +281,6 @@
 		7DF90B4A1BE7A8110059C0E3 /* IASKSettingsReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DF90B471BE7A8110059C0E3 /* IASKSettingsReader.m */; };
 		7DF90B4B1BE7A8110059C0E3 /* IASKSpecifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DF90B491BE7A8110059C0E3 /* IASKSpecifier.m */; };
 		7DF9352F1958AB0600E60FD4 /* UIColor+Presets.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DF9352E1958AB0600E60FD4 /* UIColor+Presets.m */; };
-		81334053F6D89AB90E14A1C3 /* libPods-VLC-iOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 91CCB170FBC97B6B93B99E0A /* libPods-VLC-iOSTests.a */; };
 		8D0E75CB24D1D870000D5267 /* VideoPlayerViewController+ControlsDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D0E75CA24D1D870000D5267 /* VideoPlayerViewController+ControlsDelegate.swift */; };
 		8D144D6322298E8E00984C46 /* AudioMiniPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D144D6222298E8E00984C46 /* AudioMiniPlayer.swift */; };
 		8D15A1ED22A9603300CFA758 /* ActionSheetSortSectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D15A1EC22A9603300CFA758 /* ActionSheetSortSectionHeader.swift */; };
@@ -333,8 +330,8 @@
 		9B9231C4185A703700F89498 /* VLCNetworkLoginViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B9231C3185A703700F89498 /* VLCNetworkLoginViewController.xib */; };
 		9BADAF45185FBD9D00108BD8 /* VLCFrostedGlasView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9BADAF44185FBD9D00108BD8 /* VLCFrostedGlasView.m */; };
 		9BE4D1CE183D76950006346C /* VLCCloudStorageTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3784B0183A990F009EE944 /* VLCCloudStorageTableViewCell.m */; };
-		A483C473E441E7BA7B31BF76 /* libPods-VLC-iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE6CC455148EC65B1D66CC66 /* libPods-VLC-iOS.a */; };
 		A79246C8170F11DF0036AAF2 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A79246C6170F11DF0036AAF2 /* Localizable.strings */; };
+		ABCDCCB0B59453B72E6C4787 /* libPods-VLC-iOS-Screenshots.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4307771A200A7301C243AE51 /* libPods-VLC-iOS-Screenshots.a */; };
 		CAA0B0ED2072651000B9274E /* VLCTestMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAF76D8F20709C4100E2AD7B /* VLCTestMenu.swift */; };
 		CAA0B0F02072651A00B9274E /* XCUIElement+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAF76D9320709C9500E2AD7B /* XCUIElement+Helpers.swift */; };
 		CAA0B0F52072686E00B9274E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A79246C6170F11DF0036AAF2 /* Localizable.strings */; };
@@ -350,7 +347,9 @@
 		D6E034ED1CC284FC0037F516 /* VLCStreamingHistoryCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D6E034EC1CC284FC0037F516 /* VLCStreamingHistoryCell.m */; };
 		D902E21527F4ADF900DC2B41 /* ArtistViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D902E21427F4ADF900DC2B41 /* ArtistViewController.swift */; };
 		D92C186527CD317D0034058F /* ChapterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D92C186427CD317D0034058F /* ChapterView.swift */; };
+		D96ACA962832836C00DD1A3E /* GraphViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D96ACA952832836C00DD1A3E /* GraphViewController.swift */; };
 		D96C9EBC28105F5B005F13BB /* AlbumHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = D96C9EBB28105F5B005F13BB /* AlbumHeader.swift */; };
+		D98EE7452846183F00E6B02D /* GraphTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D98EE7442846183F00E6B02D /* GraphTableViewController.swift */; };
 		D9AFDCA527D6383F002326CC /* BookmarksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AFDCA427D6383F002326CC /* BookmarksView.swift */; };
 		DD13A37B1BEE2FAA00A35554 /* VLCMaskView.m in Sources */ = {isa = PBXBuildFile; fileRef = DD13A37A1BEE2FAA00A35554 /* VLCMaskView.m */; };
 		DD1B31F41BF637D500A369B6 /* VLCPlaybackInfoTracksTVViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD1B31F21BF637D500A369B6 /* VLCPlaybackInfoTracksTVViewController.m */; };
@@ -439,6 +438,7 @@
 		E08AD1712304DDE800E023B9 /* MediaPlayerActionSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = E08AD1702304DDE800E023B9 /* MediaPlayerActionSheet.swift */; };
 		E0C04F951A25B4410080331A /* VLCDocumentPickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = E0C04F941A25B4410080331A /* VLCDocumentPickerController.m */; };
 		E0F8980422D399E10061DB2F /* MediaScrubProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0F8980322D399E10061DB2F /* MediaScrubProgressBar.swift */; };
+		FA22019D4109D19B4299773C /* libPods-VLC-iOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 939888242E2DC6874C59DCD6 /* libPods-VLC-iOSTests.a */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -466,6 +466,7 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
+		027E1E187A0A43CF5CFAECEC /* Pods-VLC-iOS.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS.distribution.xcconfig"; path = "Target Support Files/Pods-VLC-iOS/Pods-VLC-iOS.distribution.xcconfig"; sourceTree = "<group>"; };
 		1ACB60BB25275E5700405250 /* VLCFirstStepsBaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VLCFirstStepsBaseViewController.h; path = Sources/VLCFirstStepsBaseViewController.h; sourceTree = "<group>"; };
 		1ACB60BC25275E5700405250 /* VLCFirstStepsBaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = VLCFirstStepsBaseViewController.m; path = Sources/VLCFirstStepsBaseViewController.m; sourceTree = "<group>"; };
 		2629C886223991A300F8D080 /* VLC-tvOS-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VLC-tvOS-Bridging-Header.h"; sourceTree = "<group>"; };
@@ -475,9 +476,8 @@
 		26F1BFCF1A770408001DF30C /* libMediaVLC.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = libMediaVLC.xml; sourceTree = "<group>"; };
 		29125E5417492219003F03E5 /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = index.html; sourceTree = "<group>"; };
 		2915544217490D4A00B86CAD /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
-		2B1BC34A3BC4BCE7588BD68A /* Pods-VLC-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-tvOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS.release.xcconfig"; sourceTree = "<group>"; };
-		3B75A76DF6589FE678357D42 /* Pods-VLC-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-iOS/Pods-VLC-iOS.debug.xcconfig"; sourceTree = "<group>"; };
-		3E95DC30A81B2AF9F7442E00 /* Pods-VLC-iOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOSTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-iOSTests/Pods-VLC-iOSTests.debug.xcconfig"; sourceTree = "<group>"; };
+		2E995114543D1E41A5A82486 /* Pods-VLC-iOS-Screenshots.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS-Screenshots.release.xcconfig"; path = "Target Support Files/Pods-VLC-iOS-Screenshots/Pods-VLC-iOS-Screenshots.release.xcconfig"; sourceTree = "<group>"; };
+		3B79FA55420524A988373783 /* Pods-VLC-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS.release.xcconfig"; path = "Target Support Files/Pods-VLC-iOS/Pods-VLC-iOS.release.xcconfig"; sourceTree = "<group>"; };
 		4072A776258791B8006EA498 /* VideoFiltersView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VideoFiltersView.xib; sourceTree = "<group>"; };
 		4072A77D25879577006EA498 /* VideoFiltersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoFiltersView.swift; sourceTree = "<group>"; };
 		407EB586257A418900686B1F /* SleepTimerView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SleepTimerView.xib; sourceTree = "<group>"; };
@@ -610,6 +610,7 @@
 		41EC28E42136DD41004BCF0F /* MovieCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovieCollectionViewCell.swift; sourceTree = "<group>"; };
 		41EC28E82136DE46004BCF0F /* MovieCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MovieCollectionViewCell.xib; sourceTree = "<group>"; };
 		41FCD2F720B565B500660AAB /* VLCAlertViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VLCAlertViewController.swift; sourceTree = "<group>"; };
+		4307771A200A7301C243AE51 /* libPods-VLC-iOS-Screenshots.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VLC-iOS-Screenshots.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		4342C3C227474CA000E52334 /* SortedMediaFiles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SortedMediaFiles.swift; sourceTree = "<group>"; };
 		444E5BF924C6081A0003B69C /* PasscodeLockController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasscodeLockController.swift; sourceTree = "<group>"; };
 		444E5BFF24C719480003B69C /* AboutController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutController.swift; sourceTree = "<group>"; };
@@ -622,11 +623,9 @@
 		44C8BBAC24AF36F4003F8940 /* SettingsCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsCell.swift; sourceTree = "<group>"; };
 		44C8BBAD24AF36F4003F8940 /* SettingsHeaderFooterView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsHeaderFooterView.swift; sourceTree = "<group>"; };
 		44C8BBB424AF51FD003F8940 /* NSObject+SettingsReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSObject+SettingsReader.swift"; path = "Sources/Extensions/NSObject+SettingsReader.swift"; sourceTree = "<group>"; };
-		52DDBB38DF22E6BBD19C38C8 /* libPods-VLC-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VLC-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
-		5671052B495534848FA467EE /* Pods-VLC-iOS-Screenshots.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS-Screenshots.release.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-iOS-Screenshots/Pods-VLC-iOS-Screenshots.release.xcconfig"; sourceTree = "<group>"; };
+		535ECB057D81248C91FA25C4 /* Pods-VLC-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS.debug.xcconfig"; path = "Target Support Files/Pods-VLC-iOS/Pods-VLC-iOS.debug.xcconfig"; sourceTree = "<group>"; };
+		57087A12E77ACEB9D1D30E33 /* Pods-VLC-tvOS.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-tvOS.distribution.xcconfig"; path = "Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS.distribution.xcconfig"; sourceTree = "<group>"; };
 		597B403E2625E85000C0D81E /* SliderInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderInfoView.swift; sourceTree = "<group>"; };
-		5B343E4F4D971F5A169EB864 /* Pods-VLC-iOS.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS.distribution.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-iOS/Pods-VLC-iOS.distribution.xcconfig"; sourceTree = "<group>"; };
-		65EC8984D840047F50AA00A1 /* libPods-VLC-iOSUITests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VLC-iOSUITests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		6B4E33CF1BF2A39400A35255 /* playerControl.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = playerControl.css; path = Resources/web/playerControl.css; sourceTree = SOURCE_ROOT; };
 		6B4E33D01BF2A39400A35255 /* playerControl.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = playerControl.js; path = Resources/web/playerControl.js; sourceTree = SOURCE_ROOT; };
 		6C5B0C9C27A43098005AE25B /* PlaybackServiceAdjustFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PlaybackServiceAdjustFilter.swift; path = Sources/PlaybackServiceAdjustFilter.swift; sourceTree = SOURCE_ROOT; };
@@ -651,17 +650,12 @@
 		6DE36F2A2719D7CB00558199 /* UIDevice+VLC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDevice+VLC.swift"; sourceTree = "<group>"; };
 		6DE63F3E270FD3D1008A011D /* VLCPlayerDisplayController+MiniPlayerDraggingDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VLCPlayerDisplayController+MiniPlayerDraggingDelegate.swift"; sourceTree = "<group>"; };
 		6DE9183C25F65C390039AFA7 /* UIScrollView+flashScrollIndicatorsIfNeeded.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "UIScrollView+flashScrollIndicatorsIfNeeded.swift"; path = "Sources/Extensions/UIScrollView+flashScrollIndicatorsIfNeeded.swift"; sourceTree = "<group>"; };
-		703A80CCC005093CCDFBECBF /* Pods-VLC-iOS-Screenshots.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS-Screenshots.distribution.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-iOS-Screenshots/Pods-VLC-iOS-Screenshots.distribution.xcconfig"; sourceTree = "<group>"; };
+		723659CB3834E1B30918E514 /* Pods-VLC-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS.debug.xcconfig"; sourceTree = "<group>"; };
 		7AC8629B1765DC560011611A /* style.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = style.css; sourceTree = "<group>"; };
 		7AC8629F1765E90C0011611A /* jquery.fileupload.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = jquery.fileupload.js; sourceTree = "<group>"; };
 		7AC862A01765E90C0011611A /* jquery.iframe-transport.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "jquery.iframe-transport.js"; sourceTree = "<group>"; };
 		7AC862A11765E90C0011611A /* jquery.ui.widget.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = jquery.ui.widget.js; sourceTree = "<group>"; };
 		7D00161A17704DAC00649F27 /* main.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = "<group>"; };
-		7D1052E71A4DCC1100295F08 /* VLCOneDriveTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCOneDriveTableViewController.h; path = Sources/VLCOneDriveTableViewController.h; sourceTree = SOURCE_ROOT; };
-		7D1052E81A4DCC1100295F08 /* VLCOneDriveTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCOneDriveTableViewController.m; path = Sources/VLCOneDriveTableViewController.m; sourceTree = SOURCE_ROOT; };
-		7D1052EB1A4DCC4B00295F08 /* VLCOneDriveConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VLCOneDriveConstants.h; path = Sources/VLCOneDriveConstants.h; sourceTree = SOURCE_ROOT; };
-		7D1052EC1A4DCD1E00295F08 /* VLCOneDriveController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCOneDriveController.h; path = Sources/VLCOneDriveController.h; sourceTree = SOURCE_ROOT; };
-		7D1052ED1A4DCD1E00295F08 /* VLCOneDriveController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCOneDriveController.m; path = Sources/VLCOneDriveController.m; sourceTree = SOURCE_ROOT; };
 		7D13293D1BA1F10100BE647E /* VLC-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "VLC-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		7D1329401BA1F10100BE647E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
 		7D1329421BA1F10100BE647E /* AppleTVAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppleTVAppDelegate.h; sourceTree = "<group>"; };
@@ -888,8 +882,6 @@
 		7DF383B81BF21E4400D71A5C /* VLCPlayerControlWebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCPlayerControlWebSocket.m; path = SharedSources/VLCPlayerControlWebSocket.m; sourceTree = SOURCE_ROOT; };
 		7DF383BF1BF231BC00D71A5C /* VLCCloudStorageTVViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCCloudStorageTVViewController.h; sourceTree = "<group>"; };
 		7DF383C01BF231BC00D71A5C /* VLCCloudStorageTVViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCCloudStorageTVViewController.m; sourceTree = "<group>"; };
-		7DF383C91BF2498800D71A5C /* VLCOneDriveCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCOneDriveCollectionViewController.h; path = SharedSources/Clouds/VLCOneDriveCollectionViewController.h; sourceTree = SOURCE_ROOT; };
-		7DF383CA1BF2498800D71A5C /* VLCOneDriveCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCOneDriveCollectionViewController.m; path = SharedSources/Clouds/VLCOneDriveCollectionViewController.m; sourceTree = SOURCE_ROOT; };
 		7DF383CE1BF24BB100D71A5C /* VLCBoxCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCBoxCollectionViewController.h; path = SharedSources/Clouds/VLCBoxCollectionViewController.h; sourceTree = SOURCE_ROOT; };
 		7DF383CF1BF24BB100D71A5C /* VLCBoxCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCBoxCollectionViewController.m; path = SharedSources/Clouds/VLCBoxCollectionViewController.m; sourceTree = SOURCE_ROOT; };
 		7DF7CA0617650C2A00C61739 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
@@ -900,7 +892,6 @@
 		7DF90B491BE7A8110059C0E3 /* IASKSpecifier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IASKSpecifier.m; path = Pods/InAppSettingsKit/InAppSettingsKit/Models/IASKSpecifier.m; sourceTree = SOURCE_ROOT; };
 		7DF9352D1958AB0600E60FD4 /* UIColor+Presets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIColor+Presets.h"; path = "Sources/Extensions/UIColor+Presets.h"; sourceTree = SOURCE_ROOT; };
 		7DF9352E1958AB0600E60FD4 /* UIColor+Presets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIColor+Presets.m"; path = "Sources/Extensions/UIColor+Presets.m"; sourceTree = SOURCE_ROOT; };
-		7FC9CCF39DD8843873A42D34 /* Pods-VLC-iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOSTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-iOSTests/Pods-VLC-iOSTests.release.xcconfig"; sourceTree = "<group>"; };
 		8D0E75CA24D1D870000D5267 /* VideoPlayerViewController+ControlsDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VideoPlayerViewController+ControlsDelegate.swift"; sourceTree = "<group>"; };
 		8D144D6222298E8E00984C46 /* AudioMiniPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioMiniPlayer.swift; sourceTree = "<group>"; };
 		8D15A1EC22A9603300CFA758 /* ActionSheetSortSectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionSheetSortSectionHeader.swift; sourceTree = "<group>"; };
@@ -944,9 +935,9 @@
 		918C8E10279065C6002B3CD6 /* TitleSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleSelectionView.swift; sourceTree = "<group>"; };
 		91B85AEE2731A4C00010F137 /* StoreProductCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = StoreProductCollectionViewCell.xib; path = Resources/Xib/StoreProductCollectionViewCell.xib; sourceTree = "<group>"; };
 		91C1BB7F25EFD7A40096F97E /* ColorThemeExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorThemeExtension.swift; sourceTree = "<group>"; };
-		91CCB170FBC97B6B93B99E0A /* libPods-VLC-iOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VLC-iOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		91D33C7225E6B6E700CC49BE /* VideoPlayerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerInfoView.swift; sourceTree = "<group>"; };
 		91F8BF1727318D890058D9DE /* StoreProductCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreProductCollectionViewCell.swift; sourceTree = "<group>"; };
+		939888242E2DC6874C59DCD6 /* libPods-VLC-iOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VLC-iOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		9B088306183D7BEC004B5C2A /* VLCCloudStorageTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCCloudStorageTableViewController.h; path = Sources/VLCCloudStorageTableViewController.h; sourceTree = SOURCE_ROOT; };
 		9B088307183D7BEC004B5C2A /* VLCCloudStorageTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCCloudStorageTableViewController.m; path = Sources/VLCCloudStorageTableViewController.m; sourceTree = SOURCE_ROOT; };
 		9B9231C3185A703700F89498 /* VLCNetworkLoginViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = VLCNetworkLoginViewController.xib; path = Resources/VLCNetworkLoginViewController.xib; sourceTree = SOURCE_ROOT; };
@@ -955,8 +946,12 @@
 		A7035BBD174519600057DFA7 /* iTunesArtwork */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTunesArtwork; sourceTree = "<group>"; };
 		A79246C7170F11DF0036AAF2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; lineEnding = 0; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.simpleColoring; };
 		A79246C9170F11E40036AAF2 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
-		AC40202FFE42CEDCEB37E50D /* Pods-VLC-tvOS.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-tvOS.distribution.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS.distribution.xcconfig"; sourceTree = "<group>"; };
-		C6872E7B396534F3DAF4E48F /* Pods-VLC-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-iOS/Pods-VLC-iOS.release.xcconfig"; sourceTree = "<group>"; };
+		AF116147FD13655FDCF10359 /* Pods-VLC-iOSTests.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOSTests.distribution.xcconfig"; path = "Target Support Files/Pods-VLC-iOSTests/Pods-VLC-iOSTests.distribution.xcconfig"; sourceTree = "<group>"; };
+		B0E3BE184ED7B95399C04EB6 /* libPods-VLC-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VLC-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		B1CA1021683B1DE3C1E367A6 /* Pods-VLC-iOS-Screenshots.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS-Screenshots.debug.xcconfig"; path = "Target Support Files/Pods-VLC-iOS-Screenshots/Pods-VLC-iOS-Screenshots.debug.xcconfig"; sourceTree = "<group>"; };
+		BB4AA60FE9D8D55360CC4ED3 /* Pods-VLC-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-tvOS.release.xcconfig"; path = "Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS.release.xcconfig"; sourceTree = "<group>"; };
+		C177035ADC636FBBDB2F537A /* Pods-VLC-iOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOSTests.debug.xcconfig"; path = "Target Support Files/Pods-VLC-iOSTests/Pods-VLC-iOSTests.debug.xcconfig"; sourceTree = "<group>"; };
+		C3E0FA5F7E6B347A85A3E252 /* Pods-VLC-iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOSTests.release.xcconfig"; path = "Target Support Files/Pods-VLC-iOSTests/Pods-VLC-iOSTests.release.xcconfig"; sourceTree = "<group>"; };
 		CA6FB8222074601900FC9BF2 /* VLC-iOS-Screenshots-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VLC-iOS-Screenshots-Bridging-Header.h"; sourceTree = "<group>"; };
 		CAA0B0F620726A0E00B9274E /* TestHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHelper.swift; sourceTree = "<group>"; };
 		CAD925782075536300F88496 /* Screenshot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Screenshot.swift; sourceTree = "<group>"; };
@@ -976,15 +971,14 @@
 		CC87148317A56C85003C7383 /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; lineEnding = 0; name = ca; path = ca.lproj/Localizable.strings; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.simpleColoring; };
 		CCAF837E17DE46D800E3578F /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = "<group>"; };
 		CCE2A22D17A5859E00D9EAAD /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
-		CE6CC455148EC65B1D66CC66 /* libPods-VLC-iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VLC-iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		D0AF091E220A741300076D07 /* VLCCloudSortingSpecifierManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = VLCCloudSortingSpecifierManager.swift; path = Sources/VLCCloudSortingSpecifierManager.swift; sourceTree = "<group>"; };
-		D581CD3C269D82BD6A25E543 /* Pods-VLC-iOS-Screenshots.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS-Screenshots.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-iOS-Screenshots/Pods-VLC-iOS-Screenshots.debug.xcconfig"; sourceTree = "<group>"; };
-		D5BE7EF6F028FE82FA278E5E /* libPods-VLC-iOS-Screenshots.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VLC-iOS-Screenshots.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 		D6E034EB1CC284FC0037F516 /* VLCStreamingHistoryCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCStreamingHistoryCell.h; path = Sources/VLCStreamingHistoryCell.h; sourceTree = SOURCE_ROOT; };
 		D6E034EC1CC284FC0037F516 /* VLCStreamingHistoryCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCStreamingHistoryCell.m; path = Sources/VLCStreamingHistoryCell.m; sourceTree = SOURCE_ROOT; };
 		D902E21427F4ADF900DC2B41 /* ArtistViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArtistViewController.swift; sourceTree = "<group>"; };
 		D92C186427CD317D0034058F /* ChapterView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChapterView.swift; sourceTree = "<group>"; };
+		D96ACA952832836C00DD1A3E /* GraphViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphViewController.swift; sourceTree = "<group>"; };
 		D96C9EBB28105F5B005F13BB /* AlbumHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumHeader.swift; sourceTree = "<group>"; };
+		D98EE7442846183F00E6B02D /* GraphTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphTableViewController.swift; sourceTree = "<group>"; };
 		D9AFDCA427D6383F002326CC /* BookmarksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksView.swift; sourceTree = "<group>"; };
 		DD13A3791BEE2FAA00A35554 /* VLCMaskView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCMaskView.h; path = "UI Elements/VLCMaskView.h"; sourceTree = "<group>"; };
 		DD13A37A1BEE2FAA00A35554 /* VLCMaskView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCMaskView.m; path = "UI Elements/VLCMaskView.m"; sourceTree = "<group>"; };
@@ -1113,8 +1107,8 @@
 		E0C04F931A25B4410080331A /* VLCDocumentPickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCDocumentPickerController.h; path = Sources/VLCDocumentPickerController.h; sourceTree = SOURCE_ROOT; };
 		E0C04F941A25B4410080331A /* VLCDocumentPickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCDocumentPickerController.m; path = Sources/VLCDocumentPickerController.m; sourceTree = SOURCE_ROOT; };
 		E0F8980322D399E10061DB2F /* MediaScrubProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaScrubProgressBar.swift; sourceTree = "<group>"; };
-		E39E49F085F7C54D2DB79534 /* Pods-VLC-iOSTests.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOSTests.distribution.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-iOSTests/Pods-VLC-iOSTests.distribution.xcconfig"; sourceTree = "<group>"; };
-		F25DF68DCD1A8FA89D1933B3 /* Pods-VLC-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-tvOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS.debug.xcconfig"; sourceTree = "<group>"; };
+		F4D7CA6C946BEC69172FE01C /* libPods-VLC-iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VLC-iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		FC34D45714F6ABBFF4645E35 /* Pods-VLC-iOS-Screenshots.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VLC-iOS-Screenshots.distribution.xcconfig"; path = "Target Support Files/Pods-VLC-iOS-Screenshots/Pods-VLC-iOS-Screenshots.distribution.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -1122,7 +1116,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				226083AA75B10C9AA36C939A /* libPods-VLC-iOS-Screenshots.a in Frameworks */,
+				ABCDCCB0B59453B72E6C4787 /* libPods-VLC-iOS-Screenshots.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1130,7 +1124,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				81334053F6D89AB90E14A1C3 /* libPods-VLC-iOSTests.a in Frameworks */,
+				FA22019D4109D19B4299773C /* libPods-VLC-iOSTests.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1145,7 +1139,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				14903A768F4E959C0828288C /* libPods-VLC-tvOS.a in Frameworks */,
+				13925DC647EC27EEB2818FD2 /* libPods-VLC-tvOS.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1176,13 +1170,32 @@
 				7D94FCDF16DE7D1000F2623B /* UIKit.framework in Frameworks */,
 				7D94FCE116DE7D1000F2623B /* Foundation.framework in Frameworks */,
 				7D94FCE316DE7D1000F2623B /* CoreGraphics.framework in Frameworks */,
-				A483C473E441E7BA7B31BF76 /* libPods-VLC-iOS.a in Frameworks */,
+				4B079F7D58CA85ECBFEE7115 /* libPods-VLC-iOS.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		023340A3B4C320149F526087 /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				535ECB057D81248C91FA25C4 /* Pods-VLC-iOS.debug.xcconfig */,
+				3B79FA55420524A988373783 /* Pods-VLC-iOS.release.xcconfig */,
+				027E1E187A0A43CF5CFAECEC /* Pods-VLC-iOS.distribution.xcconfig */,
+				B1CA1021683B1DE3C1E367A6 /* Pods-VLC-iOS-Screenshots.debug.xcconfig */,
+				2E995114543D1E41A5A82486 /* Pods-VLC-iOS-Screenshots.release.xcconfig */,
+				FC34D45714F6ABBFF4645E35 /* Pods-VLC-iOS-Screenshots.distribution.xcconfig */,
+				C177035ADC636FBBDB2F537A /* Pods-VLC-iOSTests.debug.xcconfig */,
+				C3E0FA5F7E6B347A85A3E252 /* Pods-VLC-iOSTests.release.xcconfig */,
+				AF116147FD13655FDCF10359 /* Pods-VLC-iOSTests.distribution.xcconfig */,
+				723659CB3834E1B30918E514 /* Pods-VLC-tvOS.debug.xcconfig */,
+				BB4AA60FE9D8D55360CC4ED3 /* Pods-VLC-tvOS.release.xcconfig */,
+				57087A12E77ACEB9D1D30E33 /* Pods-VLC-tvOS.distribution.xcconfig */,
+			);
+			path = Pods;
+			sourceTree = "<group>";
+		};
 		29125E5317492219003F03E5 /* web */ = {
 			isa = PBXGroup;
 			children = (
@@ -1345,13 +1358,6 @@
 		7D1052EA1A4DCC1700295F08 /* OneDrive */ = {
 			isa = PBXGroup;
 			children = (
-				7D1052EB1A4DCC4B00295F08 /* VLCOneDriveConstants.h */,
-				7D1052E71A4DCC1100295F08 /* VLCOneDriveTableViewController.h */,
-				7D1052E81A4DCC1100295F08 /* VLCOneDriveTableViewController.m */,
-				7DF383C91BF2498800D71A5C /* VLCOneDriveCollectionViewController.h */,
-				7DF383CA1BF2498800D71A5C /* VLCOneDriveCollectionViewController.m */,
-				7D1052EC1A4DCD1E00295F08 /* VLCOneDriveController.h */,
-				7D1052ED1A4DCD1E00295F08 /* VLCOneDriveController.m */,
 			);
 			name = OneDrive;
 			sourceTree = "<group>";
@@ -1517,6 +1523,8 @@
 				D0AF091E220A741300076D07 /* VLCCloudSortingSpecifierManager.swift */,
 				4184AA131A5492070063DF5A /* VLCCloudStorageController.h */,
 				4184AA141A5492070063DF5A /* VLCCloudStorageController.m */,
+				D96ACA952832836C00DD1A3E /* GraphViewController.swift */,
+				D98EE7442846183F00E6B02D /* GraphTableViewController.swift */,
 			);
 			name = "Cloud Integration";
 			path = ..;
@@ -1642,8 +1650,8 @@
 				4133CADD22CCB0620047A4EC /* VLC-iOSScreenShots */,
 				7D94FCDD16DE7D1000F2623B /* Frameworks */,
 				7D94FCDC16DE7D1000F2623B /* Products */,
-				A77803FFDA800BD6A3DAED0C /* Pods */,
 				412A87D01F3B89B000640BB7 /* Recovered References */,
+				023340A3B4C320149F526087 /* Pods */,
 			);
 			sourceTree = "<group>";
 			usesTabs = 0;
@@ -1686,11 +1694,10 @@
 				7D94FCDE16DE7D1000F2623B /* UIKit.framework */,
 				7D94FCE016DE7D1000F2623B /* Foundation.framework */,
 				7D94FCE216DE7D1000F2623B /* CoreGraphics.framework */,
-				CE6CC455148EC65B1D66CC66 /* libPods-VLC-iOS.a */,
-				91CCB170FBC97B6B93B99E0A /* libPods-VLC-iOSTests.a */,
-				65EC8984D840047F50AA00A1 /* libPods-VLC-iOSUITests.a */,
-				52DDBB38DF22E6BBD19C38C8 /* libPods-VLC-tvOS.a */,
-				D5BE7EF6F028FE82FA278E5E /* libPods-VLC-iOS-Screenshots.a */,
+				F4D7CA6C946BEC69172FE01C /* libPods-VLC-iOS.a */,
+				4307771A200A7301C243AE51 /* libPods-VLC-iOS-Screenshots.a */,
+				939888242E2DC6874C59DCD6 /* libPods-VLC-iOSTests.a */,
+				B0E3BE184ED7B95399C04EB6 /* libPods-VLC-tvOS.a */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";
@@ -2194,25 +2201,6 @@
 			name = GoogleDrive;
 			sourceTree = "<group>";
 		};
-		A77803FFDA800BD6A3DAED0C /* Pods */ = {
-			isa = PBXGroup;
-			children = (
-				3B75A76DF6589FE678357D42 /* Pods-VLC-iOS.debug.xcconfig */,
-				C6872E7B396534F3DAF4E48F /* Pods-VLC-iOS.release.xcconfig */,
-				5B343E4F4D971F5A169EB864 /* Pods-VLC-iOS.distribution.xcconfig */,
-				F25DF68DCD1A8FA89D1933B3 /* Pods-VLC-tvOS.debug.xcconfig */,
-				2B1BC34A3BC4BCE7588BD68A /* Pods-VLC-tvOS.release.xcconfig */,
-				AC40202FFE42CEDCEB37E50D /* Pods-VLC-tvOS.distribution.xcconfig */,
-				3E95DC30A81B2AF9F7442E00 /* Pods-VLC-iOSTests.debug.xcconfig */,
-				7FC9CCF39DD8843873A42D34 /* Pods-VLC-iOSTests.release.xcconfig */,
-				E39E49F085F7C54D2DB79534 /* Pods-VLC-iOSTests.distribution.xcconfig */,
-				D581CD3C269D82BD6A25E543 /* Pods-VLC-iOS-Screenshots.debug.xcconfig */,
-				5671052B495534848FA467EE /* Pods-VLC-iOS-Screenshots.release.xcconfig */,
-				703A80CCC005093CCDFBECBF /* Pods-VLC-iOS-Screenshots.distribution.xcconfig */,
-			);
-			name = Pods;
-			sourceTree = "<group>";
-		};
 		A7924697170F0ED20036AAF2 /* iOS Resources */ = {
 			isa = PBXGroup;
 			children = (
@@ -2497,7 +2485,7 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = 4133CAE622CCB0620047A4EC /* Build configuration list for PBXNativeTarget "VLC-iOS-Screenshots" */;
 			buildPhases = (
-				2E5934DFBFA4E9DF220B9070 /* [CP] Check Pods Manifest.lock */,
+				249843156C1F5E72AAC05696 /* [CP] Check Pods Manifest.lock */,
 				4133CAD822CCB0620047A4EC /* Sources */,
 				4133CAD922CCB0620047A4EC /* Frameworks */,
 				4133CADA22CCB0620047A4EC /* Resources */,
@@ -2516,7 +2504,7 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = 41533C98211338D600EC3ABA /* Build configuration list for PBXNativeTarget "VLC-iOSTests" */;
 			buildPhases = (
-				16C1AB96786C00EC189F241D /* [CP] Check Pods Manifest.lock */,
+				DFC9085B196928CE07634712 /* [CP] Check Pods Manifest.lock */,
 				41533C8D211338D500EC3ABA /* Sources */,
 				41533C8E211338D500EC3ABA /* Frameworks */,
 				41533C8F211338D500EC3ABA /* Resources */,
@@ -2553,12 +2541,12 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = 7D1329541BA1F10100BE647E /* Build configuration list for PBXNativeTarget "VLC-tvOS" */;
 			buildPhases = (
-				CEAC60B72FF5CB91256BC99B /* [CP] Check Pods Manifest.lock */,
+				6B1272663E377D4BC4DCBF9D /* [CP] Check Pods Manifest.lock */,
 				7D1329391BA1F10100BE647E /* Sources */,
 				7D13293A1BA1F10100BE647E /* Frameworks */,
 				7D13293B1BA1F10100BE647E /* Resources */,
-				0452CD613294910CB73B58CB /* [CP] Copy Pods Resources */,
-				08BEF713BB055DD740241EF9 /* [CP] Embed Pods Frameworks */,
+				982755253ECF96B8E3B17FEE /* [CP] Embed Pods Frameworks */,
+				9FC273B6B91160C54B8FDFE5 /* [CP] Copy Pods Resources */,
 			);
 			buildRules = (
 			);
@@ -2573,14 +2561,14 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = 7D94FD0A16DE7D1100F2623B /* Build configuration list for PBXNativeTarget "VLC-iOS" */;
 			buildPhases = (
-				23B425DEB65EA5C88D873ED2 /* [CP] Check Pods Manifest.lock */,
+				23B51B8827E6794878250849 /* [CP] Check Pods Manifest.lock */,
 				41F7087C1F37900A00953630 /* Generate Localized Strings */,
 				0A9D17D120C4A14700AA4A8C /* Run SwiftLint Script */,
 				7D94FCD716DE7D1000F2623B /* Sources */,
 				7D94FCD816DE7D1000F2623B /* Frameworks */,
 				7D94FCD916DE7D1000F2623B /* Resources */,
-				9706D52A0CDF446E336826A6 /* [CP] Copy Pods Resources */,
-				3696DF9BCC8B754F06D345D9 /* [CP] Embed Pods Frameworks */,
+				F03D8E7BCA1DC4981CDB963A /* [CP] Embed Pods Frameworks */,
+				A7E516CDB189F9DFEC0DA54B /* [CP] Copy Pods Resources */,
 			);
 			buildRules = (
 			);
@@ -2850,93 +2838,79 @@
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
-		0452CD613294910CB73B58CB /* [CP] Copy Pods Resources */ = {
+		0A9D17D120C4A14700AA4A8C /* Run SwiftLint Script */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS-resources.sh",
-				"${PODS_CONFIGURATION_BUILD_DIR}/XKKeychain-tvOS/XKKeychain.bundle",
 			);
-			name = "[CP] Copy Pods Resources";
+			name = "Run SwiftLint Script";
 			outputPaths = (
-				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/XKKeychain.bundle",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS-resources.sh\"\n";
-			showEnvVarsInLog = 0;
+			shellScript = "${PODS_ROOT}/SwiftLint/swiftlint\n";
 		};
-		08BEF713BB055DD740241EF9 /* [CP] Embed Pods Frameworks */ = {
+		23B51B8827E6794878250849 /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
+			inputFileListPaths = (
+			);
 			inputPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS-frameworks.sh",
-				"${PODS_XCFRAMEWORKS_BUILD_DIR}/TVVLCKit/TVVLCKit.framework/TVVLCKit",
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
 			);
-			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TVVLCKit.framework",
+				"$(DERIVED_FILE_DIR)/Pods-VLC-iOS-checkManifestLockResult.txt",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS-frameworks.sh\"\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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
-		0A9D17D120C4A14700AA4A8C /* Run SwiftLint Script */ = {
+		249843156C1F5E72AAC05696 /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
-			inputPaths = (
-			);
-			name = "Run SwiftLint Script";
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "${PODS_ROOT}/SwiftLint/swiftlint\n";
-		};
-		16C1AB96786C00EC189F241D /* [CP] Check Pods Manifest.lock */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
+			inputFileListPaths = (
 			);
 			inputPaths = (
 				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
 				"${PODS_ROOT}/Manifest.lock",
 			);
 			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
 			outputPaths = (
-				"$(DERIVED_FILE_DIR)/Pods-VLC-iOSTests-checkManifestLockResult.txt",
+				"$(DERIVED_FILE_DIR)/Pods-VLC-iOS-Screenshots-checkManifestLockResult.txt",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
-		23B425DEB65EA5C88D873ED2 /* [CP] Check Pods Manifest.lock */ = {
+		41F7087C1F37900A00953630 /* Generate Localized Strings */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
-				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
-				"${PODS_ROOT}/Manifest.lock",
 			);
-			name = "[CP] Check Pods Manifest.lock";
+			name = "Generate Localized Strings";
 			outputPaths = (
-				"$(DERIVED_FILE_DIR)/Pods-VLC-iOS-checkManifestLockResult.txt",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
-			showEnvVarsInLog = 0;
+			shellScript = "python3 Tools/update_strings.py Resources/en.lproj/Localizable.strings\n";
 		};
-		2E5934DFBFA4E9DF220B9070 /* [CP] Check Pods Manifest.lock */ = {
+		6B1272663E377D4BC4DCBF9D /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
@@ -2951,48 +2925,50 @@
 			outputFileListPaths = (
 			);
 			outputPaths = (
-				"$(DERIVED_FILE_DIR)/Pods-VLC-iOS-Screenshots-checkManifestLockResult.txt",
+				"$(DERIVED_FILE_DIR)/Pods-VLC-tvOS-checkManifestLockResult.txt",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
-		3696DF9BCC8B754F06D345D9 /* [CP] Embed Pods Frameworks */ = {
+		982755253ECF96B8E3B17FEE /* [CP] Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-VLC-iOS/Pods-VLC-iOS-frameworks.sh",
-				"${PODS_XCFRAMEWORKS_BUILD_DIR}/MobileVLCKit/MobileVLCKit.framework/MobileVLCKit",
-				"${PODS_XCFRAMEWORKS_BUILD_DIR}/VLCMediaLibraryKit/VLCMediaLibraryKit.framework/VLCMediaLibraryKit",
+				"${PODS_ROOT}/Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS-frameworks.sh",
+				"${PODS_XCFRAMEWORKS_BUILD_DIR}/TVVLCKit/TVVLCKit.framework/TVVLCKit",
 			);
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MobileVLCKit.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/VLCMediaLibraryKit.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TVVLCKit.framework",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VLC-iOS/Pods-VLC-iOS-frameworks.sh\"\n";
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		41F7087C1F37900A00953630 /* Generate Localized Strings */ = {
+		9FC273B6B91160C54B8FDFE5 /* [CP] Copy Pods Resources */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS-resources.sh",
+				"${PODS_CONFIGURATION_BUILD_DIR}/XKKeychain-tvOS/XKKeychain.bundle",
 			);
-			name = "Generate Localized Strings";
+			name = "[CP] Copy Pods Resources";
 			outputPaths = (
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/XKKeychain.bundle",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "python3 Tools/update_strings.py Resources/en.lproj/Localizable.strings\n";
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VLC-tvOS/Pods-VLC-tvOS-resources.sh\"\n";
+			showEnvVarsInLog = 0;
 		};
-		9706D52A0CDF446E336826A6 /* [CP] Copy Pods Resources */ = {
+		A7E516CDB189F9DFEC0DA54B /* [CP] Copy Pods Resources */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
@@ -3016,24 +2992,48 @@
 			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VLC-iOS/Pods-VLC-iOS-resources.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		CEAC60B72FF5CB91256BC99B /* [CP] Check Pods Manifest.lock */ = {
+		DFC9085B196928CE07634712 /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
+			inputFileListPaths = (
+			);
 			inputPaths = (
 				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
 				"${PODS_ROOT}/Manifest.lock",
 			);
 			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
 			outputPaths = (
-				"$(DERIVED_FILE_DIR)/Pods-VLC-tvOS-checkManifestLockResult.txt",
+				"$(DERIVED_FILE_DIR)/Pods-VLC-iOSTests-checkManifestLockResult.txt",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
+		F03D8E7BCA1DC4981CDB963A /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-VLC-iOS/Pods-VLC-iOS-frameworks.sh",
+				"${PODS_XCFRAMEWORKS_BUILD_DIR}/MobileVLCKit/MobileVLCKit.framework/MobileVLCKit",
+				"${PODS_XCFRAMEWORKS_BUILD_DIR}/VLCMediaLibraryKit/VLCMediaLibraryKit.framework/VLCMediaLibraryKit",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MobileVLCKit.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/VLCMediaLibraryKit.framework",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VLC-iOS/Pods-VLC-iOS-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
@@ -3185,6 +3185,7 @@
 				4090705925A60341004667E7 /* OptionsNavigationBar.swift in Sources */,
 				444E5C0024C719480003B69C /* AboutController.swift in Sources */,
 				41D7DD2720C3060300AD94F6 /* PagerStripViewController.swift in Sources */,
+				D98EE7452846183F00E6B02D /* GraphTableViewController.swift in Sources */,
 				413EC98B201B4F2C00BF412F /* PresentationTheme.swift in Sources */,
 				DDF908D01CF4CCAA00108B70 /* VLCNetworkLoginViewButtonCell.m in Sources */,
 				DD3EFF3D1BDEBCE500B68579 /* VLCLocalNetworkServiceBrowserHTTP.m in Sources */,
@@ -3361,16 +3362,15 @@
 				DD3EFEEE1BDEBA3800B68579 /* VLCServerListViewController.m in Sources */,
 				8DE187832105DB2E00A091D2 /* AudioViewController.swift in Sources */,
 				7DB0CB42247FCBCE00077592 /* VLCLocalNetworkServiceBrowserUPnP.m in Sources */,
-				7D1052E91A4DCC1100295F08 /* VLCOneDriveTableViewController.m in Sources */,
 				7D30F3D7183AB2F100FFC021 /* VLCNetworkListCell.m in Sources */,
 				44C8BBB124AF36F4003F8940 /* ActionSheetSpecifier.swift in Sources */,
 				44B5822024E434FD001A2583 /* MediaGridCollectionCell.swift in Sources */,
 				8D6E1588223BBAF600077DD3 /* MiniPlayer.swift in Sources */,
-				7D1052EE1A4DCD1E00295F08 /* VLCOneDriveController.m in Sources */,
 				414396C22023316C005E3FAF /* AppearanceManager.swift in Sources */,
 				7D30F3DC183AB2F900FFC021 /* VLCNetworkLoginViewController.m in Sources */,
 				91F8BF1827318D890058D9DE /* StoreProductCollectionViewCell.swift in Sources */,
 				91D33C7325E6B6E700CC49BE /* VideoPlayerInfoView.swift in Sources */,
+				D96ACA962832836C00DD1A3E /* GraphViewController.swift in Sources */,
 				8DE18890210B53E000A091D2 /* TrackModel.swift in Sources */,
 				8DE18898210F144B00A091D2 /* GenreModel.swift in Sources */,
 				7D310885245F1EE100BC6D79 /* VLCMediaFileDownloader.m in Sources */,
@@ -3531,7 +3531,7 @@
 /* Begin XCBuildConfiguration section */
 		4133CAE322CCB0620047A4EC /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = D581CD3C269D82BD6A25E543 /* Pods-VLC-iOS-Screenshots.debug.xcconfig */;
+			baseConfigurationReference = B1CA1021683B1DE3C1E367A6 /* Pods-VLC-iOS-Screenshots.debug.xcconfig */;
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@@ -3567,7 +3567,7 @@
 		};
 		4133CAE422CCB0620047A4EC /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 5671052B495534848FA467EE /* Pods-VLC-iOS-Screenshots.release.xcconfig */;
+			baseConfigurationReference = 2E995114543D1E41A5A82486 /* Pods-VLC-iOS-Screenshots.release.xcconfig */;
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@@ -3603,7 +3603,7 @@
 		};
 		4133CAE522CCB0620047A4EC /* Distribution */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 703A80CCC005093CCDFBECBF /* Pods-VLC-iOS-Screenshots.distribution.xcconfig */;
+			baseConfigurationReference = FC34D45714F6ABBFF4645E35 /* Pods-VLC-iOS-Screenshots.distribution.xcconfig */;
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@@ -3639,7 +3639,7 @@
 		};
 		41533C99211338D600EC3ABA /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 3E95DC30A81B2AF9F7442E00 /* Pods-VLC-iOSTests.debug.xcconfig */;
+			baseConfigurationReference = C177035ADC636FBBDB2F537A /* Pods-VLC-iOSTests.debug.xcconfig */;
 			buildSettings = {
 				BUNDLE_LOADER = "$(TEST_HOST)";
 				CLANG_ANALYZER_NONNULL = YES;
@@ -3676,7 +3676,7 @@
 		};
 		41533C9A211338D600EC3ABA /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 7FC9CCF39DD8843873A42D34 /* Pods-VLC-iOSTests.release.xcconfig */;
+			baseConfigurationReference = C3E0FA5F7E6B347A85A3E252 /* Pods-VLC-iOSTests.release.xcconfig */;
 			buildSettings = {
 				BUNDLE_LOADER = "$(TEST_HOST)";
 				CLANG_ANALYZER_NONNULL = YES;
@@ -3714,7 +3714,7 @@
 		};
 		41533C9B211338D600EC3ABA /* Distribution */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = E39E49F085F7C54D2DB79534 /* Pods-VLC-iOSTests.distribution.xcconfig */;
+			baseConfigurationReference = AF116147FD13655FDCF10359 /* Pods-VLC-iOSTests.distribution.xcconfig */;
 			buildSettings = {
 				BUNDLE_LOADER = "$(TEST_HOST)";
 				CLANG_ANALYZER_NONNULL = YES;
@@ -3902,7 +3902,7 @@
 		};
 		7D1329511BA1F10100BE647E /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = F25DF68DCD1A8FA89D1933B3 /* Pods-VLC-tvOS.debug.xcconfig */;
+			baseConfigurationReference = 723659CB3834E1B30918E514 /* Pods-VLC-tvOS.debug.xcconfig */;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
 				ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
@@ -3947,7 +3947,7 @@
 		};
 		7D1329521BA1F10100BE647E /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 2B1BC34A3BC4BCE7588BD68A /* Pods-VLC-tvOS.release.xcconfig */;
+			baseConfigurationReference = BB4AA60FE9D8D55360CC4ED3 /* Pods-VLC-tvOS.release.xcconfig */;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
 				ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
@@ -3992,7 +3992,7 @@
 		};
 		7D1329531BA1F10100BE647E /* Distribution */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = AC40202FFE42CEDCEB37E50D /* Pods-VLC-tvOS.distribution.xcconfig */;
+			baseConfigurationReference = 57087A12E77ACEB9D1D30E33 /* Pods-VLC-tvOS.distribution.xcconfig */;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
 				ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
@@ -4141,7 +4141,7 @@
 		};
 		7D94FD0B16DE7D1100F2623B /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 3B75A76DF6589FE678357D42 /* Pods-VLC-iOS.debug.xcconfig */;
+			baseConfigurationReference = 535ECB057D81248C91FA25C4 /* Pods-VLC-iOS.debug.xcconfig */;
 			buildSettings = {
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
 				ARCHS = (
@@ -4189,7 +4189,7 @@
 		};
 		7D94FD0C16DE7D1100F2623B /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = C6872E7B396534F3DAF4E48F /* Pods-VLC-iOS.release.xcconfig */;
+			baseConfigurationReference = 3B79FA55420524A988373783 /* Pods-VLC-iOS.release.xcconfig */;
 			buildSettings = {
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
 				ARCHS = (
@@ -4286,7 +4286,7 @@
 		};
 		A7035BC0174519E40057DFA7 /* Distribution */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 5B343E4F4D971F5A169EB864 /* Pods-VLC-iOS.distribution.xcconfig */;
+			baseConfigurationReference = 027E1E187A0A43CF5CFAECEC /* Pods-VLC-iOS.distribution.xcconfig */;
 			buildSettings = {
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
 				ARCHS = (
diff --git a/vlc-ios/VLC-iOS-Bridging-Header.h b/vlc-ios/VLC-iOS-Bridging-Header.h
index d807b78bf8532c19cdb7d2a6cd92d7546f005139..9c4801624d0c537fa4746ad975e45b8f781bfdec 100644
--- a/vlc-ios/VLC-iOS-Bridging-Header.h
+++ b/vlc-ios/VLC-iOS-Bridging-Header.h
@@ -26,6 +26,7 @@
 #import "VLCMediaFileDiscoverer.h"
 #import "VLCMigrationViewController.h"
 #import "VLCCloudStorageTableViewController.h"
+#import "VLCCloudStorageTableViewCell.h"
 #import "VLCMetadata.h"
 #import "VLCPlayerDisplayController.h"
 #import "NSString+SupportedMedia.h"