Add url to Pixelfed instructions

This commit is contained in:
Marcin Czachursk 2023-02-21 08:36:14 +01:00
parent c160b48b03
commit 0cd2ed9f54
19 changed files with 138 additions and 91 deletions

View File

@ -72,6 +72,7 @@
F8764189298ABEC80057D362 /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8764188298ABEC80057D362 /* ErrorView.swift */; };
F876418B298AC1B80057D362 /* NoDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F876418A298AC1B80057D362 /* NoDataView.swift */; };
F876418D298AE5020057D362 /* PaginableStatusesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F876418C298AE5020057D362 /* PaginableStatusesView.swift */; };
F878842229A4A4E3003CFAD2 /* AppMetadataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F878842129A4A4E3003CFAD2 /* AppMetadataService.swift */; };
F87AEB922986C44E00434FB6 /* AuthorizationSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87AEB912986C44E00434FB6 /* AuthorizationSession.swift */; };
F87AEB942986C51B00434FB6 /* AppConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87AEB932986C51B00434FB6 /* AppConstants.swift */; };
F87AEB972986D16D00434FB6 /* AuthorisationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = F87AEB962986D16D00434FB6 /* AuthorisationError.swift */; };
@ -113,7 +114,7 @@
F89992CE296D92E7005994BF /* AttachmentModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89992CD296D92E7005994BF /* AttachmentModel.swift */; };
F89A46DC296EAACE0062125F /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89A46DB296EAACE0062125F /* SettingsView.swift */; };
F89A46DE296EABA20062125F /* StatusPlaceholderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89A46DD296EABA20062125F /* StatusPlaceholderView.swift */; };
F89AC00529A1F9B500F4159F /* Servers.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89AC00429A1F9B500F4159F /* Servers.swift */; };
F89AC00529A1F9B500F4159F /* AppMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89AC00429A1F9B500F4159F /* AppMetadata.swift */; };
F89AC00729A208CC00F4159F /* PlaceSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89AC00629A208CC00F4159F /* PlaceSelectorView.swift */; };
F89AC00929A20C5C00F4159F /* Client+Places.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89AC00829A20C5C00F4159F /* Client+Places.swift */; };
F89CEB802984198600A1376F /* AttachmentData+HighestImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89CEB7F2984198600A1376F /* AttachmentData+HighestImage.swift */; };
@ -212,6 +213,7 @@
F8764188298ABEC80057D362 /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
F876418A298AC1B80057D362 /* NoDataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoDataView.swift; sourceTree = "<group>"; };
F876418C298AE5020057D362 /* PaginableStatusesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginableStatusesView.swift; sourceTree = "<group>"; };
F878842129A4A4E3003CFAD2 /* AppMetadataService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMetadataService.swift; sourceTree = "<group>"; };
F87AEB912986C44E00434FB6 /* AuthorizationSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthorizationSession.swift; sourceTree = "<group>"; };
F87AEB932986C51B00434FB6 /* AppConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConstants.swift; sourceTree = "<group>"; };
F87AEB962986D16D00434FB6 /* AuthorisationError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthorisationError.swift; sourceTree = "<group>"; };
@ -253,7 +255,7 @@
F89992CD296D92E7005994BF /* AttachmentModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentModel.swift; sourceTree = "<group>"; };
F89A46DB296EAACE0062125F /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
F89A46DD296EABA20062125F /* StatusPlaceholderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusPlaceholderView.swift; sourceTree = "<group>"; };
F89AC00429A1F9B500F4159F /* Servers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Servers.swift; sourceTree = "<group>"; };
F89AC00429A1F9B500F4159F /* AppMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMetadata.swift; sourceTree = "<group>"; };
F89AC00629A208CC00F4159F /* PlaceSelectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceSelectorView.swift; sourceTree = "<group>"; };
F89AC00829A20C5C00F4159F /* Client+Places.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Client+Places.swift"; sourceTree = "<group>"; };
F89CEB7F2984198600A1376F /* AttachmentData+HighestImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AttachmentData+HighestImage.swift"; sourceTree = "<group>"; };
@ -401,7 +403,7 @@
F86167C7297FE781004D1F67 /* AvatarShape.swift */,
F8764186298ABB520057D362 /* ViewState.swift */,
F8FA9918299FA35A007AB130 /* PhotoAttachment.swift */,
F89AC00429A1F9B500F4159F /* Servers.swift */,
F89AC00429A1F9B500F4159F /* AppMetadata.swift */,
);
path = Models;
sourceTree = "<group>";
@ -600,6 +602,7 @@
F886F256297859E300879356 /* CacheImageService.swift */,
F88E4D49297EA0490057491A /* RouterPath.swift */,
F829193B2983012400367CE2 /* ImageSizeService.swift */,
F878842129A4A4E3003CFAD2 /* AppMetadataService.swift */,
);
path = Services;
sourceTree = "<group>";
@ -813,10 +816,11 @@
F89D6C4429718092001DA3D4 /* AccentsSectionView.swift in Sources */,
F88E4D42297E69FD0057491A /* StatusesView.swift in Sources */,
F86FB555298BF83F000131F0 /* FavouriteTouch.swift in Sources */,
F878842229A4A4E3003CFAD2 /* AppMetadataService.swift in Sources */,
F85D497929640B9D00751DF7 /* ImagesCarousel.swift in Sources */,
F8C5E55F2988E92600ADF6A7 /* AccountModel.swift in Sources */,
F89D6C3F29716E41001DA3D4 /* Theme.swift in Sources */,
F89AC00529A1F9B500F4159F /* Servers.swift in Sources */,
F89AC00529A1F9B500F4159F /* AppMetadata.swift in Sources */,
F8CC95CE2970761D00C9C2AC /* TintColor.swift in Sources */,
F89992CC296D9231005994BF /* StatusModel.swift in Sources */,
F80048052961850500E6868A /* StatusData+CoreDataClass.swift in Sources */,

View File

@ -9,48 +9,10 @@ import PixelfedKit
/// Pixelfed 'Search'.
extension Client {
public class Instances {
private let urlJson = URL(string: "https://raw.githubusercontent.com/VernissageApp/Home/main/instances.json")!
private let backupInstances: [String] = [
"https://pixelfed.de",
"https://pixelfed.social",
"https://pxlmo.com",
"https://metapixl.com",
"https://pixey.org",
"https://pixel.tchncs.de",
"https://pixelfed.tokyo",
"https://pixelfed.fr",
"https://pixelfed.nz",
"https://pixelfed.au",
"https://pixelfed.eus",
"https://pixelfed.bachgau.social",
"https://pixelfed.es",
"https://pixelfed.cz",
"https://pixelfed.automat.click",
"https://gram.social",
"https://nixorigin.one",
"https://miniature.photography",
"https://fedifilm.art",
"https://fedipix.de",
"https://pixel.jabbxi.de",
"https://nodegray.com",
"https://socialpixels.xyz",
"https://pixel.mamutut.space",
"https://pixelfed.fioverse.zone",
"https://pixel.artemai.art",
"https://pix.anduin.net",
"https://faf.photos",
"https://pix.vleij.com",
"https://pixels.gsi.li",
"https://eorzea.photos"
]
func instances() async -> [Instance] {
public class Instances {
func instances(instanceUrls: [String]) async -> [Instance] {
var instances: [Instance] = []
// First we have to download list of instances from github.
let instanceUrls = await self.servers()
// Now we have to download information about each instance.
await withTaskGroup(of: Instance?.self) { group in
for url in instanceUrls {
@ -83,21 +45,5 @@ extension Client {
let client = PixelfedClient(baseURL: url)
return try await client.readInstanceInformation()
}
private func servers() async -> [String] {
do {
let (data, response) = try await URLSession.shared.data(from: urlJson)
guard (response as? HTTPURLResponse)?.status?.responseType == .success else {
throw NetworkError.notSuccessResponse(response)
}
let servers = try JSONDecoder().decode(Servers.self, from: data)
return servers.instances
} catch {
ErrorService.shared.handle(error, message: "Error during downloading list of instances")
return backupInstances
}
}
}
}

View File

@ -0,0 +1,51 @@
//
// https://mczachurski.dev
// Copyright © 2023 Marcin Czachurski and the repository contributors.
// Licensed under the MIT License.
//
import Foundation
public struct AppMetadata: Codable {
public let instructionsUrl: String
public let serversUrl: String
public let instances: [String]
init() {
self.instructionsUrl = "https://pixelfed.org/how-to-join"
self.serversUrl = "https://pixelfed.org/servers"
self.instances = [
"https://pixelfed.de",
"https://pixelfed.social",
"https://pxlmo.com",
"https://metapixl.com",
"https://pixey.org",
"https://pixel.tchncs.de",
"https://pixelfed.tokyo",
"https://pixelfed.fr",
"https://pixelfed.nz",
"https://pixelfed.au",
"https://pixelfed.eus",
"https://pixelfed.bachgau.social",
"https://pixelfed.es",
"https://pixelfed.cz",
"https://pixelfed.automat.click",
"https://gram.social",
"https://nixorigin.one",
"https://miniature.photography",
"https://fedifilm.art",
"https://fedipix.de",
"https://pixel.jabbxi.de",
"https://nodegray.com",
"https://socialpixels.xyz",
"https://pixel.mamutut.space",
"https://pixelfed.fioverse.zone",
"https://pixel.artemai.art",
"https://pix.anduin.net",
"https://faf.photos",
"https://pix.vleij.com",
"https://pixels.gsi.li",
"https://eorzea.photos"
]
}
}

View File

@ -1,11 +0,0 @@
//
// https://mczachurski.dev
// Copyright © 2023 Marcin Czachurski and the repository contributors.
// Licensed under the MIT License.
//
import Foundation
public struct Servers: Codable {
public let instances: [String]
}

View File

@ -0,0 +1,39 @@
//
// https://mczachurski.dev
// Copyright © 2023 Marcin Czachurski and the repository contributors.
// Licensed under the MIT License.
//
import Foundation
import PixelfedKit
public class AppMetadataService {
public static let shared = AppMetadataService()
private init() { }
private let metadataUrl = URL(string: "https://raw.githubusercontent.com/VernissageApp/Home/main/instances.json")!
private let metadataCacheKey = "metadataCacheKey"
private var memoryCacheData = MemoryCache<String, AppMetadata>(entryLifetime: 600)
public func metadata() async -> AppMetadata {
do {
if let metadata = self.memoryCacheData[metadataCacheKey] {
return metadata
}
let (data, response) = try await URLSession.shared.data(from: metadataUrl)
guard (response as? HTTPURLResponse)?.status?.responseType == .success else {
throw NetworkError.notSuccessResponse(response)
}
let metadata = try JSONDecoder().decode(AppMetadata.self, from: data)
self.memoryCacheData[metadataCacheKey] = metadata
return metadata
} catch {
ErrorService.shared.handle(error, message: "Error during downloading metadata.")
return AppMetadata()
}
}
}

View File

@ -29,7 +29,7 @@ struct AccountsView: View {
var body: some View {
self.mainBody()
.navigationBarTitle(self.getTitle())
.navigationTitle(self.getTitle())
}
@ViewBuilder

View File

@ -200,7 +200,8 @@ struct ComposeView: View {
}
})
.photosPicker(isPresented: $photosPickerVisible, selection: $selectedItems, maxSelectionCount: 4, matching: .images)
.navigationBarTitle(Text("Compose"), displayMode: .inline)
.navigationTitle("Compose")
.navigationBarTitleDisplayMode(.inline)
}
.withAppRouteur()
.withOverlayDestinations(overlayDestinations: $routerPath.presentedOverlay)

View File

@ -37,7 +37,7 @@ struct MainView: View {
var body: some View {
self.getMainView()
.navigationBarTitle(navBarTitle)
.navigationTitle(navBarTitle)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
self.getLeadingToolbar()

View File

@ -23,7 +23,7 @@ struct NotificationsView: View {
var body: some View {
self.mainBody()
.navigationBarTitle("Notifications")
.navigationTitle("Notifications")
}
@ViewBuilder

View File

@ -28,7 +28,7 @@ struct PaginableStatusesView: View {
var body: some View {
self.mainBody()
.navigationBarTitle(self.getTitle())
.navigationTitle(self.getTitle())
}
@ViewBuilder

View File

@ -47,7 +47,8 @@ struct PhotoEditorView: View {
.onAppear {
self.description = self.photoAttachment.uploadedAttachment?.description ?? String.empty()
}
.navigationBarTitle(Text("Photo details"), displayMode: .inline)
.navigationTitle("Photo details")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
self.getTrailingToolbar()
}

View File

@ -86,7 +86,8 @@ struct PlaceSelectorView: View {
}
}
}
.navigationBarTitle(Text("Places"), displayMode: .inline)
.navigationTitle("Places")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
self.getTrailingToolbar()
}

View File

@ -58,7 +58,8 @@ struct SettingsView: View {
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification), perform: { _ in
self.theme = applicationState.theme.colorScheme() ?? self.getSystemColorScheme()
})
.navigationBarTitle(Text("Settings"), displayMode: .inline)
.navigationTitle("Settings")
.navigationBarTitleDisplayMode(.inline)
.preferredColorScheme(self.theme)
}
.withAppRouteur()

View File

@ -15,14 +15,15 @@ struct SignInView: View {
@EnvironmentObject var applicationState: ApplicationState
@EnvironmentObject var client: Client
@State private var serverAddress: String = String.empty()
@State private var serverAddress = String.empty()
@State private var instructionsUrlString:String?
@State private var instances: [Instance] = []
var onSignedIn: ((_ accountData: AccountData) -> Void)?
var body: some View {
List {
Section("Custom server address") {
Section {
VStack(alignment: .center) {
HStack(alignment: .center, spacing: 4) {
TextField("Server address", text: $serverAddress)
@ -44,9 +45,20 @@ struct SignInView: View {
.padding(.vertical, 4)
}
}
} header: {
Text("Enter server address")
} footer: {
if let instructionsUrlString = self.instructionsUrlString,
let instructionsUrl = URL(string: instructionsUrlString) {
HStack {
Spacer()
Link("How to join Pixelfed", destination: instructionsUrl)
.font(.caption)
}
}
}
Section("Pixelfed servers") {
Section("Or choose Pixelfed server") {
if self.instances.isEmpty {
HStack {
Spacer()
@ -62,12 +74,13 @@ struct SignInView: View {
}
}
}
}
.onFirstAppear {
self.instances = await self.client.instances.instances()
let metadata = await AppMetadataService.shared.metadata()
self.instances = await self.client.instances.instances(instanceUrls: metadata.instances)
self.instructionsUrlString = metadata.instructionsUrl
}
.navigationBarTitle("Sign in to Pixelfed")
.navigationTitle("Sign in to Pixelfed")
.navigationBarTitleDisplayMode(.inline)
}

View File

@ -36,7 +36,7 @@ struct StatusView: View {
var body: some View {
self.mainBody()
.navigationBarTitle("Details")
.navigationTitle("Details")
.fullScreenCover(isPresented: $showImageViewer, content: {
if let statusViewModel = self.statusViewModel {
ImagesViewer(statusViewModel: statusViewModel, selectedAttachmentId: selectedAttachmentId ?? String.empty())

View File

@ -31,7 +31,7 @@ struct StatusesView: View {
var body: some View {
self.mainBody()
.navigationBarTitle(self.getTitle())
.navigationTitle(self.getTitle())
.toolbar {
// TODO: It seems like pixelfed is not supporting the endpoints.
// self.getTrailingToolbar()

View File

@ -69,7 +69,8 @@ struct ThirdPartyView: View {
.font(.footnote)
}
}
.navigationBarTitle("Third party", displayMode: .inline)
.navigationTitle("Third party")
.navigationBarTitleDisplayMode(.inline)
}
}

View File

@ -41,7 +41,7 @@ struct TrendStatusesView: View {
self.mainBody()
}
.navigationBarTitle("Trends")
.navigationTitle("Trends")
}
@ViewBuilder

View File

@ -21,7 +21,7 @@ struct UserProfileView: View {
var body: some View {
self.mainBody()
.navigationBarTitle(self.accountDisplayName ?? self.accountUserName)
.navigationTitle(self.accountDisplayName ?? self.accountUserName)
.toolbar {
if let account = self.account {
if self.applicationState.account?.id != account.id {