-
Notifications
You must be signed in to change notification settings - Fork 199
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #269 from mahee96/master
-[Feature]: Multi-line input for adding bulk tracker URLs
- Loading branch information
Showing
8 changed files
with
463 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// | ||
// EditTextViewController.swift | ||
// iTorrent | ||
// | ||
// Created by Magesh K on 17.10.2023. | ||
// Copyright © 2023 Magesh K. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import UIKit | ||
|
||
// EditTextView - UI Control | ||
class EditTextView: UITextView{ | ||
|
||
// Set margins using UIEdgeInsets | ||
let defaultMargins = UIEdgeInsets(top: 4, left: 12, bottom: 12, right: 12) | ||
let defaultPlaceholder = NSLocalizedString("PlaceHolder text", comment: "") | ||
|
||
// Custom placeholder text | ||
var placeholder: String? { | ||
didSet { placeholderLabel.text = placeholder } | ||
} | ||
|
||
// Custom placeholder text color | ||
var placeholderTextColor: UIColor = .lightGray { | ||
didSet { placeholderLabel.textColor = placeholderTextColor } | ||
} | ||
|
||
// Private UILabel for the placeholder text | ||
private let placeholderLabel: UILabel = { | ||
let label = UILabel() | ||
label.textColor = .lightGray | ||
return label | ||
}() | ||
|
||
|
||
/* Override methods */ | ||
override init(frame: CGRect, textContainer: NSTextContainer?){ | ||
super.init(frame: frame, textContainer:textContainer) | ||
performCustomizations() | ||
} | ||
|
||
required init?(coder: NSCoder){ | ||
super.init(coder:coder) | ||
performCustomizations() | ||
} | ||
|
||
|
||
/* Helper methods */ | ||
private func performCustomizations() -> Void{ | ||
let textView = self | ||
let theme = Themes.current | ||
|
||
textView.keyboardAppearance = theme.keyboardAppearence | ||
textView.autoresizingMask = [.flexibleWidth, .flexibleHeight] | ||
textView.font = UIFont.systemFont(ofSize: UIFont.systemFontSize * 1.0) | ||
textView.contentInset.left = 2 //For left padding | ||
textView.contentInset.right = 2 //For right padding | ||
textView.contentInset.top = 2 //For top padding | ||
textView.contentInset.bottom = 2 //For bottom padding | ||
|
||
textView.layer.borderWidth = 0.5 | ||
textView.layer.cornerRadius = 8 | ||
textView.layer.borderColor = UIColor.lightGray.withAlphaComponent(0.5).cgColor | ||
textView.layer.backgroundColor = nil | ||
textView.returnKeyType = .default | ||
textView.autocapitalizationType = .none | ||
|
||
textView.translatesAutoresizingMaskIntoConstraints = false | ||
setupPlaceholderLabel() | ||
} | ||
|
||
private func setupPlaceholderLabel() { | ||
addSubview(placeholderLabel) | ||
|
||
placeholder = self.defaultPlaceholder | ||
placeholderLabel.font = UIFont.systemFont(ofSize: UIFont.systemFontSize * 1.0) | ||
placeholderLabel.layer.borderColor = UIColor.lightGray.withAlphaComponent(0.5).cgColor | ||
|
||
placeholderLabel.translatesAutoresizingMaskIntoConstraints = false | ||
// Set constraints for the placeholder label | ||
NSLayoutConstraint.activate([ | ||
placeholderLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: self.contentInset.left+4), | ||
placeholderLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -(self.contentInset.right+4)), | ||
placeholderLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: self.contentInset.top+6), | ||
placeholderLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -(self.contentInset.bottom+6)) | ||
]) | ||
|
||
// Hide the placeholder label when there is text | ||
NotificationCenter.default.addObserver(self, selector: #selector(textDidChange), name: UITextView.textDidChangeNotification, object: nil) | ||
} | ||
|
||
@objc private func textDidChange() { | ||
placeholderLabel.isHidden = !text.isEmpty | ||
} | ||
|
||
public func setDefaultMargins(){ | ||
setMargins(by: self.defaultMargins) | ||
} | ||
|
||
|
||
public func setMargins(by: UIEdgeInsets){ | ||
let margins = by | ||
if let containerView = self.superview{ | ||
self.frame = containerView.frame | ||
// Add constraints to the UITextView within the parent view | ||
NSLayoutConstraint.activate([ | ||
self.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: margins.left), | ||
self.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -margins.right), | ||
self.topAnchor.constraint(equalTo: containerView.topAnchor, constant: margins.top), | ||
self.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -margins.bottom) | ||
]) | ||
} | ||
} | ||
|
||
// callback for superview changes | ||
override func didMoveToSuperview() { | ||
// attach superView's frame reference into this view | ||
// and set margins if superView is present | ||
self.setDefaultMargins() | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
iTorrent/CustomViews/EditTextView/EditTextViewController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// | ||
// EditTextViewController.swift | ||
// iTorrent | ||
// | ||
// Created by Magesh K on 17.10.2023. | ||
// Copyright © 2023 Magesh K. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import UIKit | ||
|
||
class EditTextViewController: UIViewController, UITextViewDelegate { | ||
|
||
private let editTextView:EditTextView | ||
private let SINGLE_LINE_HEIGHT:Double = 54.0 | ||
|
||
convenience init(){ | ||
self.init(editTextView: EditTextView()) | ||
} | ||
|
||
init(editTextView: EditTextView){ | ||
self.editTextView = editTextView | ||
super.init(nibName: nil, bundle: nil) | ||
} | ||
|
||
required init?(coder: NSCoder) { | ||
self.editTextView = EditTextView() | ||
super.init(coder: coder) | ||
} | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
// add the UITextView | ||
self.view.addSubview(self.editTextView) | ||
// register callback for textView changes | ||
editTextView.delegate = self | ||
// Create a height constraint for the view controller's view | ||
viewControllerHeightConstraint = view.heightAnchor.constraint(equalToConstant: SINGLE_LINE_HEIGHT) | ||
viewControllerHeightConstraint.isActive = true | ||
} | ||
|
||
var viewControllerHeightConstraint: NSLayoutConstraint! | ||
|
||
func textViewDidChange(_ textView: UITextView) { | ||
|
||
let maxLinesToShow:Double = 1.5 | ||
let maxContentSize:Double = SINGLE_LINE_HEIGHT * maxLinesToShow | ||
|
||
var contentSize:Double = textView.contentSize.height + 17.0 | ||
if contentSize > maxContentSize{ | ||
contentSize = maxContentSize | ||
} | ||
if contentSize < SINGLE_LINE_HEIGHT{ | ||
contentSize = SINGLE_LINE_HEIGHT | ||
} | ||
|
||
if(contentSize != prevContentSize){ | ||
// Calculate the content height of the UITextView | ||
// Update the height constraint of the view controller's view | ||
viewControllerHeightConstraint.constant = contentSize | ||
|
||
// Optionally, animate the constraint change | ||
UIView.animate( | ||
withDuration: 0.5, | ||
delay: 0.0, | ||
usingSpringWithDamping: 0.5, // Adjust this value (lower for more bounce, higher for less) | ||
initialSpringVelocity: 0.0, //Adjust this value (higher for more initial velocity) | ||
options: [.curveEaseInOut], // Use curveEaseInOut | ||
animations: { | ||
self.view.layoutIfNeeded() | ||
}, | ||
completion: nil | ||
) | ||
} | ||
prevContentSize = contentSize | ||
|
||
|
||
// Optionally, you can scroll to the bottom as the user types | ||
// let bottomOffset = CGPoint(x: 0, y: max(textView.contentSize.height - textView.bounds.size.height, 0)) | ||
// textView.setContentOffset(bottomOffset, animated: false) | ||
} | ||
|
||
private var prevContentSize: Double = 0.0 | ||
} |
91 changes: 91 additions & 0 deletions
91
iTorrent/CustomViews/ProgressView/ProgressViewController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// | ||
// ProgressViewController.swift | ||
// iTorrent | ||
// | ||
// Created by Magesh K on 19/10/23. | ||
// Copyright © 2023 Magesh K. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import UIKit | ||
|
||
class ProgressViewController: UIViewController { | ||
private let progressView = UIActivityIndicatorView(style: .whiteLarge) | ||
private let progressLabel = ThemedUILabel() | ||
private var progress:Float = 0.0 | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
view.backgroundColor = UIColor(white: 0, alpha: 0.7) // Semi-transparent background | ||
|
||
// Do not perform autolayout | ||
progressView.translatesAutoresizingMaskIntoConstraints = false | ||
progressLabel.translatesAutoresizingMaskIntoConstraints = false | ||
view.addSubview(progressView) | ||
view.addSubview(progressLabel) | ||
|
||
progressView.hidesWhenStopped = true | ||
|
||
// explicit layout constraints | ||
NSLayoutConstraint.activate([ | ||
// center the progressView on parent view | ||
progressView.centerXAnchor.constraint(equalTo: view.centerXAnchor), | ||
progressView.centerYAnchor.constraint(equalTo: view.centerYAnchor), | ||
|
||
// place the progress label below the progressView with constant space between the two | ||
progressLabel.topAnchor.constraint(equalTo: progressView.bottomAnchor, constant: 8), // Adjust the spacing as needed | ||
progressLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor), | ||
]) | ||
|
||
progressLabel.textColor = .white | ||
// progressLabel.font = UIFont.systemFont(ofSize: 16) // Adjust the size | ||
// progressLabel.font = UIFont.boldSystemFont(ofSize: 16) | ||
progressLabel.font = UIFont(name: "Helvetica-Bold", size: 16) | ||
progressLabel.backgroundColor = .clear | ||
|
||
progressView.startAnimating() // Start the activity indicator | ||
} | ||
|
||
public func runSyncOnUIThread(action: ()->Void){ | ||
if (Thread.isMainThread){ action() } | ||
else { DispatchQueue.main.sync { action() } } | ||
} | ||
|
||
public func showProgress(presenter: UIViewController?, animated: Bool=true, action: (()->Void)? = nil) { | ||
runSyncOnUIThread{ | ||
progressLabel.text = "0.00%" | ||
modalPresentationStyle = .overFullScreen | ||
modalTransitionStyle = .crossDissolve | ||
presenter?.present(self, animated: animated, completion: action) | ||
} | ||
} | ||
|
||
public func hideProgress(animated: Bool=true, action: (()->Void)? = nil) { | ||
runSyncOnUIThread{ | ||
dismiss(animated: animated, completion: action) | ||
} | ||
} | ||
|
||
public func setProgress(_ progress: Float) { | ||
// Keep progress updates synchronously on UI Thread | ||
runSyncOnUIThread { | ||
self.progress = progress | ||
// cap the progress at 100% | ||
if(progress > 100.0){ self.progress = 100.0 } | ||
self.progressLabel.text = String(format: "%.2f%%", self.progress) | ||
} | ||
} | ||
|
||
public func getProgress()->Float{ | ||
return self.progress | ||
} | ||
|
||
public func consumeRemainingPercentage(){ | ||
var totalProgress = self.progress | ||
let increment:Float = 1.0 | ||
while(totalProgress <= 100.0){ | ||
totalProgress += increment // increment the progress | ||
setProgress(totalProgress) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.