Compare commits
No commits in common. "822c2e0fa262fcf476d2417bf841720d37759db8" and "7449688bfeaf8187cc6bdbbb8e2586c7d1596353" have entirely different histories.
822c2e0fa2
...
7449688bfe
|
@ -1,11 +1,5 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 2023.5 (84)
|
|
||||||
Bugfixes:
|
|
||||||
- Fix notifications scrolling to top when refreshing
|
|
||||||
- Fix decoding statuses failing on GoToSocial
|
|
||||||
- Fix assorted issues when collapsing/expanding between sidebar and tab bar modes
|
|
||||||
|
|
||||||
## 2023.5 (83)
|
## 2023.5 (83)
|
||||||
This build contains significant refactors to the notifications screen, please report any issues you encounter.
|
This build contains significant refactors to the notifications screen, please report any issues you encounter.
|
||||||
|
|
||||||
|
|
|
@ -120,8 +120,8 @@ class PollController: ViewController {
|
||||||
}
|
}
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.background(
|
.background(
|
||||||
RoundedRectangle(cornerRadius: 10, style: .continuous)
|
backgroundColor
|
||||||
.foregroundColor(backgroundColor)
|
.cornerRadius(10)
|
||||||
)
|
)
|
||||||
.onChange(of: controller.duration) { newValue in
|
.onChange(of: controller.duration) { newValue in
|
||||||
poll.duration = newValue.timeInterval
|
poll.duration = newValue.timeInterval
|
||||||
|
|
|
@ -155,7 +155,6 @@ public class DuckableContainerViewController: UIViewController, DuckableViewCont
|
||||||
bottomConstraint.isActive = true
|
bottomConstraint.isActive = true
|
||||||
|
|
||||||
child.view.layer.cornerRadius = duckedCornerRadius
|
child.view.layer.cornerRadius = duckedCornerRadius
|
||||||
child.view.layer.cornerCurve = .continuous
|
|
||||||
child.view.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
|
child.view.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
|
||||||
child.view.layer.masksToBounds = true
|
child.view.layer.masksToBounds = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,12 +51,8 @@ public final class Status: StatusProtocol, Decodable, Sendable {
|
||||||
do {
|
do {
|
||||||
self.url = try container.decodeIfPresent(WebURL.self, forKey: .url)
|
self.url = try container.decodeIfPresent(WebURL.self, forKey: .url)
|
||||||
} catch {
|
} catch {
|
||||||
let s = try? container.decode(String.self, forKey: .url)
|
let s = (try? container.decode(String.self, forKey: .url)) ?? "<failed to decode string>"
|
||||||
if s == "" {
|
throw DecodingError.dataCorruptedError(forKey: .url, in: container, debugDescription: "Could not decode URL '\(s)', reason: \(String(describing: error))")
|
||||||
self.url = nil
|
|
||||||
} else {
|
|
||||||
throw DecodingError.dataCorrupted(.init(codingPath: container.codingPath + [CodingKeys.url], debugDescription: "Could not decode URL '\(s ?? "<failed to decode string>")'", underlyingError: error))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.account = try container.decode(Account.self, forKey: .account)
|
self.account = try container.decode(Account.self, forKey: .account)
|
||||||
self.inReplyToID = try container.decodeIfPresent(String.self, forKey: .inReplyToID)
|
self.inReplyToID = try container.decodeIfPresent(String.self, forKey: .inReplyToID)
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
//
|
//
|
||||||
// CharacterCounterTests.swift
|
// CharacterCounterTests.swift
|
||||||
// ComposeUITests
|
// PachydermTests
|
||||||
//
|
//
|
||||||
// Created by Shadowfacts on 9/29/18.
|
// Created by Shadowfacts on 9/29/18.
|
||||||
// Copyright © 2018 Shadowfacts. All rights reserved.
|
// Copyright © 2018 Shadowfacts. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import ComposeUI
|
@testable import Pachyderm
|
||||||
import InstanceFeatures
|
|
||||||
|
|
||||||
class CharacterCounterTests: XCTestCase {
|
class CharacterCounterTests: XCTestCase {
|
||||||
|
|
||||||
|
@ -17,34 +16,32 @@ class CharacterCounterTests: XCTestCase {
|
||||||
|
|
||||||
override func tearDown() {
|
override func tearDown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let features = InstanceFeatures()
|
|
||||||
|
|
||||||
func testCountEmpty() {
|
func testCountEmpty() {
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "", for: features), 0)
|
XCTAssertEqual(CharacterCounter.count(text: ""), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCountPlainText() {
|
func testCountPlainText() {
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "This is an example message", for: features), 26)
|
XCTAssertEqual(CharacterCounter.count(text: "This is an example message"), 26)
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "This is an example message with an Emoji: 😄", for: features), 43)
|
XCTAssertEqual(CharacterCounter.count(text: "This is an example message with an Emoji: 😄"), 43)
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "😄😄😄😄😄😄😄", for: features), 7)
|
XCTAssertEqual(CharacterCounter.count(text: "😄😄😄😄😄😄😄"), 7)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCountLinks() {
|
func testCountLinks() {
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "This is an example with a link: https://example.com", for: features), 55)
|
XCTAssertEqual(CharacterCounter.count(text: "This is an example with a link: https://example.com"), 55)
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "This is an example with a link 😄: https://example.com", for: features), 57)
|
XCTAssertEqual(CharacterCounter.count(text: "This is an example with a link 😄: https://example.com"), 57)
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "😄😄😄😄😄😄😄: https://example.com", for: features), 32)
|
XCTAssertEqual(CharacterCounter.count(text: "😄😄😄😄😄😄😄: https://example.com"), 32)
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "This is an example with a link: https://a.much.longer.example.com/link?foo=bar#baz", for: features), 55)
|
XCTAssertEqual(CharacterCounter.count(text: "This is an example with a link: https://a.much.longer.example.com/link?foo=bar#baz"), 55)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCountLocalMentions() {
|
func testCountLocalMentions() {
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "hello @example", for: features), 14)
|
XCTAssertEqual(CharacterCounter.count(text: "hello @example"), 14)
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "@some_really_long_name", for: features), 22)
|
XCTAssertEqual(CharacterCounter.count(text: "@some_really_long_name"), 22)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCountRemoteMentions() {
|
func testCountRemoteMentions() {
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "hello @example@some.remote.social", for: features), 14)
|
XCTAssertEqual(CharacterCounter.count(text: "hello @example@some.remote.social"), 14)
|
||||||
XCTAssertEqual(CharacterCounter.count(text: "hello @some_really_long_name@some-long.remote-instance.social", for: features), 28)
|
XCTAssertEqual(CharacterCounter.count(text: "hello @some_really_long_name@some-long.remote-instance.social"), 28)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -8,7 +8,6 @@
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import Pachyderm
|
@testable import Pachyderm
|
||||||
|
|
||||||
@MainActor
|
|
||||||
class NotificationGroupTests: XCTestCase {
|
class NotificationGroupTests: XCTestCase {
|
||||||
|
|
||||||
let decoder: JSONDecoder = {
|
let decoder: JSONDecoder = {
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
//
|
|
||||||
// StatusTests.swift
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Created by Shadowfacts on 5/8/23.
|
|
||||||
//
|
|
||||||
|
|
||||||
import XCTest
|
|
||||||
@testable import Pachyderm
|
|
||||||
|
|
||||||
final class StatusTests: XCTestCase {
|
|
||||||
|
|
||||||
func testDecode() {
|
|
||||||
let data = """
|
|
||||||
{
|
|
||||||
"id": "1",
|
|
||||||
"uri": "https://example.com/a/1",
|
|
||||||
"url": "",
|
|
||||||
"account": {
|
|
||||||
"id": "2",
|
|
||||||
"username": "a",
|
|
||||||
"acct": "a",
|
|
||||||
"display_name": "",
|
|
||||||
"locked": false,
|
|
||||||
"created_at": 0,
|
|
||||||
"followers_count": 0,
|
|
||||||
"following_count": 0,
|
|
||||||
"statuses_count": 0,
|
|
||||||
"note": "",
|
|
||||||
"url": "https://example.com/a"
|
|
||||||
},
|
|
||||||
"content": "",
|
|
||||||
"created_at": 0,
|
|
||||||
"emojis": [],
|
|
||||||
"reblogs_count": 0,
|
|
||||||
"favourites_count": 0,
|
|
||||||
"sensitive": false,
|
|
||||||
"spoiler_text": "",
|
|
||||||
"visibility": "public",
|
|
||||||
"media_attachments": [],
|
|
||||||
"mentions": [],
|
|
||||||
"tags": []
|
|
||||||
}
|
|
||||||
""".data(using: .utf8)!
|
|
||||||
do {
|
|
||||||
_ = try JSONDecoder().decode(Status.self, from: data)
|
|
||||||
} catch {
|
|
||||||
print(error)
|
|
||||||
XCTFail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -27,7 +27,7 @@ public struct AvatarImageView: View {
|
||||||
imageView
|
imageView
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: size, height: size)
|
.frame(width: size, height: size)
|
||||||
.clipShape(RoundedRectangle(cornerRadius: style.cornerRadiusFraction * size, style: .continuous))
|
.cornerRadius(style.cornerRadiusFraction * size)
|
||||||
.task { @MainActor in
|
.task { @MainActor in
|
||||||
image = nil
|
image = nil
|
||||||
if let url {
|
if let url {
|
||||||
|
|
|
@ -2342,7 +2342,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 84;
|
CURRENT_PROJECT_VERSION = 83;
|
||||||
INFOPLIST_FILE = Tusker/Info.plist;
|
INFOPLIST_FILE = Tusker/Info.plist;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||||
|
@ -2408,7 +2408,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 84;
|
CURRENT_PROJECT_VERSION = 83;
|
||||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||||
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
||||||
|
@ -2434,7 +2434,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 84;
|
CURRENT_PROJECT_VERSION = 83;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
||||||
|
@ -2463,7 +2463,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 84;
|
CURRENT_PROJECT_VERSION = 83;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
||||||
|
@ -2492,7 +2492,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 84;
|
CURRENT_PROJECT_VERSION = 83;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
INFOPLIST_KEY_CFBundleDisplayName = ShareExtension;
|
||||||
|
@ -2647,7 +2647,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 84;
|
CURRENT_PROJECT_VERSION = 83;
|
||||||
INFOPLIST_FILE = Tusker/Info.plist;
|
INFOPLIST_FILE = Tusker/Info.plist;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||||
|
@ -2678,7 +2678,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 84;
|
CURRENT_PROJECT_VERSION = 83;
|
||||||
INFOPLIST_FILE = Tusker/Info.plist;
|
INFOPLIST_FILE = Tusker/Info.plist;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||||
|
@ -2784,7 +2784,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 84;
|
CURRENT_PROJECT_VERSION = 83;
|
||||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||||
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
||||||
|
@ -2810,7 +2810,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 84;
|
CURRENT_PROJECT_VERSION = 83;
|
||||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||||
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
BlueprintIdentifier = "D61099AA2144B0CC00432DC2"
|
BlueprintIdentifier = "D61099AA2144B0CC00432DC2"
|
||||||
BuildableName = "Pachyderm.framework"
|
BuildableName = "Pachyderm.framework"
|
||||||
BlueprintName = "Pachyderm"
|
BlueprintName = "Pachyderm"
|
||||||
ReferencedContainer = "container:../../Tusker.xcodeproj">
|
ReferencedContainer = "container:Tusker.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
</BuildActionEntries>
|
</BuildActionEntries>
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
BlueprintIdentifier = "PachydermTests"
|
BlueprintIdentifier = "PachydermTests"
|
||||||
BuildableName = "PachydermTests"
|
BuildableName = "PachydermTests"
|
||||||
BlueprintName = "PachydermTests"
|
BlueprintName = "PachydermTests"
|
||||||
ReferencedContainer = "container:">
|
ReferencedContainer = "container:Pachyderm">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</TestableReference>
|
</TestableReference>
|
||||||
</Testables>
|
</Testables>
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
BlueprintIdentifier = "D61099AA2144B0CC00432DC2"
|
BlueprintIdentifier = "D61099AA2144B0CC00432DC2"
|
||||||
BuildableName = "Pachyderm.framework"
|
BuildableName = "Pachyderm.framework"
|
||||||
BlueprintName = "Pachyderm"
|
BlueprintName = "Pachyderm"
|
||||||
ReferencedContainer = "container:../../Tusker.xcodeproj">
|
ReferencedContainer = "container:Tusker.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
BlueprintIdentifier = "D61099AA2144B0CC00432DC2"
|
BlueprintIdentifier = "D61099AA2144B0CC00432DC2"
|
||||||
BuildableName = "Pachyderm.framework"
|
BuildableName = "Pachyderm.framework"
|
||||||
BlueprintName = "Pachyderm"
|
BlueprintName = "Pachyderm"
|
||||||
ReferencedContainer = "container:../../Tusker.xcodeproj">
|
ReferencedContainer = "container:Tusker.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
</ProfileAction>
|
</ProfileAction>
|
|
@ -27,9 +27,7 @@ class FeaturedProfileCollectionViewCell: UICollectionViewCell {
|
||||||
super.awakeFromNib()
|
super.awakeFromNib()
|
||||||
|
|
||||||
avatarContainerView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarContainerView)
|
avatarContainerView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarContainerView)
|
||||||
avatarContainerView.layer.cornerCurve = .continuous
|
|
||||||
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarImageView)
|
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarImageView)
|
||||||
avatarImageView.layer.cornerCurve = .continuous
|
|
||||||
|
|
||||||
displayNameLabel.font = UIFontMetrics(forTextStyle: .title1).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold))
|
displayNameLabel.font = UIFontMetrics(forTextStyle: .title1).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold))
|
||||||
displayNameLabel.adjustsFontForContentSizeCategory = true
|
displayNameLabel.adjustsFontForContentSizeCategory = true
|
||||||
|
@ -43,7 +41,6 @@ class FeaturedProfileCollectionViewCell: UICollectionViewCell {
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
clippingView.backgroundColor = .appBackground
|
clippingView.backgroundColor = .appBackground
|
||||||
clippingView.layer.cornerRadius = 5
|
clippingView.layer.cornerRadius = 5
|
||||||
clippingView.layer.cornerCurve = .continuous
|
|
||||||
clippingView.layer.borderWidth = 1
|
clippingView.layer.borderWidth = 1
|
||||||
clippingView.layer.masksToBounds = true
|
clippingView.layer.masksToBounds = true
|
||||||
layer.shadowOpacity = 0.2
|
layer.shadowOpacity = 0.2
|
||||||
|
|
|
@ -36,17 +36,14 @@ class SuggestedProfileCardCollectionViewCell: UICollectionViewCell {
|
||||||
layer.shadowOffset = .zero
|
layer.shadowOffset = .zero
|
||||||
layer.masksToBounds = false
|
layer.masksToBounds = false
|
||||||
contentView.layer.cornerRadius = 12.5
|
contentView.layer.cornerRadius = 12.5
|
||||||
contentView.layer.cornerCurve = .continuous
|
|
||||||
contentView.backgroundColor = .appGroupedCellBackground
|
contentView.backgroundColor = .appGroupedCellBackground
|
||||||
updateLayerColors()
|
updateLayerColors()
|
||||||
|
|
||||||
headerImageView.cache = .headers
|
headerImageView.cache = .headers
|
||||||
|
|
||||||
avatarContainerView.layer.masksToBounds = true
|
avatarContainerView.layer.masksToBounds = true
|
||||||
avatarContainerView.layer.cornerCurve = .continuous
|
|
||||||
avatarImageView.cache = .avatars
|
avatarImageView.cache = .avatars
|
||||||
avatarImageView.layer.masksToBounds = true
|
avatarImageView.layer.masksToBounds = true
|
||||||
avatarImageView.layer.cornerCurve = .continuous
|
|
||||||
|
|
||||||
displayNameLabel.font = UIFontMetrics(forTextStyle: .title1).scaledFont(for: .systemFont(ofSize: 24, weight: .semibold))
|
displayNameLabel.font = UIFontMetrics(forTextStyle: .title1).scaledFont(for: .systemFont(ofSize: 24, weight: .semibold))
|
||||||
displayNameLabel.adjustsFontForContentSizeCategory = true
|
displayNameLabel.adjustsFontForContentSizeCategory = true
|
||||||
|
|
|
@ -57,7 +57,6 @@ class TrendingLinkCardCollectionViewCell: UICollectionViewCell {
|
||||||
layer.shadowOffset = .zero
|
layer.shadowOffset = .zero
|
||||||
layer.masksToBounds = false
|
layer.masksToBounds = false
|
||||||
contentView.layer.cornerRadius = 12.5
|
contentView.layer.cornerRadius = 12.5
|
||||||
contentView.layer.cornerCurve = .continuous
|
|
||||||
contentView.backgroundColor = .appGroupedCellBackground
|
contentView.backgroundColor = .appGroupedCellBackground
|
||||||
updateLayerColors()
|
updateLayerColors()
|
||||||
|
|
||||||
|
|
|
@ -86,9 +86,7 @@ class FastSwitchingAccountView: UIView {
|
||||||
avatarImageView.translatesAutoresizingMaskIntoConstraints = false
|
avatarImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
avatarImageView.layer.masksToBounds = true
|
avatarImageView.layer.masksToBounds = true
|
||||||
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 40
|
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 40
|
||||||
avatarImageView.layer.cornerCurve = .continuous
|
|
||||||
avatarImageView.image = UIImage(systemName: Preferences.shared.avatarStyle == .circle ? "person.crop.circle" : "person.crop.square")
|
avatarImageView.image = UIImage(systemName: Preferences.shared.avatarStyle == .circle ? "person.crop.circle" : "person.crop.square")
|
||||||
// todo: this should really be fit, but somehow the image view ends up being 37pt tall?
|
|
||||||
avatarImageView.contentMode = .scaleAspectFill
|
avatarImageView.contentMode = .scaleAspectFill
|
||||||
addSubview(avatarImageView)
|
addSubview(avatarImageView)
|
||||||
|
|
||||||
|
|
|
@ -225,7 +225,6 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
// so that explore items aren't shown multiple times.
|
// so that explore items aren't shown multiple times.
|
||||||
|
|
||||||
let exploreNav = tabBarViewController.viewController(for: .explore) as! UINavigationController
|
let exploreNav = tabBarViewController.viewController(for: .explore) as! UINavigationController
|
||||||
// make sure there's a root ExploreViewController
|
|
||||||
let explore: ExploreViewController
|
let explore: ExploreViewController
|
||||||
if let existing = exploreNav.viewControllers.first as? ExploreViewController {
|
if let existing = exploreNav.viewControllers.first as? ExploreViewController {
|
||||||
explore = existing
|
explore = existing
|
||||||
|
@ -239,23 +238,14 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
explore.loadViewIfNeeded()
|
explore.loadViewIfNeeded()
|
||||||
|
|
||||||
let search = secondaryNavController.viewControllers.first as! InlineTrendsViewController
|
let search = secondaryNavController.viewControllers.first as! InlineTrendsViewController
|
||||||
if search.searchController.isActive {
|
// Copy the search query from the search VC to the Explore VC's search controller.
|
||||||
// Copy the search query from the search VC to the Explore VC's search controller.
|
let query = search.searchController.searchBar.text ?? ""
|
||||||
let query = search.searchController.searchBar.text ?? ""
|
explore.searchController.searchBar.text = query
|
||||||
explore.searchController.searchBar.text = query
|
// Instruct the explore controller to show its search controller immediately upon its first appearance.
|
||||||
// Instruct the explore controller to show its search controller immediately upon its first appearance.
|
// explore.searchController.isActive can't be set directly, see FB7814561
|
||||||
// explore.searchController.isActive can't be set directly, see FB7814561
|
explore.searchControllerStatusOnAppearance = !query.isEmpty
|
||||||
explore.searchControllerStatusOnAppearance = !query.isEmpty
|
// Copy the results from the search VC's results controller to avoid the delay introduced by an extra network request
|
||||||
// Copy the results from the search VC's results controller to avoid the delay introduced by an extra network request
|
explore.resultsController.loadResults(from: search.resultsController)
|
||||||
explore.resultsController.loadResults(from: search.resultsController)
|
|
||||||
} else {
|
|
||||||
// if there is more than just the InlineTrendsVC, and the search VC is not active,
|
|
||||||
// then the user selected something from the trends screen
|
|
||||||
if secondaryNavController.viewControllers.count >= 2 {
|
|
||||||
// make sure there's a corresponding trends VC in the collapsed nav that they can go back to
|
|
||||||
exploreNav.pushViewController(TrendsViewController(mastodonController: mastodonController), animated: false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transfer the navigation stack, dropping the search VC, to keep anything the user has opened
|
// Transfer the navigation stack, dropping the search VC, to keep anything the user has opened
|
||||||
transferNavigationStack(from: .explore, to: exploreNav, dropFirst: true, append: true)
|
transferNavigationStack(from: .explore, to: exploreNav, dropFirst: true, append: true)
|
||||||
|
@ -339,16 +329,14 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
exploreItem = .favorites
|
exploreItem = .favorites
|
||||||
case let listVC as ListTimelineViewController:
|
case let listVC as ListTimelineViewController:
|
||||||
exploreItem = .list(listVC.list)
|
exploreItem = .list(listVC.list)
|
||||||
case let hashtagVC as HashtagTimelineViewController where hashtagVC.isHashtagSaved:
|
case let hashtagVC as HashtagTimelineViewController:
|
||||||
exploreItem = .savedHashtag(hashtagVC.hashtag)
|
exploreItem = .savedHashtag(hashtagVC.hashtag)
|
||||||
case let instanceVC as InstanceTimelineViewController:
|
case let instanceVC as InstanceTimelineViewController:
|
||||||
exploreItem = .savedInstance(instanceVC.instanceURL)
|
exploreItem = .savedInstance(instanceVC.instanceURL)
|
||||||
case is TrendsViewController:
|
case is TrendingStatusesViewController, is TrendingHashtagsViewController, is TrendingLinksViewController:
|
||||||
exploreItem = .explore
|
exploreItem = .explore
|
||||||
// skip transferring the ExploreViewController and TrendsViewController
|
// these three VCs are part of the root SearchViewController, so we don't need to transfer them
|
||||||
skipFirst = 2
|
skipFirst = 2
|
||||||
// prepend the InlineTrendsViewController
|
|
||||||
toPrepend = getOrCreateNavigationStack(item: .explore).first!
|
|
||||||
default:
|
default:
|
||||||
// transfer the navigation stack prepending, the existing explore VC
|
// transfer the navigation stack prepending, the existing explore VC
|
||||||
// if there was other stuff on the explore stack, it will get discarded
|
// if there was other stuff on the explore stack, it will get discarded
|
||||||
|
|
|
@ -149,7 +149,6 @@ class ActionNotificationGroupCollectionViewCell: UICollectionViewListCell {
|
||||||
imageView.contentMode = .scaleAspectFit
|
imageView.contentMode = .scaleAspectFit
|
||||||
imageView.layer.masksToBounds = true
|
imageView.layer.masksToBounds = true
|
||||||
imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30
|
imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30
|
||||||
imageView.layer.cornerCurve = .continuous
|
|
||||||
avatarStack.addArrangedSubview(imageView)
|
avatarStack.addArrangedSubview(imageView)
|
||||||
imageView.update(for: avatarURL)
|
imageView.update(for: avatarURL)
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,6 @@ class FollowNotificationGroupCollectionViewCell: UICollectionViewListCell {
|
||||||
let imageView = CachedImageView(cache: .avatars)
|
let imageView = CachedImageView(cache: .avatars)
|
||||||
imageView.layer.masksToBounds = true
|
imageView.layer.masksToBounds = true
|
||||||
imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30
|
imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30
|
||||||
imageView.layer.cornerCurve = .continuous
|
|
||||||
imageView.update(for: avatarURL)
|
imageView.update(for: avatarURL)
|
||||||
avatarStack.addArrangedSubview(imageView)
|
avatarStack.addArrangedSubview(imageView)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ class FollowRequestNotificationCollectionViewCell: UICollectionViewListCell {
|
||||||
|
|
||||||
private let avatarImageView = CachedImageView(cache: .avatars).configure {
|
private let avatarImageView = CachedImageView(cache: .avatars).configure {
|
||||||
$0.layer.masksToBounds = true
|
$0.layer.masksToBounds = true
|
||||||
$0.layer.cornerCurve = .continuous
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
$0.widthAnchor.constraint(equalTo: $0.heightAnchor),
|
$0.widthAnchor.constraint(equalTo: $0.heightAnchor),
|
||||||
])
|
])
|
||||||
|
|
|
@ -355,24 +355,8 @@ extension NotificationsCollectionViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlePrependItems(_ timelineItems: [NotificationGroup]) async {
|
func handlePrependItems(_ timelineItems: [NotificationGroup]) async {
|
||||||
let topItem = dataSource.snapshot().itemIdentifiers(inSection: .notifications).first
|
|
||||||
|
|
||||||
// we always replace all, because new items are merged with existing ones
|
// we always replace all, because new items are merged with existing ones
|
||||||
await handleReplaceAllItems(timelineItems)
|
await handleReplaceAllItems(timelineItems)
|
||||||
|
|
||||||
// preserve the scroll position
|
|
||||||
// todo: this won't work for cmd+r when not at top
|
|
||||||
if let topID = topItem?.group?.notifications.first?.id {
|
|
||||||
// the exact item may have changed, due to merging
|
|
||||||
let newTopGroup = timelineItems.first {
|
|
||||||
$0.notifications.contains {
|
|
||||||
$0.id == topID
|
|
||||||
}
|
|
||||||
}!
|
|
||||||
if let newTopIndexPath = dataSource.indexPath(for: .group(newTopGroup)) {
|
|
||||||
collectionView.scrollToItem(at: newTopIndexPath, at: .top, animated: false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadOlder() async throws -> [NotificationGroup] {
|
func loadOlder() async throws -> [NotificationGroup] {
|
||||||
|
|
|
@ -15,7 +15,7 @@ class HashtagTimelineViewController: TimelineViewController {
|
||||||
|
|
||||||
var toggleSaveButton: UIBarButtonItem!
|
var toggleSaveButton: UIBarButtonItem!
|
||||||
|
|
||||||
var isHashtagSaved: Bool {
|
private var isHashtagSaved: Bool {
|
||||||
let req = SavedHashtag.fetchRequest(name: hashtag.name, account: mastodonController.accountInfo!)
|
let req = SavedHashtag.fetchRequest(name: hashtag.name, account: mastodonController.accountInfo!)
|
||||||
return mastodonController.persistentContainer.viewContext.objectExists(for: req)
|
return mastodonController.persistentContainer.viewContext.objectExists(for: req)
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,6 @@ extension TimelineLikeCollectionViewController {
|
||||||
}
|
}
|
||||||
await apply(snapshot, animatingDifferences: false)
|
await apply(snapshot, animatingDifferences: false)
|
||||||
|
|
||||||
// todo: this won't work for cmd+r when not at top
|
|
||||||
if let first,
|
if let first,
|
||||||
let indexPath = dataSource.indexPath(for: first) {
|
let indexPath = dataSource.indexPath(for: first) {
|
||||||
// TODO: i can't tell if this actually works or not
|
// TODO: i can't tell if this actually works or not
|
||||||
|
|
|
@ -22,7 +22,6 @@ class AccountCollectionViewCell: UICollectionViewListCell {
|
||||||
|
|
||||||
private let avatarImageView = CachedImageView(cache: .avatars).configure {
|
private let avatarImageView = CachedImageView(cache: .avatars).configure {
|
||||||
$0.layer.masksToBounds = true
|
$0.layer.masksToBounds = true
|
||||||
$0.layer.cornerCurve = .continuous
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
$0.widthAnchor.constraint(equalToConstant: 50),
|
$0.widthAnchor.constraint(equalToConstant: 50),
|
||||||
$0.heightAnchor.constraint(equalToConstant: 50),
|
$0.heightAnchor.constraint(equalToConstant: 50),
|
||||||
|
|
|
@ -28,7 +28,6 @@ class AccountTableViewCell: UITableViewCell {
|
||||||
super.awakeFromNib()
|
super.awakeFromNib()
|
||||||
|
|
||||||
avatarImageView.layer.masksToBounds = true
|
avatarImageView.layer.masksToBounds = true
|
||||||
avatarImageView.layer.cornerCurve = .continuous
|
|
||||||
|
|
||||||
usernameLabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .light))
|
usernameLabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .light))
|
||||||
usernameLabel.adjustsFontForContentSizeCategory = true
|
usernameLabel.adjustsFontForContentSizeCategory = true
|
||||||
|
|
|
@ -22,7 +22,6 @@ class LargeAccountDetailView: UIView {
|
||||||
|
|
||||||
avatarImageView.translatesAutoresizingMaskIntoConstraints = false
|
avatarImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
avatarImageView.layer.masksToBounds = true
|
avatarImageView.layer.masksToBounds = true
|
||||||
avatarImageView.layer.cornerCurve = .continuous
|
|
||||||
addSubview(avatarImageView)
|
addSubview(avatarImageView)
|
||||||
|
|
||||||
displayNameLabel.translatesAutoresizingMaskIntoConstraints = false
|
displayNameLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
|
@ -368,13 +368,11 @@ class AttachmentView: GIFImageView {
|
||||||
let first = stack.arrangedSubviews.first!
|
let first = stack.arrangedSubviews.first!
|
||||||
first.layer.masksToBounds = true
|
first.layer.masksToBounds = true
|
||||||
first.layer.cornerRadius = 4
|
first.layer.cornerRadius = 4
|
||||||
first.layer.cornerCurve = .continuous
|
|
||||||
if stack.arrangedSubviews.count > 1 {
|
if stack.arrangedSubviews.count > 1 {
|
||||||
first.layer.maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner]
|
first.layer.maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner]
|
||||||
let last = stack.arrangedSubviews.last!
|
let last = stack.arrangedSubviews.last!
|
||||||
last.layer.masksToBounds = true
|
last.layer.masksToBounds = true
|
||||||
last.layer.cornerRadius = 4
|
last.layer.cornerRadius = 4
|
||||||
last.layer.cornerCurve = .continuous
|
|
||||||
last.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMaxXMaxYCorner]
|
last.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMaxXMaxYCorner]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,6 @@ class AttachmentsContainerView: UIView {
|
||||||
case 1:
|
case 1:
|
||||||
let attachmentView = createAttachmentView(index: 0, hSize: .full, vSize: .full)
|
let attachmentView = createAttachmentView(index: 0, hSize: .full, vSize: .full)
|
||||||
attachmentView.layer.cornerRadius = 5
|
attachmentView.layer.cornerRadius = 5
|
||||||
attachmentView.layer.cornerCurve = .continuous
|
|
||||||
attachmentView.layer.masksToBounds = true
|
attachmentView.layer.masksToBounds = true
|
||||||
fillView(attachmentView)
|
fillView(attachmentView)
|
||||||
sendSubviewToBack(attachmentView)
|
sendSubviewToBack(attachmentView)
|
||||||
|
@ -96,12 +95,10 @@ class AttachmentsContainerView: UIView {
|
||||||
case 2:
|
case 2:
|
||||||
let left = createAttachmentView(index: 0, hSize: .half, vSize: .full)
|
let left = createAttachmentView(index: 0, hSize: .half, vSize: .full)
|
||||||
left.layer.cornerRadius = 5
|
left.layer.cornerRadius = 5
|
||||||
left.layer.cornerCurve = .continuous
|
|
||||||
left.layer.maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner]
|
left.layer.maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner]
|
||||||
left.layer.masksToBounds = true
|
left.layer.masksToBounds = true
|
||||||
let right = createAttachmentView(index: 1, hSize: .half, vSize: .full)
|
let right = createAttachmentView(index: 1, hSize: .half, vSize: .full)
|
||||||
right.layer.cornerRadius = 5
|
right.layer.cornerRadius = 5
|
||||||
right.layer.cornerCurve = .continuous
|
|
||||||
right.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMaxXMaxYCorner]
|
right.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMaxXMaxYCorner]
|
||||||
right.layer.masksToBounds = true
|
right.layer.masksToBounds = true
|
||||||
let stack = createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
|
let stack = createAttachmentsStack(axis: .horizontal, arrangedSubviews: [
|
||||||
|
@ -119,17 +116,14 @@ class AttachmentsContainerView: UIView {
|
||||||
case 3:
|
case 3:
|
||||||
let left = createAttachmentView(index: 0, hSize: .half, vSize: .full)
|
let left = createAttachmentView(index: 0, hSize: .half, vSize: .full)
|
||||||
left.layer.cornerRadius = 5
|
left.layer.cornerRadius = 5
|
||||||
left.layer.cornerCurve = .continuous
|
|
||||||
left.layer.maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner]
|
left.layer.maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner]
|
||||||
left.layer.masksToBounds = true
|
left.layer.masksToBounds = true
|
||||||
let topRight = createAttachmentView(index: 1, hSize: .half, vSize: .half)
|
let topRight = createAttachmentView(index: 1, hSize: .half, vSize: .half)
|
||||||
topRight.layer.cornerRadius = 5
|
topRight.layer.cornerRadius = 5
|
||||||
topRight.layer.cornerCurve = .continuous
|
|
||||||
topRight.layer.maskedCorners = .layerMaxXMinYCorner
|
topRight.layer.maskedCorners = .layerMaxXMinYCorner
|
||||||
topRight.layer.masksToBounds = true
|
topRight.layer.masksToBounds = true
|
||||||
let bottomRight = createAttachmentView(index: 2, hSize: .half, vSize: .half)
|
let bottomRight = createAttachmentView(index: 2, hSize: .half, vSize: .half)
|
||||||
bottomRight.layer.cornerRadius = 5
|
bottomRight.layer.cornerRadius = 5
|
||||||
bottomRight.layer.cornerCurve = .continuous
|
|
||||||
bottomRight.layer.maskedCorners = .layerMaxXMaxYCorner
|
bottomRight.layer.maskedCorners = .layerMaxXMaxYCorner
|
||||||
bottomRight.layer.masksToBounds = true
|
bottomRight.layer.masksToBounds = true
|
||||||
let innerStack = createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
let innerStack = createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
||||||
|
@ -154,12 +148,10 @@ class AttachmentsContainerView: UIView {
|
||||||
case 4:
|
case 4:
|
||||||
let topLeft = createAttachmentView(index: 0, hSize: .half, vSize: .half)
|
let topLeft = createAttachmentView(index: 0, hSize: .half, vSize: .half)
|
||||||
topLeft.layer.cornerRadius = 5
|
topLeft.layer.cornerRadius = 5
|
||||||
topLeft.layer.cornerCurve = .continuous
|
|
||||||
topLeft.layer.maskedCorners = .layerMinXMinYCorner
|
topLeft.layer.maskedCorners = .layerMinXMinYCorner
|
||||||
topLeft.layer.masksToBounds = true
|
topLeft.layer.masksToBounds = true
|
||||||
let bottomLeft = createAttachmentView(index: 2, hSize: .half, vSize: .half)
|
let bottomLeft = createAttachmentView(index: 2, hSize: .half, vSize: .half)
|
||||||
bottomLeft.layer.cornerRadius = 5
|
bottomLeft.layer.cornerRadius = 5
|
||||||
bottomLeft.layer.cornerCurve = .continuous
|
|
||||||
bottomLeft.layer.maskedCorners = .layerMinXMaxYCorner
|
bottomLeft.layer.maskedCorners = .layerMinXMaxYCorner
|
||||||
bottomLeft.layer.masksToBounds = true
|
bottomLeft.layer.masksToBounds = true
|
||||||
let left = createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
let left = createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
||||||
|
@ -169,12 +161,10 @@ class AttachmentsContainerView: UIView {
|
||||||
attachmentStacks.add(left)
|
attachmentStacks.add(left)
|
||||||
let topRight = createAttachmentView(index: 1, hSize: .half, vSize: .half)
|
let topRight = createAttachmentView(index: 1, hSize: .half, vSize: .half)
|
||||||
topRight.layer.cornerRadius = 5
|
topRight.layer.cornerRadius = 5
|
||||||
topRight.layer.cornerCurve = .continuous
|
|
||||||
topRight.layer.maskedCorners = .layerMaxXMinYCorner
|
topRight.layer.maskedCorners = .layerMaxXMinYCorner
|
||||||
topRight.layer.masksToBounds = true
|
topRight.layer.masksToBounds = true
|
||||||
let bottomRight = createAttachmentView(index: 3, hSize: .half, vSize: .half)
|
let bottomRight = createAttachmentView(index: 3, hSize: .half, vSize: .half)
|
||||||
bottomRight.layer.cornerRadius = 5
|
bottomRight.layer.cornerRadius = 5
|
||||||
bottomRight.layer.cornerCurve = .continuous
|
|
||||||
bottomRight.layer.maskedCorners = .layerMaxXMaxYCorner
|
bottomRight.layer.maskedCorners = .layerMaxXMaxYCorner
|
||||||
bottomRight.layer.masksToBounds = true
|
bottomRight.layer.masksToBounds = true
|
||||||
let right = createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
let right = createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
||||||
|
@ -206,7 +196,6 @@ class AttachmentsContainerView: UIView {
|
||||||
moreView.isUserInteractionEnabled = true
|
moreView.isUserInteractionEnabled = true
|
||||||
moreView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(moreViewTapped)))
|
moreView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(moreViewTapped)))
|
||||||
moreView.layer.cornerRadius = 5
|
moreView.layer.cornerRadius = 5
|
||||||
moreView.layer.cornerCurve = .continuous
|
|
||||||
moreView.layer.maskedCorners = .layerMaxXMaxYCorner
|
moreView.layer.maskedCorners = .layerMaxXMaxYCorner
|
||||||
moreView.layer.masksToBounds = true
|
moreView.layer.masksToBounds = true
|
||||||
let moreLabel = UILabel()
|
let moreLabel = UILabel()
|
||||||
|
@ -219,7 +208,6 @@ class AttachmentsContainerView: UIView {
|
||||||
|
|
||||||
let topLeft = createAttachmentView(index: 0, hSize: .half, vSize: .half)
|
let topLeft = createAttachmentView(index: 0, hSize: .half, vSize: .half)
|
||||||
topLeft.layer.cornerRadius = 5
|
topLeft.layer.cornerRadius = 5
|
||||||
topLeft.layer.cornerCurve = .continuous
|
|
||||||
topLeft.layer.maskedCorners = .layerMinXMinYCorner
|
topLeft.layer.maskedCorners = .layerMinXMinYCorner
|
||||||
topLeft.layer.masksToBounds = true
|
topLeft.layer.masksToBounds = true
|
||||||
let bottomLeft = createAttachmentView(index: 2, hSize: .half, vSize: .half)
|
let bottomLeft = createAttachmentView(index: 2, hSize: .half, vSize: .half)
|
||||||
|
@ -233,7 +221,6 @@ class AttachmentsContainerView: UIView {
|
||||||
attachmentStacks.add(left)
|
attachmentStacks.add(left)
|
||||||
let topRight = createAttachmentView(index: 1, hSize: .half, vSize: .half)
|
let topRight = createAttachmentView(index: 1, hSize: .half, vSize: .half)
|
||||||
topRight.layer.cornerRadius = 5
|
topRight.layer.cornerRadius = 5
|
||||||
topRight.layer.cornerCurve = .continuous
|
|
||||||
topRight.layer.maskedCorners = .layerMaxXMinYCorner
|
topRight.layer.maskedCorners = .layerMaxXMinYCorner
|
||||||
topRight.layer.masksToBounds = true
|
topRight.layer.masksToBounds = true
|
||||||
let right = createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
let right = createAttachmentsStack(axis: .vertical, arrangedSubviews: [
|
||||||
|
|
|
@ -35,7 +35,6 @@ class PollOptionCheckboxView: UIView {
|
||||||
|
|
||||||
let size: CGFloat = 20
|
let size: CGFloat = 20
|
||||||
layer.cornerRadius = (multiple ? 0.1 : 0.5) * size
|
layer.cornerRadius = (multiple ? 0.1 : 0.5) * size
|
||||||
layer.cornerCurve = .continuous
|
|
||||||
layer.borderWidth = 2
|
layer.borderWidth = 2
|
||||||
|
|
||||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
|
@ -22,7 +22,6 @@ class PollOptionView: UIView {
|
||||||
|
|
||||||
let minHeight: CGFloat = 35
|
let minHeight: CGFloat = 35
|
||||||
layer.cornerRadius = 0.1 * minHeight
|
layer.cornerRadius = 0.1 * minHeight
|
||||||
layer.cornerCurve = .continuous
|
|
||||||
backgroundColor = unselectedBackgroundColor
|
backgroundColor = unselectedBackgroundColor
|
||||||
|
|
||||||
checkbox.translatesAutoresizingMaskIntoConstraints = false
|
checkbox.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
@ -67,7 +66,6 @@ class PollOptionView: UIView {
|
||||||
fillView.backgroundColor = .tintColor.withAlphaComponent(0.6)
|
fillView.backgroundColor = .tintColor.withAlphaComponent(0.6)
|
||||||
fillView.layer.zPosition = -1
|
fillView.layer.zPosition = -1
|
||||||
fillView.layer.cornerRadius = layer.cornerRadius
|
fillView.layer.cornerRadius = layer.cornerRadius
|
||||||
fillView.layer.cornerCurve = .continuous
|
|
||||||
addSubview(fillView)
|
addSubview(fillView)
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
|
|
|
@ -42,7 +42,6 @@ class ProfileHeaderMovedOverlayView: UIView {
|
||||||
avatarImageView = CachedImageView(cache: .avatars)
|
avatarImageView = CachedImageView(cache: .avatars)
|
||||||
avatarImageView.layer.masksToBounds = true
|
avatarImageView.layer.masksToBounds = true
|
||||||
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 50
|
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 50
|
||||||
avatarImageView.layer.cornerCurve = .continuous
|
|
||||||
avatarImageView.addInteraction(UIPointerInteraction(delegate: self))
|
avatarImageView.addInteraction(UIPointerInteraction(delegate: self))
|
||||||
avatarImageView.isUserInteractionEnabled = true
|
avatarImageView.isUserInteractionEnabled = true
|
||||||
|
|
||||||
|
|
|
@ -66,9 +66,7 @@ class ProfileHeaderView: UIView {
|
||||||
|
|
||||||
avatarContainerView.backgroundColor = .appBackground
|
avatarContainerView.backgroundColor = .appBackground
|
||||||
avatarContainerView.layer.masksToBounds = true
|
avatarContainerView.layer.masksToBounds = true
|
||||||
avatarContainerView.layer.cornerCurve = .continuous
|
|
||||||
avatarImageView.layer.masksToBounds = true
|
avatarImageView.layer.masksToBounds = true
|
||||||
avatarImageView.layer.cornerCurve = .continuous
|
|
||||||
avatarImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(avatarPressed)))
|
avatarImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(avatarPressed)))
|
||||||
avatarImageView.isUserInteractionEnabled = true
|
avatarImageView.isUserInteractionEnabled = true
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status
|
||||||
private static let avatarImageViewSize: CGFloat = 50
|
private static let avatarImageViewSize: CGFloat = 50
|
||||||
private(set) lazy var avatarImageView = CachedImageView(cache: .avatars).configure {
|
private(set) lazy var avatarImageView = CachedImageView(cache: .avatars).configure {
|
||||||
$0.layer.masksToBounds = true
|
$0.layer.masksToBounds = true
|
||||||
$0.layer.cornerCurve = .continuous
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
$0.heightAnchor.constraint(equalToConstant: ConversationMainStatusCollectionViewCell.avatarImageViewSize),
|
$0.heightAnchor.constraint(equalToConstant: ConversationMainStatusCollectionViewCell.avatarImageViewSize),
|
||||||
$0.widthAnchor.constraint(equalToConstant: ConversationMainStatusCollectionViewCell.avatarImageViewSize),
|
$0.widthAnchor.constraint(equalToConstant: ConversationMainStatusCollectionViewCell.avatarImageViewSize),
|
||||||
|
|
|
@ -102,7 +102,6 @@ class StatusCardView: UIView {
|
||||||
hStack.spacing = 4
|
hStack.spacing = 4
|
||||||
hStack.clipsToBounds = true
|
hStack.clipsToBounds = true
|
||||||
hStack.layer.borderWidth = 0.5
|
hStack.layer.borderWidth = 0.5
|
||||||
hStack.layer.cornerCurve = .continuous
|
|
||||||
hStack.backgroundColor = inactiveBackgroundColor
|
hStack.backgroundColor = inactiveBackgroundColor
|
||||||
updateBorderColor()
|
updateBorderColor()
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
|
||||||
$0.image = reblogIcon
|
$0.image = reblogIcon
|
||||||
$0.contentMode = .scaleAspectFit
|
$0.contentMode = .scaleAspectFit
|
||||||
$0.layer.masksToBounds = true
|
$0.layer.masksToBounds = true
|
||||||
$0.layer.cornerCurve = .continuous
|
|
||||||
$0.tintColor = .secondaryLabel
|
$0.tintColor = .secondaryLabel
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
// this needs to be lessThanOrEqualTo not just equalTo b/c otherwise intermediate layouts are broken
|
// this needs to be lessThanOrEqualTo not just equalTo b/c otherwise intermediate layouts are broken
|
||||||
|
@ -76,7 +75,6 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
|
||||||
private static let avatarImageViewSize: CGFloat = 50
|
private static let avatarImageViewSize: CGFloat = 50
|
||||||
private(set) lazy var avatarImageView = CachedImageView(cache: .avatars).configure {
|
private(set) lazy var avatarImageView = CachedImageView(cache: .avatars).configure {
|
||||||
$0.layer.masksToBounds = true
|
$0.layer.masksToBounds = true
|
||||||
$0.layer.cornerCurve = .continuous
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
$0.heightAnchor.constraint(equalToConstant: TimelineStatusCollectionViewCell.avatarImageViewSize),
|
$0.heightAnchor.constraint(equalToConstant: TimelineStatusCollectionViewCell.avatarImageViewSize),
|
||||||
$0.widthAnchor.constraint(equalToConstant: TimelineStatusCollectionViewCell.avatarImageViewSize),
|
$0.widthAnchor.constraint(equalToConstant: TimelineStatusCollectionViewCell.avatarImageViewSize),
|
||||||
|
|
Loading…
Reference in New Issue