Signal-iOS/SignalUI/Views/CustomKeyboard.swift
Evan Hahn 370ff654e7
Change license to AGPL
Change license to AGPL

This commit:

- Updates the `LICENSE` file

- Start every file with something like:

      // Copyright YEAR_FIRST_PUBLISHED Signal Messenger, LLC
      // SPDX-License-Identifier: AGPL-3.0-only

---

First, I removed existing license headers with this Ruby 3.1.2 script:

    require 'set'

    EXTENSIONS_TO_CHECK = Set['.h', '.hpp', '.cpp', '.m', '.mm', '.pch', '.swift']

    same = 0
    different = 0

    all_files = `git ls-files`.lines.map { |line| line.strip }
    all_files.each do |relative_path|
      if relative_path == 'Pods'
        next
      end

      unless EXTENSIONS_TO_CHECK.include? File.extname(relative_path)
        next
      end

      path = File.expand_path(relative_path)

      contents = File.read(path)
      new_contents = contents.sub(/\/\/\n\/\/  Copyright .*\n\/\/\n\n/, '')

      if contents == new_contents
        same += 1
      else
        different += 1
      end

      File.write(path, new_contents)
    end

    puts "updated #{different} file(s), left #{same} untouched"

I'm sure this script could be improved, but it worked well enough.

Then, I created `Scripts/lint/lint-license-headers` and ran it to auto-
fix a lot of files. This changed the mode of some files, but I think
that's actually desirable. For example,
`SignalServiceKit/src/Util/AppContext.m` previously had a mode of
`0755/-rwxr-xr-x`, and it's now `0644/-rw-r--r--`.

Then I fixed some stragglers and updated the precommit script.

See [a similar change in the Desktop app][0].

[0]: 8bfaf598af
2022-10-13 08:25:37 -05:00

158 lines
4.6 KiB
Swift

//
// Copyright 2019 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
@objc(OWSCustomKeyboard)
open class CustomKeyboard: UIInputView {
@objc
public let contentView = UIView()
@objc
public init() {
super.init(frame: .zero, inputViewStyle: .default)
addSubview(contentView)
contentView.autoPinEdgesToSuperviewEdges()
NotificationCenter.default.addObserver(
self,
selector: #selector(orientationDidChange),
name: UIDevice.orientationDidChangeNotification,
object: UIDevice.current
)
translatesAutoresizingMaskIntoConstraints = false
allowsSelfSizing = true
resizeToSystemKeyboard()
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
open func willPresent() {}
open func wasPresented() {}
open func wasDismissed() {}
@objc
public func registerWithView(_ view: UIView) {
view.addSubview(responder)
}
private lazy var responder = CustomKeyboardResponder(customKeyboard: self)
override open var isFirstResponder: Bool { return responder.isFirstResponder }
open override func becomeFirstResponder() -> Bool {
let result = responder.becomeFirstResponder()
if result { willPresent() }
return result
}
open override func resignFirstResponder() -> Bool {
return responder.resignFirstResponder()
}
open override func didMoveToSuperview() {
// Call wasPresented/wasDismissed on the next run loop,
// once this view hierarchy change has finished.
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
if self.superview == nil {
self.wasDismissed()
} else {
self.wasPresented()
}
}
}
// MARK: - Height Management
private lazy var heightConstraint = autoSetDimension(.height, toSize: 0)
private struct SystemKeyboardHeight {
var landscape: CGFloat?
var portrait: CGFloat?
var current: CGFloat? {
get {
return CurrentAppContext().interfaceOrientation.isLandscape ? landscape : portrait
}
set {
if CurrentAppContext().interfaceOrientation.isLandscape {
landscape = newValue
} else {
portrait = newValue
}
}
}
}
private var cachedSystemKeyboardHeight = SystemKeyboardHeight()
@objc
public func updateSystemKeyboardHeight(_ height: CGFloat) {
// Only respect this height if it's reasonable, we don't want
// to have a tiny keyboard.
guard height > 170 else { return }
cachedSystemKeyboardHeight.current = height
resizeToSystemKeyboard()
}
@objc
open func resizeToSystemKeyboard() {
guard let cachedHeight = cachedSystemKeyboardHeight.current else {
// We don't have a cached height for this orientation,
// let the auto sizing do its best guess at what the
// system keyboard height might be.
heightConstraint.isActive = false
allowsSelfSizing = false
return
}
// We have a cached height so we want to size ourself. The system
// sizing isn't a 100% match to the system keyboard's size and
// does not account for things like the quicktype toolbar.
allowsSelfSizing = true
heightConstraint.isActive = true
heightConstraint.constant = cachedHeight
}
open override func layoutSubviews() {
super.layoutSubviews()
resizeToSystemKeyboard()
}
@objc
open func orientationDidChange() {
resizeToSystemKeyboard()
}
}
private class CustomKeyboardResponder: UITextView {
@objc
public weak var customKeyboard: CustomKeyboard?
init(customKeyboard: CustomKeyboard) {
self.customKeyboard = customKeyboard
super.init(frame: .zero, textContainer: nil)
autocorrectionType = .no
keyboardAppearance = Theme.keyboardAppearance
inputAssistantItem.leadingBarButtonGroups = []
inputAssistantItem.trailingBarButtonGroups = []
}
override var inputView: UIView? {
get { customKeyboard }
set {}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override var canBecomeFirstResponder: Bool {
return true
}
}