diff --git a/Sources/Brave/Frontend/Settings/Debug/BraveTalkLogsView.swift b/Sources/Brave/Frontend/Settings/Debug/BraveTalkLogsView.swift new file mode 100644 index 000000000000..cc5ed0c0cdc3 --- /dev/null +++ b/Sources/Brave/Frontend/Settings/Debug/BraveTalkLogsView.swift @@ -0,0 +1,77 @@ +// Copyright 2024 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import Foundation +import SwiftUI +import os.log +import OSLog + +struct BraveTalkLogsView: View { + @State private var logs: String = "" + @State private var isLoading: Bool = true + @State private var showShareSheet: Bool = false + @State private var fileURL: URL? + + var body: some View { + VStack { + if isLoading { + ProgressView() + } else { + ScrollView { + Text(logs.isEmpty ? "No logs" : logs) + .padding() + } + } + } + .navigationBarItems(trailing: ShareButton()) + .task { + logs = await getLogs() + fileURL = createTemporaryLogFile() + isLoading = false + } + } + + @ViewBuilder private func ShareButton() -> some View { + if #available(iOS 16, *) { + ShareLink(item: fileURL ?? URL(string: "disabled")!) + .disabled(fileURL == nil || logs.isEmpty) + } else { + EmptyView() + } + } + + private func createTemporaryLogFile() -> URL { + let temporaryDirectoryURL = FileManager.default.temporaryDirectory + let logFileURL = temporaryDirectoryURL.appendingPathComponent("Logs.txt") + + try? logs.write(to: logFileURL, atomically: true, encoding: .utf8) + return logFileURL + } + + private func getLogs() async -> String { + do { + let store = try OSLogStore(scope: .currentProcessIdentifier) + + return try store + .getEntries() + .compactMap { $0 as? OSLogEntryLog } + .filter { $0.category == "BraveTalk" && $0.subsystem == Bundle.main.bundleIdentifier } + .map { "[\($0.date.formatted())] \($0.composedMessage)" } + .joined(separator: "\n") + } catch { + Logger.module.error("\(error.localizedDescription, privacy: .public)") + } + + return "" + } +} + +#if DEBUG +struct BraveTalkLogsView_Previews: PreviewProvider { + static var previews: some View { + BraveTalkLogsView() + } +} +#endif diff --git a/Sources/Brave/Frontend/Settings/Debug/BraveTalkLogsViewController.swift b/Sources/Brave/Frontend/Settings/Debug/BraveTalkLogsViewController.swift deleted file mode 100644 index aca02948ee5d..000000000000 --- a/Sources/Brave/Frontend/Settings/Debug/BraveTalkLogsViewController.swift +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2024 The Brave Authors. All rights reserved. -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -import UIKit -import os.log -import OSLog -import SnapKit - -public class BraveTalkLogsViewController: UIViewController { - - private var logsTextView = UITextView() - - public override func viewDidLoad() { - super.viewDidLoad() - - logsTextView.isEditable = false - view.addSubview(logsTextView) - logsTextView.snp.makeConstraints { - $0.edges.equalToSuperview() - } - - logsTextView.text = getLogs() - - let shareButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareLogs)) - navigationItem.rightBarButtonItem = shareButton - } - - @objc private func shareLogs() { - do { - let fileURL = try createTemporaryLogFile() - let activityViewController = UIActivityViewController(activityItems: [fileURL], applicationActivities: nil) - present(activityViewController, animated: true) - } catch { - Logger.module.error("Error while creating the log file: \(error.localizedDescription, privacy: .public)") - } - } - - private func createTemporaryLogFile() throws -> URL { - let logsString = getLogs() - let temporaryDirectoryURL = FileManager.default.temporaryDirectory - let logFileURL = temporaryDirectoryURL.appendingPathComponent("Logs.txt") - - try logsString.write(to: logFileURL, atomically: true, encoding: .utf8) - return logFileURL - } - - private func getLogs() -> String { - do { - let store = try OSLogStore(scope: .currentProcessIdentifier) - - return try store - .getEntries() - .compactMap { $0 as? OSLogEntryLog } - .filter { $0.category == "BraveTalk" && $0.subsystem == Bundle.main.bundleIdentifier } - .map { "[\($0.date.formatted())] \($0.composedMessage)" } - .joined(separator: "\n") - } catch { - Logger.module.error("\(error.localizedDescription, privacy: .public)") - } - - return "" - } -} diff --git a/Sources/Brave/Frontend/Settings/SettingsViewController.swift b/Sources/Brave/Frontend/Settings/SettingsViewController.swift index cc9b00aaddf5..8b1275eccbef 100644 --- a/Sources/Brave/Frontend/Settings/SettingsViewController.swift +++ b/Sources/Brave/Frontend/Settings/SettingsViewController.swift @@ -864,7 +864,8 @@ class SettingsViewController: TableViewController { Row( text: "Brave Talk Logs", selection: { [unowned self] in - self.navigationController?.pushViewController(BraveTalkLogsViewController(), animated: true) + let controller = UIHostingController(rootView: BraveTalkLogsView()) + self.navigationController?.pushViewController(controller, animated: true) }, accessory: .disclosureIndicator, cellClass: MultilineValue1Cell.self), Row( text: "Retention Preferences Debug Menu",