186 lines
7.0 KiB
Swift
186 lines
7.0 KiB
Swift
//
|
||
// FormatLogViewController.swift
|
||
// Note
|
||
//
|
||
// Created by fish on 2026/7/12.
|
||
//
|
||
|
||
import UIKit
|
||
|
||
class FormatLogViewController: UIViewController {
|
||
|
||
private var textView: UITextView!
|
||
private var formatButton: UIButton!
|
||
private var doneButton: UIBarButtonItem!
|
||
private var pasteButton: UIBarButtonItem!
|
||
private var resetButton: UIBarButtonItem!
|
||
private var isFormatted = false
|
||
private var rightBarButtonMode: RightBarButtonMode = .paste
|
||
|
||
private enum RightBarButtonMode {
|
||
case paste
|
||
case reset
|
||
}
|
||
|
||
override func viewDidLoad() {
|
||
super.viewDidLoad()
|
||
title = "格式化日志"
|
||
navigationItem.largeTitleDisplayMode = .never
|
||
view.backgroundColor = .systemGroupedBackground
|
||
setupUI()
|
||
}
|
||
|
||
private func setupUI() {
|
||
textView = UITextView()
|
||
textView.translatesAutoresizingMaskIntoConstraints = false
|
||
textView.font = UIFont.systemFont(ofSize: 16)
|
||
textView.backgroundColor = .white
|
||
textView.layer.cornerRadius = 12
|
||
textView.textContainerInset = UIEdgeInsets(top: 12, left: 12, bottom: 12, right: 12)
|
||
textView.delegate = self
|
||
view.addSubview(textView)
|
||
|
||
doneButton = UIBarButtonItem(title: "完成", style: .prominent, target: self, action: #selector(didTapDoneButton))
|
||
pasteButton = UIBarButtonItem(title: "粘贴文案", style: .plain, target: self, action: #selector(didTapPasteButton))
|
||
resetButton = UIBarButtonItem(title: "重置", style: .plain, target: self, action: #selector(didTapResetButton))
|
||
|
||
updateRightBarButtonItem()
|
||
|
||
formatButton = UIButton(type: .system)
|
||
formatButton.translatesAutoresizingMaskIntoConstraints = false
|
||
formatButton.setTitle("格式化", for: .normal)
|
||
formatButton.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
|
||
formatButton.backgroundColor = .systemBlue
|
||
formatButton.setTitleColor(.white, for: .normal)
|
||
formatButton.layer.cornerRadius = 12
|
||
formatButton.addTarget(self, action: #selector(didTapFormatButton), for: .touchUpInside)
|
||
view.addSubview(formatButton)
|
||
|
||
NSLayoutConstraint.activate([
|
||
textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16),
|
||
textView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
|
||
textView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
|
||
textView.bottomAnchor.constraint(equalTo: formatButton.topAnchor, constant: -16),
|
||
|
||
formatButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
|
||
formatButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
|
||
formatButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -16),
|
||
formatButton.heightAnchor.constraint(equalToConstant: 52)
|
||
])
|
||
}
|
||
|
||
@objc private func didTapDoneButton() {
|
||
textView.resignFirstResponder()
|
||
}
|
||
|
||
@objc private func didTapFormatButton() {
|
||
if isFormatted {
|
||
saveToFiles()
|
||
} else {
|
||
textView.text = formatLog(textView.text)
|
||
isFormatted = true
|
||
formatButton.setTitle("保存到 iCloud", for: .normal)
|
||
rightBarButtonMode = .reset
|
||
updateRightBarButtonItem()
|
||
}
|
||
}
|
||
|
||
@objc private func didTapPasteButton() {
|
||
if let string = UIPasteboard.general.string {
|
||
textView.text = string
|
||
}
|
||
}
|
||
|
||
@objc private func didTapResetButton() {
|
||
textView.text = ""
|
||
isFormatted = false
|
||
formatButton.setTitle("格式化", for: .normal)
|
||
rightBarButtonMode = .paste
|
||
updateRightBarButtonItem()
|
||
}
|
||
|
||
private func updateRightBarButtonItem() {
|
||
if textView.isFirstResponder {
|
||
navigationItem.rightBarButtonItem = doneButton
|
||
} else {
|
||
switch rightBarButtonMode {
|
||
case .paste:
|
||
navigationItem.rightBarButtonItem = pasteButton
|
||
case .reset:
|
||
navigationItem.rightBarButtonItem = resetButton
|
||
}
|
||
}
|
||
}
|
||
|
||
private func saveToFiles() {
|
||
let fileName = generateFileName()
|
||
let fileURL = FileManager.default.temporaryDirectory.appendingPathComponent(fileName)
|
||
|
||
do {
|
||
try textView.text.write(to: fileURL, atomically: true, encoding: .utf8)
|
||
let documentPicker = UIDocumentPickerViewController(forExporting: [fileURL], asCopy: true)
|
||
documentPicker.delegate = self
|
||
present(documentPicker, animated: true)
|
||
} catch {
|
||
print("Failed to write file: \(error)")
|
||
}
|
||
}
|
||
|
||
private func generateFileName() -> String {
|
||
let text = textView.text ?? ""
|
||
let firstLine = text.components(separatedBy: .newlines).first ?? ""
|
||
let trimmed = firstLine.trimmingCharacters(in: .whitespaces)
|
||
let withoutHash = trimmed.replacingOccurrences(of: "^#\\s*", with: "", options: .regularExpression)
|
||
let cleanName = withoutHash.trimmingCharacters(in: .whitespaces)
|
||
|
||
if cleanName.isEmpty {
|
||
return "formatted_log_\(Int(Date().timeIntervalSince1970)).md"
|
||
}
|
||
return cleanName + ".md"
|
||
}
|
||
|
||
private func formatLog(_ text: String) -> String {
|
||
var content = text
|
||
|
||
content = content.replacingOccurrences(of: "# ", with: "")
|
||
content = content.replacingOccurrences(of: "#", with: "")
|
||
content = content.replacingOccurrences(of: ";", with: "。")
|
||
content = content.replacingOccurrences(of: ";", with: "。")
|
||
content = content.replacingOccurrences(of: ".", with: "。")
|
||
content = content.replacingOccurrences(of: "(", with: "(")
|
||
content = content.replacingOccurrences(of: ")", with: ")")
|
||
content = content.replacingOccurrences(of: "?", with: "?")
|
||
content = content.replacingOccurrences(of: ",", with: ",")
|
||
content = content.replacingOccurrences(of: ":", with: ":")
|
||
content = content.replacingOccurrences(of: "日星期", with: "日 星期")
|
||
content = "# " + content
|
||
content = content.replacingOccurrences(of: "一、生活方面", with: "## 一、生活方面")
|
||
content = content.replacingOccurrences(of: "二、交易方面", with: "## 二、交易方面")
|
||
content = content.replacingOccurrences(of: "三、工作方面", with: "## 三、工作方面")
|
||
|
||
return content
|
||
}
|
||
}
|
||
|
||
extension FormatLogViewController: UITextViewDelegate {
|
||
|
||
func textViewDidBeginEditing(_ textView: UITextView) {
|
||
updateRightBarButtonItem()
|
||
}
|
||
|
||
func textViewDidEndEditing(_ textView: UITextView) {
|
||
updateRightBarButtonItem()
|
||
}
|
||
}
|
||
|
||
extension FormatLogViewController: UIDocumentPickerDelegate {
|
||
|
||
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
|
||
// File saved to selected location
|
||
}
|
||
|
||
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
|
||
// User cancelled
|
||
}
|
||
}
|