Compare commits
No commits in common. "566df3e285bb48437e971aa941876bd5c447aa9c" and "ac0dedfd3d6c6b6414be35204d7246b4e6f9ecc9" have entirely different histories.
566df3e285
...
ac0dedfd3d
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,16 +1,5 @@
|
|||
# Changelog
|
||||
|
||||
## 2023.1 (62)
|
||||
Features/Improvements:
|
||||
- Add New List action in Add to List menu
|
||||
|
||||
Bugfixes:
|
||||
- Fix crash when retrying follow hashtag
|
||||
- Fix separators on timeline not being properly inset
|
||||
- Fix various elements not adjusting to the accent color preference
|
||||
- Prevent all pinned timelines from being removed, which would previously crash
|
||||
- Fix crash when handling search activity
|
||||
|
||||
## 2023.1 (61)
|
||||
Features/Improvements:
|
||||
- Add report UI
|
||||
|
|
|
@ -2314,7 +2314,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 61;
|
||||
INFOPLIST_FILE = Tusker/Info.plist;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
|
@ -2382,7 +2382,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 61;
|
||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
||||
|
@ -2533,7 +2533,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 61;
|
||||
INFOPLIST_FILE = Tusker/Info.plist;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
|
@ -2562,7 +2562,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 61;
|
||||
INFOPLIST_FILE = Tusker/Info.plist;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
|
@ -2672,7 +2672,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 61;
|
||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
||||
|
@ -2698,7 +2698,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 62;
|
||||
CURRENT_PROJECT_VERSION = 61;
|
||||
INFOPLIST_FILE = OpenInTusker/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.1;
|
||||
"IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.3;
|
||||
|
|
|
@ -37,7 +37,7 @@ class ToggleFollowHashtagService {
|
|||
config.systemImageName = "checkmark"
|
||||
config.dismissAutomaticallyAfter = 2
|
||||
} catch {
|
||||
config = ToastConfiguration(from: error, with: "Error Unfollowing Hashtag", in: presenter) { toast in
|
||||
config = ToastConfiguration(from: error, with: "Error Unfollowing Hashtag", in: presenter) { [unowned self] toast in
|
||||
toast.dismissToast(animated: true)
|
||||
await self.toggleFollow()
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class ToggleFollowHashtagService {
|
|||
config.systemImageName = "checkmark"
|
||||
config.dismissAutomaticallyAfter = 2
|
||||
} catch {
|
||||
config = ToastConfiguration(from: error, with: "Error Following Hashtag", in: presenter) { toast in
|
||||
config = ToastConfiguration(from: error, with: "Error Following Hashtag", in: presenter) { [unowned self] toast in
|
||||
toast.dismissToast(animated: true)
|
||||
await self.toggleFollow()
|
||||
}
|
||||
|
|
|
@ -39,9 +39,7 @@ class OpenInSafariActivity: UIActivity {
|
|||
static func completionHandler(navigator: TuskerNavigationDelegate, url: URL) -> UIActivityViewController.CompletionWithItemsHandler {
|
||||
return { (activityType, _, _, _) in
|
||||
if activityType == .openInSafari {
|
||||
let vc = SFSafariViewController(url: url)
|
||||
vc.preferredControlTintColor = Preferences.shared.accentColor.color
|
||||
navigator.show(vc)
|
||||
navigator.show(SFSafariViewController(url: url))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
|
@ -22,10 +22,10 @@
|
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="a8U-KI-8PM">
|
||||
<rect key="frame" x="0.0" y="48" width="414" height="814"/>
|
||||
<rect key="frame" x="0.0" y="44" width="414" height="818"/>
|
||||
<subviews>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" verticalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="uQy-Yw-Dba">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="718"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="722"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" verticalHuggingPriority="249" scrollEnabled="NO" editable="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="hxN-7J-Usc">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="166.5"/>
|
||||
|
@ -46,12 +46,11 @@
|
|||
<viewLayoutGuide key="frameLayoutGuide" id="Rgd-t7-8QN"/>
|
||||
</scrollView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ofm-5l-nAp">
|
||||
<rect key="frame" x="52" y="726" width="310.5" height="50"/>
|
||||
<color key="backgroundColor" systemColor="tintColor"/>
|
||||
<rect key="frame" x="52" y="730" width="310.5" height="50"/>
|
||||
<color key="backgroundColor" systemColor="systemBlueColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="jHf-W0-qQn"/>
|
||||
</constraints>
|
||||
<color key="tintColor" systemColor="tintColor"/>
|
||||
<state key="normal" title="Send Report">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
|
@ -63,7 +62,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="JiJ-Ng-jOz">
|
||||
<rect key="frame" x="168.5" y="784" width="77" height="30"/>
|
||||
<rect key="frame" x="168.5" y="788" width="77" height="30"/>
|
||||
<state key="normal" title="Don't Send"/>
|
||||
<connections>
|
||||
<action selector="cancelPressed:" destination="-1" eventType="touchUpInside" id="o4R-0Q-STS"/>
|
||||
|
@ -88,12 +87,12 @@
|
|||
</objects>
|
||||
<resources>
|
||||
<systemColor name="labelColor">
|
||||
<color red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="tintColor">
|
||||
<systemColor name="systemBlueColor">
|
||||
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
|
|
|
@ -49,9 +49,9 @@ struct PinnedTimelinesView: View {
|
|||
.onMove { indices, newOffset in
|
||||
pinnedTimelines.move(fromOffsets: indices, toOffset: newOffset)
|
||||
}
|
||||
.onDelete(perform: pinnedTimelines.count == 1 ? nil : { indices in
|
||||
.onDelete { indices in
|
||||
pinnedTimelines.remove(atOffsets: indices)
|
||||
})
|
||||
}
|
||||
|
||||
Menu {
|
||||
ForEach([Timeline.home, .public(local: true), .public(local: false)], id: \.id) { timeline in
|
||||
|
|
|
@ -75,9 +75,7 @@ class TrendingLinksViewController: EnhancedTableViewController {
|
|||
return nil
|
||||
}
|
||||
return UIContextMenuConfiguration(identifier: nil) {
|
||||
let vc = SFSafariViewController(url: url)
|
||||
vc.preferredControlTintColor = Preferences.shared.accentColor.color
|
||||
return vc
|
||||
return SFSafariViewController(url: url)
|
||||
} actionProvider: { _ in
|
||||
return UIMenu(children: self.actionsForTrendingLink(card: item.card))
|
||||
}
|
||||
|
|
|
@ -60,11 +60,7 @@ class TrendingStatusesViewController: UIViewController {
|
|||
}
|
||||
return config
|
||||
}
|
||||
let layout = UICollectionViewCompositionalLayout { sectionIndex, environment in
|
||||
let section = NSCollectionLayoutSection.list(using: config, layoutEnvironment: environment)
|
||||
section.contentInsetsReference = .readableContent
|
||||
return section
|
||||
}
|
||||
let layout = UICollectionViewCompositionalLayout.list(using: config)
|
||||
view = UICollectionView(frame: .zero, collectionViewLayout: layout)
|
||||
collectionView.delegate = self
|
||||
collectionView.dragDelegate = self
|
||||
|
|
|
@ -10,25 +10,19 @@ import UIKit
|
|||
|
||||
class FastSwitchingAccountView: UIView {
|
||||
|
||||
private lazy var selectedColor = UIColor { [unowned self] (traits) in
|
||||
var hue: CGFloat = 0
|
||||
var saturation: CGFloat = 0
|
||||
var brightness: CGFloat = 0
|
||||
var alpha: CGFloat = 0
|
||||
self.tintColor.resolvedColor(with: traits).getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
|
||||
brightness = min(1, brightness + 0.4)
|
||||
saturation = max(0, saturation - 0.3)
|
||||
return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
|
||||
private static let selectedColor = UIColor { (traits) in
|
||||
if traits.userInterfaceStyle == .dark {
|
||||
return UIColor(hue: 211 / 360, saturation: 85 / 100, brightness: 100 / 100, alpha: 1)
|
||||
} else {
|
||||
return UIColor(hue: 211 / 360, saturation: 70 / 100, brightness: 100 / 100, alpha: 1)
|
||||
}
|
||||
}
|
||||
private static let currentColor = UIColor { (traits) in
|
||||
if traits.userInterfaceStyle == .dark {
|
||||
return UIColor(hue: 211 / 360, saturation: 85 / 100, brightness: 85 / 100, alpha: 1)
|
||||
} else {
|
||||
return UIColor(hue: 211 / 360, saturation: 50 / 100, brightness: 100 / 100, alpha: 1)
|
||||
}
|
||||
private lazy var currentColor = UIColor { [unowned self] (traits) in
|
||||
var hue: CGFloat = 0
|
||||
var saturation: CGFloat = 0
|
||||
var brightness: CGFloat = 0
|
||||
var alpha: CGFloat = 0
|
||||
self.tintColor.resolvedColor(with: traits).getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
|
||||
brightness = min(1, brightness + 0.3)
|
||||
saturation = max(0, saturation - 0.2)
|
||||
return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
|
||||
}
|
||||
var isSelected = false {
|
||||
didSet {
|
||||
|
@ -145,9 +139,9 @@ class FastSwitchingAccountView: UIView {
|
|||
private func updateLabelColors() {
|
||||
let color: UIColor
|
||||
if isSelected {
|
||||
color = selectedColor
|
||||
color = FastSwitchingAccountView.selectedColor
|
||||
} else if isCurrent {
|
||||
color = currentColor
|
||||
color = FastSwitchingAccountView.currentColor
|
||||
} else {
|
||||
color = .white
|
||||
}
|
||||
|
|
|
@ -80,15 +80,7 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
|
|||
}
|
||||
return config
|
||||
}
|
||||
let layout = UICollectionViewCompositionalLayout { [unowned self] sectionIndex, environment in
|
||||
if case .header = dataSource.sectionIdentifier(for: sectionIndex) {
|
||||
return .list(using: .init(appearance: .plain), layoutEnvironment: environment)
|
||||
} else {
|
||||
let section = NSCollectionLayoutSection.list(using: config, layoutEnvironment: environment)
|
||||
section.contentInsetsReference = .readableContent
|
||||
return section
|
||||
}
|
||||
}
|
||||
let layout = UICollectionViewCompositionalLayout.list(using: config)
|
||||
view = UICollectionView(frame: .zero, collectionViewLayout: layout)
|
||||
collectionView.delegate = self
|
||||
collectionView.dragDelegate = self
|
||||
|
|
|
@ -278,9 +278,7 @@ extension SearchViewController: UICollectionViewDelegate {
|
|||
return nil
|
||||
}
|
||||
return UIContextMenuConfiguration {
|
||||
let vc = SFSafariViewController(url: url)
|
||||
vc.preferredControlTintColor = Preferences.shared.accentColor.color
|
||||
return vc
|
||||
SFSafariViewController(url: url)
|
||||
} actionProvider: { _ in
|
||||
UIMenu(children: self.actionsForTrendingLink(card: card))
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
import UIKit
|
||||
import Pachyderm
|
||||
import Combine
|
||||
import Sentry
|
||||
|
||||
class TimelineViewController: UIViewController, TimelineLikeCollectionViewController, CollectionViewController, RefreshableViewController {
|
||||
let timeline: Timeline
|
||||
|
@ -87,12 +86,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
|||
}
|
||||
return config
|
||||
}
|
||||
// just setting layout.configuration.contentInsetsReference doesn't work with UICollectionViewCompositionalLayout.list
|
||||
let layout = UICollectionViewCompositionalLayout { sectionIndex, environment in
|
||||
let section = NSCollectionLayoutSection.list(using: config, layoutEnvironment: environment)
|
||||
section.contentInsetsReference = .readableContent
|
||||
return section
|
||||
}
|
||||
let layout = UICollectionViewCompositionalLayout.list(using: config)
|
||||
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
|
||||
collectionView.delegate = self
|
||||
collectionView.dragDelegate = self
|
||||
|
@ -341,7 +335,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
|||
}
|
||||
loadViewIfNeeded()
|
||||
var loaded = false
|
||||
await controller.restoreInitial { @MainActor in
|
||||
await controller.restoreInitial {
|
||||
let hasStatusesToRestore = await loadStatusesToRestore(position: position)
|
||||
if hasStatusesToRestore {
|
||||
applyItemsToRestore(position: position)
|
||||
|
@ -357,45 +351,26 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
|||
guard !unloaded.isEmpty else {
|
||||
return true
|
||||
}
|
||||
let results = await withTaskGroup(of: (String, Result<Status, Swift.Error>).self) { group -> [(String, Result<Status, Swift.Error>)] in
|
||||
let statuses = await withTaskGroup(of: Status?.self) { group -> [Status] in
|
||||
for id in unloaded {
|
||||
group.addTask {
|
||||
do {
|
||||
let (status, _) = try await self.mastodonController.run(Client.getStatus(id: id))
|
||||
return (id, .success(status))
|
||||
return status
|
||||
} catch {
|
||||
return (id, .failure(error))
|
||||
print(error)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return await group.reduce(into: []) { partialResult, result in
|
||||
partialResult.append(result)
|
||||
return await group.reduce(into: []) { partialResult, status in
|
||||
if let status {
|
||||
partialResult.append(status)
|
||||
}
|
||||
}
|
||||
var statuses = [Status]()
|
||||
for (id, result) in results {
|
||||
switch result {
|
||||
case .success(let status):
|
||||
statuses.append(status)
|
||||
case .failure(let error):
|
||||
let crumb = Breadcrumb(level: .error, category: "TimelineViewController")
|
||||
crumb.message = "Error loading status"
|
||||
crumb.data = [
|
||||
"error": String(describing: error),
|
||||
"id": id
|
||||
]
|
||||
SentrySDK.addBreadcrumb(crumb: crumb)
|
||||
}
|
||||
}
|
||||
await mastodonController.persistentContainer.addAll(statuses: statuses, in: mastodonController.persistentContainer.viewContext)
|
||||
|
||||
let crumb = Breadcrumb(level: .info, category: "TimelineViewController")
|
||||
crumb.message = "Original position statusIDs"
|
||||
crumb.data = [
|
||||
"statusIDs": position.statusIDs,
|
||||
]
|
||||
SentrySDK.addBreadcrumb(crumb: crumb)
|
||||
|
||||
// update the timeline position in case some statuses couldn't be loaded
|
||||
if let center = position.centerStatusID {
|
||||
let nearestLoadedStatusToCenter = position.statusIDs[position.statusIDs.firstIndex(of: center)!...].first(where: { id in
|
||||
|
@ -408,17 +383,9 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
|||
!unloaded.contains(id) || statuses.contains(where: { $0.id == id })
|
||||
}
|
||||
|
||||
let crumb2 = Breadcrumb(level: .info, category: "TimelineViewController")
|
||||
crumb2.message = "Filtered position statusIDs"
|
||||
crumb2.data = [
|
||||
"statusIDs": position.statusIDs,
|
||||
]
|
||||
SentrySDK.addBreadcrumb(crumb: crumb2)
|
||||
|
||||
return !position.statusIDs.isEmpty
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func applyItemsToRestore(position: TimelinePosition) {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||
snapshot.appendSections([.statuses])
|
||||
|
@ -426,12 +393,6 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
|||
let centerStatusID = position.centerStatusID
|
||||
let items = position.statusIDs.map { Item.status(id: $0, collapseState: .unknown, filterState: .unknown) }
|
||||
snapshot.appendItems(items, toSection: .statuses)
|
||||
let crumb = Breadcrumb(level: .info, category: "TimelineViewController")
|
||||
crumb.message = "Restoring statuses"
|
||||
crumb.data = [
|
||||
"statusIDs": position.statusIDs
|
||||
]
|
||||
SentrySDK.addBreadcrumb(crumb: crumb)
|
||||
dataSource.apply(snapshot, animatingDifferences: false) {
|
||||
if let centerStatusID,
|
||||
let index = statusIDs.firstIndex(of: centerStatusID),
|
||||
|
@ -465,12 +426,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
|||
|
||||
private func filterResult(state: FilterState, statusID: String) -> (Filterer.Result, NSAttributedString?) {
|
||||
let status = {
|
||||
guard let status = self.mastodonController.persistentContainer.status(for: statusID) else {
|
||||
let crumb = Breadcrumb(level: .fatal, category: "TimelineViewController")
|
||||
crumb.message = "Looking up status \(statusID)"
|
||||
SentrySDK.addBreadcrumb(crumb: crumb)
|
||||
preconditionFailure("Missing status for filtering")
|
||||
}
|
||||
let status = self.mastodonController.persistentContainer.status(for: statusID)!
|
||||
// if the status is a reblog of another one, filter based on that one
|
||||
if let reblogged = status.reblog {
|
||||
return (reblogged, true)
|
||||
|
|
|
@ -70,8 +70,8 @@ extension MenuActionProvider {
|
|||
accountID != ownAccount.id {
|
||||
actionsSection.append(relationshipAction(fetchRelationship, accountID: accountID, mastodonController: mastodonController, builder: { [unowned self] in self.followAction(for: $0, mastodonController: $1) }))
|
||||
actionsSection.append(UIDeferredMenuElement.uncached({ elementHandler in
|
||||
var listActions = mastodonController.lists.map { list in
|
||||
UIAction(title: list.title, image: UIImage(systemName: "list.bullet")) { [unowned self] _ in
|
||||
let listActions = mastodonController.lists.map { list in
|
||||
UIAction(title: list.title, image: UIImage(systemName: "plus")) { [unowned self] _ in
|
||||
let req = List.add(list, accounts: [accountID])
|
||||
mastodonController.run(req) { response in
|
||||
if case .failure(let error) = response {
|
||||
|
@ -80,21 +80,6 @@ extension MenuActionProvider {
|
|||
}
|
||||
}
|
||||
}
|
||||
listActions.append(UIAction(title: "New List…", image: UIImage(systemName: "plus"), handler: { [unowned self] _ in
|
||||
Task { @MainActor in
|
||||
let service = CreateListService(mastodonController: mastodonController, present: { [unowned self] in
|
||||
self.navigationDelegate!.present($0, animated: true)
|
||||
}) { list in
|
||||
let req = List.add(list, accounts: [accountID])
|
||||
mastodonController.run(req) { response in
|
||||
if case .failure(let error) = response {
|
||||
self.handleError(error, title: "Error Adding to List")
|
||||
}
|
||||
}
|
||||
}
|
||||
service.run()
|
||||
}
|
||||
}))
|
||||
elementHandler([UIMenu(title: "Add to List", image: UIImage(systemName: "list.bullet"), children: listActions)])
|
||||
}))
|
||||
suppressSection.append(relationshipAction(fetchRelationship, accountID: accountID, mastodonController: mastodonController, builder: { [unowned self] in self.blockAction(for: $0, mastodonController: $1) }))
|
||||
|
|
|
@ -257,7 +257,6 @@ class UserActivityManager {
|
|||
if let navigationController = mainViewController.getTabController(tab: .explore) as? UINavigationController,
|
||||
let exploreController = navigationController.viewControllers.first as? ExploreViewController {
|
||||
navigationController.popToRootViewController(animated: false)
|
||||
exploreController.loadViewIfNeeded()
|
||||
exploreController.searchController.isActive = true
|
||||
exploreController.searchController.searchBar.becomeFirstResponder()
|
||||
}
|
||||
|
|
|
@ -50,9 +50,7 @@ extension TuskerNavigationDelegate {
|
|||
url.scheme == "https" || url.scheme == "http" {
|
||||
let config = SFSafariViewController.Configuration()
|
||||
config.entersReaderIfAvailable = Preferences.shared.inAppSafariAutomaticReaderMode
|
||||
let vc = SFSafariViewController(url: url, configuration: config)
|
||||
vc.preferredControlTintColor = Preferences.shared.accentColor.color
|
||||
present(vc, animated: true)
|
||||
present(SFSafariViewController(url: url, configuration: config), animated: true)
|
||||
} else if UIApplication.shared.canOpenURL(url) {
|
||||
UIApplication.shared.open(url, options: [:])
|
||||
} else {
|
||||
|
|
|
@ -185,9 +185,7 @@ class ContentTextView: LinkTextView, BaseEmojiLabel {
|
|||
} else if let tag = getHashtag(for: url, text: text) {
|
||||
return HashtagTimelineViewController(for: tag, mastodonController: mastodonController!)
|
||||
} else if url.scheme == "https" || url.scheme == "http" {
|
||||
let vc = SFSafariViewController(url: url)
|
||||
vc.preferredControlTintColor = Preferences.shared.accentColor.color
|
||||
return vc
|
||||
return SFSafariViewController(url: url)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ class PollOptionView: UIView {
|
|||
|
||||
let fillView = UIView()
|
||||
fillView.translatesAutoresizingMaskIntoConstraints = false
|
||||
fillView.backgroundColor = .tintColor.withAlphaComponent(0.6)
|
||||
fillView.backgroundColor = tintColor.withAlphaComponent(0.6)
|
||||
fillView.layer.zPosition = -1
|
||||
fillView.layer.cornerRadius = layer.cornerRadius
|
||||
addSubview(fillView)
|
||||
|
|
|
@ -294,7 +294,7 @@ class BaseStatusTableViewCell: UITableViewCell {
|
|||
} else {
|
||||
let view = UIView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.backgroundColor = .tintColor.withAlphaComponent(0.5)
|
||||
view.backgroundColor = tintColor.withAlphaComponent(0.5)
|
||||
view.layer.cornerRadius = 2.5
|
||||
view.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
|
||||
prevThreadLinkView = view
|
||||
|
@ -316,7 +316,7 @@ class BaseStatusTableViewCell: UITableViewCell {
|
|||
} else {
|
||||
let view = UIView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.backgroundColor = .tintColor.withAlphaComponent(0.5)
|
||||
view.backgroundColor = tintColor.withAlphaComponent(0.5)
|
||||
view.layer.cornerRadius = 2.5
|
||||
view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
||||
nextThreadLinkView = view
|
||||
|
|
|
@ -229,9 +229,7 @@ extension StatusCardView: UIContextMenuInteractionDelegate {
|
|||
guard let card = card else { return nil }
|
||||
|
||||
return UIContextMenuConfiguration(identifier: nil) {
|
||||
let vc = SFSafariViewController(url: URL(card.url)!)
|
||||
vc.preferredControlTintColor = Preferences.shared.accentColor.color
|
||||
return vc
|
||||
return SFSafariViewController(url: URL(card.url)!)
|
||||
} actionProvider: { (_) in
|
||||
let actions = self.actionProvider?.actionsForURL(URL(card.url)!, source: .view(self)) ?? []
|
||||
return UIMenu(title: "", image: nil, identifier: nil, options: [], children: actions)
|
||||
|
|
|
@ -71,15 +71,11 @@ extension ToastConfiguration {
|
|||
event.tags!["error_type"] = "invalid_response"
|
||||
case .invalidModel(let error):
|
||||
event.tags!["error_type"] = "invalid_model"
|
||||
event.extra = [
|
||||
"underlying_error": String(describing: error)
|
||||
]
|
||||
event.tags!["underlying_error"] = String(describing: error)
|
||||
case .mastodonError(let code, let error):
|
||||
event.tags!["error_type"] = "mastodon_error"
|
||||
event.tags!["response_code"] = "\(code)"
|
||||
event.extra = [
|
||||
"underlying_error": String(describing: error)
|
||||
]
|
||||
event.tags!["underlying_error"] = error
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue