New Timeline architecture

This commit is contained in:
Thomas Ricouard 2022-11-21 09:31:32 +01:00
parent ab8e8a59ea
commit 864a0b3969
10 changed files with 127 additions and 49 deletions

View File

@ -7,8 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
9F295540292B6C3400E0E81B /* Timeline in Frameworks */ = {isa = PBXBuildFile; productRef = 9F29553F292B6C3400E0E81B /* Timeline */; };
9FBFE63D292A715500C250E9 /* IceCubesAppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBFE63C292A715500C250E9 /* IceCubesAppApp.swift */; };
9FBFE63F292A715500C250E9 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBFE63E292A715500C250E9 /* ContentView.swift */; };
9FBFE641292A715600C250E9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9FBFE640292A715600C250E9 /* Assets.xcassets */; };
9FBFE645292A715600C250E9 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9FBFE644292A715600C250E9 /* Preview Assets.xcassets */; };
9FBFE64E292A72BD00C250E9 /* Network in Frameworks */ = {isa = PBXBuildFile; productRef = 9FBFE64D292A72BD00C250E9 /* Network */; };
@ -16,9 +16,9 @@
/* Begin PBXFileReference section */
9F29553D292B67B600E0E81B /* Network */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Network; path = Packages/Network; sourceTree = "<group>"; };
9F29553E292B6AF600E0E81B /* Timeline */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Timeline; path = Packages/Timeline; sourceTree = "<group>"; };
9FBFE639292A715500C250E9 /* IceCubesApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IceCubesApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
9FBFE63C292A715500C250E9 /* IceCubesAppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IceCubesAppApp.swift; sourceTree = "<group>"; };
9FBFE63E292A715500C250E9 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
9FBFE640292A715600C250E9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
9FBFE642292A715600C250E9 /* IceCubesApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IceCubesApp.entitlements; sourceTree = "<group>"; };
9FBFE644292A715600C250E9 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
@ -30,6 +30,7 @@
buildActionMask = 2147483647;
files = (
9FBFE64E292A72BD00C250E9 /* Network in Frameworks */,
9F295540292B6C3400E0E81B /* Timeline in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -42,6 +43,7 @@
9FBFE63B292A715500C250E9 /* IceCubesApp */,
9FBFE63A292A715500C250E9 /* Products */,
9FBFE64C292A72BD00C250E9 /* Frameworks */,
9F29553E292B6AF600E0E81B /* Timeline */,
9F29553D292B67B600E0E81B /* Network */,
);
sourceTree = "<group>";
@ -58,7 +60,6 @@
isa = PBXGroup;
children = (
9FBFE63C292A715500C250E9 /* IceCubesAppApp.swift */,
9FBFE63E292A715500C250E9 /* ContentView.swift */,
9FBFE640292A715600C250E9 /* Assets.xcassets */,
9FBFE642292A715600C250E9 /* IceCubesApp.entitlements */,
9FBFE643292A715600C250E9 /* Preview Content */,
@ -99,6 +100,7 @@
name = IceCubesApp;
packageProductDependencies = (
9FBFE64D292A72BD00C250E9 /* Network */,
9F29553F292B6C3400E0E81B /* Timeline */,
);
productName = IceCubesApp;
productReference = 9FBFE639292A715500C250E9 /* IceCubesApp.app */;
@ -154,7 +156,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9FBFE63F292A715500C250E9 /* ContentView.swift in Sources */,
9FBFE63D292A715500C250E9 /* IceCubesAppApp.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -371,6 +372,10 @@
/* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */
9F29553F292B6C3400E0E81B /* Timeline */ = {
isa = XCSwiftPackageProductDependency;
productName = Timeline;
};
9FBFE64D292A72BD00C250E9 /* Network */ = {
isa = XCSwiftPackageProductDependency;
productName = Network;

View File

@ -1,43 +0,0 @@
import SwiftUI
import Network
struct ContentView: View {
@State private var statuses: [Status] = []
@State private var client = Client(server: "mastodon.social")
var body: some View {
List(statuses) { status in
VStack(alignment: .leading) {
HStack {
AsyncImage(
url: status.account.avatar,
content: { image in
image.resizable()
.aspectRatio(contentMode: .fit)
.cornerRadius(13)
.frame(maxWidth: 26, maxHeight: 26)
},
placeholder: {
ProgressView()
}
)
Text(status.account.username)
}
Text(status.content)
}
}
.task {
do {
self.statuses = try await client.fetchArray(endpoint: Timeline.pub)
} catch {
print(error.localizedDescription)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

View File

@ -1,10 +1,15 @@
import SwiftUI
import Timeline
import Network
@main
struct IceCubesAppApp: App {
@StateObject private var client = Client(server: "mastodon.social")
var body: some Scene {
WindowGroup {
ContentView()
TimelineView(kind: .pub)
.environmentObject(client)
}
}
}

View File

@ -1,6 +1,7 @@
import Foundation
import SwiftUI
public struct Client {
public class Client: ObservableObject {
public enum Version: String {
case v1
}

9
Packages/Timeline/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc

View File

@ -0,0 +1,29 @@
// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "Timeline",
platforms: [
.iOS(.v16),
],
products: [
.library(
name: "Timeline",
targets: ["Timeline"]),
],
dependencies: [
.package(name: "Network", path: "../Network"),
],
targets: [
.target(
name: "Timeline",
dependencies: [
.product(name: "Network", package: "Network")
]),
.testTarget(
name: "TimelineTests",
dependencies: ["Timeline"]),
]
)

View File

@ -0,0 +1,3 @@
# Timeline
A description of this package.

View File

@ -0,0 +1,27 @@
import SwiftUI
import Network
struct StatusRowView: View {
let status: Status
var body: some View {
VStack(alignment: .leading) {
HStack {
AsyncImage(
url: status.account.avatar,
content: { image in
image.resizable()
.aspectRatio(contentMode: .fit)
.cornerRadius(13)
.frame(maxWidth: 26, maxHeight: 26)
},
placeholder: {
ProgressView()
}
)
Text(status.account.username)
}
Text(status.content)
}
}
}

View File

@ -0,0 +1,31 @@
import SwiftUI
import Network
public struct TimelineView: View {
public enum Kind {
case pub, hastah, home, list
}
@EnvironmentObject private var client: Client
@State private var statuses: [Status] = []
private let kind: Kind
public init(kind: Kind) {
self.kind = kind
}
public var body: some View {
List(statuses) { status in
StatusRowView(status: status)
}
.task {
do {
self.statuses = try await client.fetchArray(endpoint: Timeline.pub)
} catch {
print(error.localizedDescription)
}
}
}
}

View File

@ -0,0 +1,11 @@
import XCTest
@testable import Timeline
final class TimelineTests: XCTestCase {
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.
XCTAssertEqual(Timeline().text, "Hello, World!")
}
}