Compare commits
5 Commits
176eb7c011
...
2e2279ba8c
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 2e2279ba8c | |
Shadowfacts | 60dadf599c | |
Shadowfacts | 90537f9d12 | |
Shadowfacts | 8b0c2f80b6 | |
Shadowfacts | 42423f36db |
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -1,5 +1,23 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2024.3 (129)
|
||||||
|
Bugfixes:
|
||||||
|
- Fix excessive network traffic on profile pages
|
||||||
|
- Fix attachment gallery controls visibility not being synced between pages
|
||||||
|
- Fix video attachments not restarting when play pressed while at ends
|
||||||
|
- Fix profile field text being misaligned
|
||||||
|
- Fix at sign in timeline statuses usernames sometimes clipping
|
||||||
|
- Fix add hashtag/instance to Pinned Timelines sheets dismissing immediately when opened
|
||||||
|
- Fix for display name being replaced with incorrect user in certain circumstances
|
||||||
|
- Fix profile moved overlay view appearing behind avatar/header
|
||||||
|
- Fix profile moved view accessibility with VoiceOver
|
||||||
|
- Fix mention/status push notifications not showing content warning
|
||||||
|
- Fix sensitive attachment thumbnails being shown in push notifications
|
||||||
|
- Fix Dynamic Type not applying to status content
|
||||||
|
- Fix expand all option in Conversation not transferring when opening ancestors
|
||||||
|
- Fix not being able to resolve remote Mastodon status links in Conversation screen
|
||||||
|
- Fix status indicator icons overlapping thread links when Dynamic Type is enabled
|
||||||
|
|
||||||
## 2024.3 (128)
|
## 2024.3 (128)
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
- Fix selecting poll option playing too much haptic feedback
|
- Fix selecting poll option playing too much haptic feedback
|
||||||
|
|
|
@ -3260,7 +3260,7 @@
|
||||||
repositoryURL = "https://git.shadowfacts.net/shadowfacts/HTMLStreamer.git";
|
repositoryURL = "https://git.shadowfacts.net/shadowfacts/HTMLStreamer.git";
|
||||||
requirement = {
|
requirement = {
|
||||||
kind = exactVersion;
|
kind = exactVersion;
|
||||||
version = 0.2.5;
|
version = 0.3.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
D63CC700290EC0B8000E19DE /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = {
|
D63CC700290EC0B8000E19DE /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = {
|
||||||
|
|
|
@ -25,8 +25,14 @@ class HTMLConverter {
|
||||||
|
|
||||||
private let converter: AttributedStringConverter<Callbacks>
|
private let converter: AttributedStringConverter<Callbacks>
|
||||||
|
|
||||||
init(font: UIFont, monospaceFont: UIFont, color: UIColor, paragraphStyle: NSParagraphStyle) {
|
init(font: UIFont, monospaceFont: UIFont, fontMetrics: UIFontMetrics, color: UIColor, paragraphStyle: NSParagraphStyle) {
|
||||||
let config = AttributedStringConverterConfiguration(font: font, monospaceFont: monospaceFont, color: color, paragraphStyle: paragraphStyle)
|
let config = AttributedStringConverterConfiguration(
|
||||||
|
font: font,
|
||||||
|
monospaceFont: monospaceFont,
|
||||||
|
fontMetrics: fontMetrics,
|
||||||
|
color: color,
|
||||||
|
paragraphStyle: paragraphStyle
|
||||||
|
)
|
||||||
self.converter = AttributedStringConverter(configuration: config)
|
self.converter = AttributedStringConverter(configuration: config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -364,7 +364,9 @@ extension ConversationCollectionViewController: UICollectionViewDelegate {
|
||||||
conv.showStatusesAutomatically = showStatusesAutomatically
|
conv.showStatusesAutomatically = showStatusesAutomatically
|
||||||
show(conv)
|
show(conv)
|
||||||
} else {
|
} else {
|
||||||
selected(status: id, state: state.copy())
|
let conv = ConversationViewController(for: id, state: state.copy(), mastodonController: mastodonController)
|
||||||
|
conv.showStatusesAutomatically = showStatusesAutomatically
|
||||||
|
show(conv)
|
||||||
}
|
}
|
||||||
case .expandThread(childThreads: let childThreads, inline: _):
|
case .expandThread(childThreads: let childThreads, inline: _):
|
||||||
let indexPathBeforeExpandThread = IndexPath(row: indexPath.row - 1, section: indexPath.section)
|
let indexPathBeforeExpandThread = IndexPath(row: indexPath.row - 1, section: indexPath.section)
|
||||||
|
|
|
@ -221,10 +221,16 @@ class ConversationViewController: UIViewController {
|
||||||
completionHandler(nil)
|
completionHandler(nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isLikelyMastodonRemoteStatus(url: url),
|
if isLikelyMastodonRemoteStatus(url: url) {
|
||||||
let (_, response) = try? await URLSession.appDefault.data(from: url, delegate: RedirectBlocker()),
|
var request = URLRequest(url: url)
|
||||||
let location = (response as? HTTPURLResponse)?.value(forHTTPHeaderField: "location") {
|
// Mastodon uses an intermediate redirect page for browsers which requires user input that we don't want.
|
||||||
effectiveURL = location
|
request.addValue("application/activity+json", forHTTPHeaderField: "accept")
|
||||||
|
if let (_, response) = try? await URLSession.appDefault.data(for: request, delegate: RedirectBlocker()),
|
||||||
|
let location = (response as? HTTPURLResponse)?.value(forHTTPHeaderField: "location") {
|
||||||
|
effectiveURL = location
|
||||||
|
} else {
|
||||||
|
effectiveURL = WebURL(url)!.serialized(excludingFragment: true)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
effectiveURL = WebURL(url)!.serialized(excludingFragment: true)
|
effectiveURL = WebURL(url)!.serialized(excludingFragment: true)
|
||||||
}
|
}
|
||||||
|
@ -232,9 +238,14 @@ class ConversationViewController: UIViewController {
|
||||||
let request = Client.search(query: effectiveURL, types: [.statuses], resolve: true)
|
let request = Client.search(query: effectiveURL, types: [.statuses], resolve: true)
|
||||||
do {
|
do {
|
||||||
let (results, _) = try await mastodonController.run(request)
|
let (results, _) = try await mastodonController.run(request)
|
||||||
guard let status = results.statuses.compactMap(\.value).first(where: { $0.url?.serialized() == effectiveURL }) else {
|
let statuses = results.statuses.compactMap(\.value)
|
||||||
|
// Don't try to exactly match effective URL because the URL form Mastodon
|
||||||
|
// uses for the ActivityPub redirect doesn't match what's returned by the API.
|
||||||
|
// Instead we just assume that, if only one status was returned, it worked.
|
||||||
|
guard statuses.count == 1 else {
|
||||||
throw UnableToResolveError()
|
throw UnableToResolveError()
|
||||||
}
|
}
|
||||||
|
let status = statuses[0]
|
||||||
_ = mastodonController.persistentContainer.addOrUpdateOnViewContext(status: status)
|
_ = mastodonController.persistentContainer.addOrUpdateOnViewContext(status: status)
|
||||||
mode = .localID(status.id)
|
mode = .localID(status.id)
|
||||||
return status.id
|
return status.id
|
||||||
|
|
|
@ -12,6 +12,7 @@ import SwiftUI
|
||||||
private var converter = HTMLConverter(
|
private var converter = HTMLConverter(
|
||||||
font: .preferredFont(forTextStyle: .body),
|
font: .preferredFont(forTextStyle: .body),
|
||||||
monospaceFont: UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular)),
|
monospaceFont: UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular)),
|
||||||
|
fontMetrics: .default,
|
||||||
color: .label,
|
color: .label,
|
||||||
paragraphStyle: .default
|
paragraphStyle: .default
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,6 +13,7 @@ class ConfirmReblogStatusPreviewView: UIView {
|
||||||
private static let htmlConverter = HTMLConverter(
|
private static let htmlConverter = HTMLConverter(
|
||||||
font: .preferredFont(forTextStyle: .caption2),
|
font: .preferredFont(forTextStyle: .caption2),
|
||||||
monospaceFont: UIFontMetrics(forTextStyle: .caption2).scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular)),
|
monospaceFont: UIFontMetrics(forTextStyle: .caption2).scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular)),
|
||||||
|
fontMetrics: UIFontMetrics(forTextStyle: .caption2),
|
||||||
color: .label,
|
color: .label,
|
||||||
paragraphStyle: .default
|
paragraphStyle: .default
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,6 +25,7 @@ class ContentTextView: LinkTextView, BaseEmojiLabel {
|
||||||
private static let defaultBodyHTMLConverter = HTMLConverter(
|
private static let defaultBodyHTMLConverter = HTMLConverter(
|
||||||
font: .preferredFont(forTextStyle: .body),
|
font: .preferredFont(forTextStyle: .body),
|
||||||
monospaceFont: UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular)),
|
monospaceFont: UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular)),
|
||||||
|
fontMetrics: .default,
|
||||||
color: .label,
|
color: .label,
|
||||||
paragraphStyle: .default
|
paragraphStyle: .default
|
||||||
)
|
)
|
||||||
|
|
|
@ -21,6 +21,7 @@ class ProfileFieldValueView: UIView {
|
||||||
private static let converter = HTMLConverter(
|
private static let converter = HTMLConverter(
|
||||||
font: .preferredFont(forTextStyle: .body),
|
font: .preferredFont(forTextStyle: .body),
|
||||||
monospaceFont: UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular)),
|
monospaceFont: UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 17, weight: .regular)),
|
||||||
|
fontMetrics: .default,
|
||||||
color: .label,
|
color: .label,
|
||||||
paragraphStyle: .default
|
paragraphStyle: .default
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,6 +20,7 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status
|
||||||
private static let htmlConverter = HTMLConverter(
|
private static let htmlConverter = HTMLConverter(
|
||||||
font: ConversationMainStatusCollectionViewCell.contentFont,
|
font: ConversationMainStatusCollectionViewCell.contentFont,
|
||||||
monospaceFont: ConversationMainStatusCollectionViewCell.monospaceFont,
|
monospaceFont: ConversationMainStatusCollectionViewCell.monospaceFont,
|
||||||
|
fontMetrics: .default,
|
||||||
color: .label,
|
color: .label,
|
||||||
paragraphStyle: ConversationMainStatusCollectionViewCell.contentParagraphStyle
|
paragraphStyle: ConversationMainStatusCollectionViewCell.contentParagraphStyle
|
||||||
)
|
)
|
||||||
|
|
|
@ -70,8 +70,7 @@ class StatusMetaIndicatorsView: UIView {
|
||||||
|
|
||||||
private func configureImageView(_ imageView: UIImageView) {
|
private func configureImageView(_ imageView: UIImageView) {
|
||||||
let weight: UIImage.SymbolWeight = UIAccessibility.isBoldTextEnabled ? .regular : traitCollection.preferredContentSizeCategory > .large ? .light : .thin
|
let weight: UIImage.SymbolWeight = UIAccessibility.isBoldTextEnabled ? .regular : traitCollection.preferredContentSizeCategory > .large ? .light : .thin
|
||||||
let scale: UIImage.SymbolScale = traitCollection.preferredContentSizeCategory > .extraLarge ? .large : .default
|
imageView.preferredSymbolConfiguration = .init(pointSize: 0, weight: weight, scale: .default)
|
||||||
imageView.preferredSymbolConfiguration = .init(pointSize: 0, weight: weight, scale: scale)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUI(status: StatusMO) {
|
func updateUI(status: StatusMO) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
|
||||||
static let htmlConverter = HTMLConverter(
|
static let htmlConverter = HTMLConverter(
|
||||||
font: TimelineStatusCollectionViewCell.contentFont,
|
font: TimelineStatusCollectionViewCell.contentFont,
|
||||||
monospaceFont: TimelineStatusCollectionViewCell.monospaceFont,
|
monospaceFont: TimelineStatusCollectionViewCell.monospaceFont,
|
||||||
|
fontMetrics: .default,
|
||||||
color: .label,
|
color: .label,
|
||||||
paragraphStyle: TimelineStatusCollectionViewCell.contentParagraphStyle
|
paragraphStyle: TimelineStatusCollectionViewCell.contentParagraphStyle
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
// https://help.apple.com/xcode/#/dev745c5c974
|
// https://help.apple.com/xcode/#/dev745c5c974
|
||||||
|
|
||||||
MARKETING_VERSION = 2024.3
|
MARKETING_VERSION = 2024.3
|
||||||
CURRENT_PROJECT_VERSION = 128
|
CURRENT_PROJECT_VERSION = 129
|
||||||
CURRENT_PROJECT_VERSION = $(inherited)$(CURRENT_PROJECT_VERSION_BUILD_SUFFIX_$(CONFIGURATION))
|
CURRENT_PROJECT_VERSION = $(inherited)$(CURRENT_PROJECT_VERSION_BUILD_SUFFIX_$(CONFIGURATION))
|
||||||
|
|
||||||
CURRENT_PROJECT_VERSION_BUILD_SUFFIX_Debug=-dev
|
CURRENT_PROJECT_VERSION_BUILD_SUFFIX_Debug=-dev
|
||||||
|
|
Loading…
Reference in New Issue