Enforce Rust and Swift ownership boundary
This commit is contained in:
@@ -494,6 +494,22 @@ fileprivate struct FfiConverterInt64: FfiConverterPrimitive {
|
||||
}
|
||||
}
|
||||
|
||||
#if swift(>=5.8)
|
||||
@_documentation(visibility: private)
|
||||
#endif
|
||||
fileprivate struct FfiConverterDouble: FfiConverterPrimitive {
|
||||
typealias FfiType = Double
|
||||
typealias SwiftType = Double
|
||||
|
||||
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Double {
|
||||
return try lift(readDouble(&buf))
|
||||
}
|
||||
|
||||
public static func write(_ value: Double, into buf: inout [UInt8]) {
|
||||
writeDouble(&buf, lower(value))
|
||||
}
|
||||
}
|
||||
|
||||
#if swift(>=5.8)
|
||||
@_documentation(visibility: private)
|
||||
#endif
|
||||
@@ -605,6 +621,8 @@ public protocol GotchaCoreProtocol: AnyObject, Sendable {
|
||||
|
||||
func issueFilters(owner: String, repository: String) async throws -> IssueFilterOptions
|
||||
|
||||
func issueFiltersActive(owner: String, repository: String) throws -> Bool
|
||||
|
||||
func issues(owner: String, repository: String) async throws -> [IssueRow]
|
||||
|
||||
func milestone(owner: String, repository: String, id: Int64) async throws -> MilestonePage
|
||||
@@ -621,7 +639,7 @@ public protocol GotchaCoreProtocol: AnyObject, Sendable {
|
||||
|
||||
func repositoryContents(owner: String, repository: String, path: String) async throws -> [RepositoryContentRow]
|
||||
|
||||
func repositoryFile(owner: String, repository: String, path: String) async throws -> Data
|
||||
func repositoryFile(owner: String, repository: String, path: String) async throws -> RepositoryFilePage
|
||||
|
||||
func selectServer(index: UInt32) throws
|
||||
|
||||
@@ -819,10 +837,10 @@ open func issue(owner: String, repository: String, number: Int64)async throws -
|
||||
|
||||
open func issueFilters(owner: String, repository: String)async throws -> IssueFilterOptions {
|
||||
return
|
||||
try await uniffiRustCallAsync(
|
||||
try await uniffiRustCallAsync(
|
||||
rustFutureFunc: {
|
||||
uniffi_gotcha_core_fn_method_gotchacore_issue_filters(
|
||||
self.uniffiCloneHandle(), FfiConverterString.lower(owner), FfiConverterString.lower(repository)
|
||||
self.uniffiCloneHandle(),FfiConverterString.lower(owner),FfiConverterString.lower(repository)
|
||||
)
|
||||
},
|
||||
pollFunc: ffi_gotcha_core_rust_future_poll_rust_buffer,
|
||||
@@ -833,6 +851,17 @@ open func issueFilters(owner: String, repository: String)async throws -> IssueF
|
||||
)
|
||||
}
|
||||
|
||||
open func issueFiltersActive(owner: String, repository: String)throws -> Bool {
|
||||
return try FfiConverterBool.lift(try rustCallWithError(FfiConverterTypeGotchaError_lift) {
|
||||
uniffiCallStatus in
|
||||
uniffi_gotcha_core_fn_method_gotchacore_issue_filters_active(
|
||||
self.uniffiCloneHandle(),
|
||||
FfiConverterString.lower(owner),
|
||||
FfiConverterString.lower(repository),uniffiCallStatus
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
open func issues(owner: String, repository: String)async throws -> [IssueRow] {
|
||||
return
|
||||
try await uniffiRustCallAsync(
|
||||
@@ -961,7 +990,7 @@ open func repositoryContents(owner: String, repository: String, path: String)asy
|
||||
)
|
||||
}
|
||||
|
||||
open func repositoryFile(owner: String, repository: String, path: String)async throws -> Data {
|
||||
open func repositoryFile(owner: String, repository: String, path: String)async throws -> RepositoryFilePage {
|
||||
return
|
||||
try await uniffiRustCallAsync(
|
||||
rustFutureFunc: {
|
||||
@@ -972,7 +1001,7 @@ open func repositoryFile(owner: String, repository: String, path: String)async t
|
||||
pollFunc: ffi_gotcha_core_rust_future_poll_rust_buffer,
|
||||
completeFunc: ffi_gotcha_core_rust_future_complete_rust_buffer,
|
||||
freeFunc: ffi_gotcha_core_rust_future_free_rust_buffer,
|
||||
liftFunc: FfiConverterData.lift,
|
||||
liftFunc: FfiConverterTypeRepositoryFilePage_lift,
|
||||
errorHandler: FfiConverterTypeGotchaError_lift
|
||||
)
|
||||
}
|
||||
@@ -1007,11 +1036,11 @@ open func setAppearance(index: UInt32)throws {try rustCallWithError(FfiConvert
|
||||
open func setIssueFilters(owner: String, repository: String, milestone: String, labels: [String])throws {try rustCallWithError(FfiConverterTypeGotchaError_lift) {
|
||||
uniffiCallStatus in
|
||||
uniffi_gotcha_core_fn_method_gotchacore_set_issue_filters(
|
||||
self.uniffiCloneHandle(),
|
||||
self.uniffiCloneHandle(),
|
||||
FfiConverterString.lower(owner),
|
||||
FfiConverterString.lower(repository),
|
||||
FfiConverterString.lower(milestone),
|
||||
FfiConverterSequenceString.lower(labels), uniffiCallStatus
|
||||
FfiConverterSequenceString.lower(labels),uniffiCallStatus
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1312,8 +1341,7 @@ public func FfiConverterTypeCommitPage_lower(_ value: CommitPage) -> RustBuffer
|
||||
public struct CommitRow: Equatable, Hashable {
|
||||
public var sha: String
|
||||
public var title: String
|
||||
public var meta: String
|
||||
public var refs: String
|
||||
public var detail: String
|
||||
public var topLanes: [UInt32]
|
||||
public var bottomLanes: [UInt32]
|
||||
public var nodeLane: UInt32?
|
||||
@@ -1321,11 +1349,10 @@ public struct CommitRow: Equatable, Hashable {
|
||||
|
||||
// Default memberwise initializers are never public by default, so we
|
||||
// declare one manually.
|
||||
public init(sha: String, title: String, meta: String, refs: String, topLanes: [UInt32], bottomLanes: [UInt32], nodeLane: UInt32?, connections: [UInt32]) {
|
||||
public init(sha: String, title: String, detail: String, topLanes: [UInt32], bottomLanes: [UInt32], nodeLane: UInt32?, connections: [UInt32]) {
|
||||
self.sha = sha
|
||||
self.title = title
|
||||
self.meta = meta
|
||||
self.refs = refs
|
||||
self.detail = detail
|
||||
self.topLanes = topLanes
|
||||
self.bottomLanes = bottomLanes
|
||||
self.nodeLane = nodeLane
|
||||
@@ -1350,8 +1377,7 @@ public struct FfiConverterTypeCommitRow: FfiConverterRustBuffer {
|
||||
try CommitRow(
|
||||
sha: FfiConverterString.read(from: &buf),
|
||||
title: FfiConverterString.read(from: &buf),
|
||||
meta: FfiConverterString.read(from: &buf),
|
||||
refs: FfiConverterString.read(from: &buf),
|
||||
detail: FfiConverterString.read(from: &buf),
|
||||
topLanes: FfiConverterSequenceUInt32.read(from: &buf),
|
||||
bottomLanes: FfiConverterSequenceUInt32.read(from: &buf),
|
||||
nodeLane: FfiConverterOptionUInt32.read(from: &buf),
|
||||
@@ -1362,8 +1388,7 @@ public struct FfiConverterTypeCommitRow: FfiConverterRustBuffer {
|
||||
public static func write(_ value: CommitRow, into buf: inout [UInt8]) {
|
||||
FfiConverterString.write(value.sha, into: &buf)
|
||||
FfiConverterString.write(value.title, into: &buf)
|
||||
FfiConverterString.write(value.meta, into: &buf)
|
||||
FfiConverterString.write(value.refs, into: &buf)
|
||||
FfiConverterString.write(value.detail, into: &buf)
|
||||
FfiConverterSequenceUInt32.write(value.topLanes, into: &buf)
|
||||
FfiConverterSequenceUInt32.write(value.bottomLanes, into: &buf)
|
||||
FfiConverterOptionUInt32.write(value.nodeLane, into: &buf)
|
||||
@@ -1562,20 +1587,14 @@ public func FfiConverterTypeFileRow_lower(_ value: FileRow) -> RustBuffer {
|
||||
|
||||
|
||||
public struct HeatCell: Equatable, Hashable {
|
||||
public var week: UInt32
|
||||
public var day: UInt32
|
||||
public var level: UInt32
|
||||
public var timestamp: Int64
|
||||
public var contributions: Int64
|
||||
|
||||
// Default memberwise initializers are never public by default, so we
|
||||
// declare one manually.
|
||||
public init(week: UInt32, day: UInt32, level: UInt32, timestamp: Int64, contributions: Int64) {
|
||||
self.week = week
|
||||
self.day = day
|
||||
public init(level: UInt32, timestamp: Int64) {
|
||||
self.level = level
|
||||
self.timestamp = timestamp
|
||||
self.contributions = contributions
|
||||
}
|
||||
|
||||
|
||||
@@ -1594,20 +1613,14 @@ public struct FfiConverterTypeHeatCell: FfiConverterRustBuffer {
|
||||
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> HeatCell {
|
||||
return
|
||||
try HeatCell(
|
||||
week: FfiConverterUInt32.read(from: &buf),
|
||||
day: FfiConverterUInt32.read(from: &buf),
|
||||
level: FfiConverterUInt32.read(from: &buf),
|
||||
timestamp: FfiConverterInt64.read(from: &buf),
|
||||
contributions: FfiConverterInt64.read(from: &buf)
|
||||
timestamp: FfiConverterInt64.read(from: &buf)
|
||||
)
|
||||
}
|
||||
|
||||
public static func write(_ value: HeatCell, into buf: inout [UInt8]) {
|
||||
FfiConverterUInt32.write(value.week, into: &buf)
|
||||
FfiConverterUInt32.write(value.day, into: &buf)
|
||||
FfiConverterUInt32.write(value.level, into: &buf)
|
||||
FfiConverterInt64.write(value.timestamp, into: &buf)
|
||||
FfiConverterInt64.write(value.contributions, into: &buf)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1630,14 +1643,18 @@ public func FfiConverterTypeHeatCell_lower(_ value: HeatCell) -> RustBuffer {
|
||||
public struct HomePage: Equatable, Hashable {
|
||||
public var serverName: String
|
||||
public var activities: [ActivityRow]
|
||||
public var issueActivities: [ActivityRow]
|
||||
public var pullActivities: [ActivityRow]
|
||||
public var heatCells: [HeatCell]
|
||||
public var contributionCount: Int64
|
||||
|
||||
// Default memberwise initializers are never public by default, so we
|
||||
// declare one manually.
|
||||
public init(serverName: String, activities: [ActivityRow], heatCells: [HeatCell], contributionCount: Int64) {
|
||||
public init(serverName: String, activities: [ActivityRow], issueActivities: [ActivityRow], pullActivities: [ActivityRow], heatCells: [HeatCell], contributionCount: Int64) {
|
||||
self.serverName = serverName
|
||||
self.activities = activities
|
||||
self.issueActivities = issueActivities
|
||||
self.pullActivities = pullActivities
|
||||
self.heatCells = heatCells
|
||||
self.contributionCount = contributionCount
|
||||
}
|
||||
@@ -1660,6 +1677,8 @@ public struct FfiConverterTypeHomePage: FfiConverterRustBuffer {
|
||||
try HomePage(
|
||||
serverName: FfiConverterString.read(from: &buf),
|
||||
activities: FfiConverterSequenceTypeActivityRow.read(from: &buf),
|
||||
issueActivities: FfiConverterSequenceTypeActivityRow.read(from: &buf),
|
||||
pullActivities: FfiConverterSequenceTypeActivityRow.read(from: &buf),
|
||||
heatCells: FfiConverterSequenceTypeHeatCell.read(from: &buf),
|
||||
contributionCount: FfiConverterInt64.read(from: &buf)
|
||||
)
|
||||
@@ -1668,6 +1687,8 @@ public struct FfiConverterTypeHomePage: FfiConverterRustBuffer {
|
||||
public static func write(_ value: HomePage, into buf: inout [UInt8]) {
|
||||
FfiConverterString.write(value.serverName, into: &buf)
|
||||
FfiConverterSequenceTypeActivityRow.write(value.activities, into: &buf)
|
||||
FfiConverterSequenceTypeActivityRow.write(value.issueActivities, into: &buf)
|
||||
FfiConverterSequenceTypeActivityRow.write(value.pullActivities, into: &buf)
|
||||
FfiConverterSequenceTypeHeatCell.write(value.heatCells, into: &buf)
|
||||
FfiConverterInt64.write(value.contributionCount, into: &buf)
|
||||
}
|
||||
@@ -1692,17 +1713,23 @@ public func FfiConverterTypeHomePage_lower(_ value: HomePage) -> RustBuffer {
|
||||
public struct IssueFilterOptions: Equatable, Hashable {
|
||||
public var milestones: [String]
|
||||
public var labels: [String]
|
||||
public var unavailableLabels: [String]
|
||||
public var selectedMilestone: String
|
||||
public var selectedLabels: [String]
|
||||
|
||||
// Default memberwise initializers are never public by default, so we
|
||||
// declare one manually.
|
||||
public init(milestones: [String], labels: [String], selectedMilestone: String, selectedLabels: [String]) {
|
||||
public init(milestones: [String], labels: [String], unavailableLabels: [String], selectedMilestone: String, selectedLabels: [String]) {
|
||||
self.milestones = milestones
|
||||
self.labels = labels
|
||||
self.unavailableLabels = unavailableLabels
|
||||
self.selectedMilestone = selectedMilestone
|
||||
self.selectedLabels = selectedLabels
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#if compiler(>=6)
|
||||
@@ -1718,6 +1745,7 @@ public struct FfiConverterTypeIssueFilterOptions: FfiConverterRustBuffer {
|
||||
try IssueFilterOptions(
|
||||
milestones: FfiConverterSequenceString.read(from: &buf),
|
||||
labels: FfiConverterSequenceString.read(from: &buf),
|
||||
unavailableLabels: FfiConverterSequenceString.read(from: &buf),
|
||||
selectedMilestone: FfiConverterString.read(from: &buf),
|
||||
selectedLabels: FfiConverterSequenceString.read(from: &buf)
|
||||
)
|
||||
@@ -1726,11 +1754,13 @@ public struct FfiConverterTypeIssueFilterOptions: FfiConverterRustBuffer {
|
||||
public static func write(_ value: IssueFilterOptions, into buf: inout [UInt8]) {
|
||||
FfiConverterSequenceString.write(value.milestones, into: &buf)
|
||||
FfiConverterSequenceString.write(value.labels, into: &buf)
|
||||
FfiConverterSequenceString.write(value.unavailableLabels, into: &buf)
|
||||
FfiConverterString.write(value.selectedMilestone, into: &buf)
|
||||
FfiConverterSequenceString.write(value.selectedLabels, into: &buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if swift(>=5.8)
|
||||
@_documentation(visibility: private)
|
||||
#endif
|
||||
@@ -2003,18 +2033,20 @@ public struct MilestoneRow: Equatable, Hashable {
|
||||
public var title: String
|
||||
public var description: String
|
||||
public var meta: String
|
||||
public var openIssues: Int64
|
||||
public var closedIssues: Int64
|
||||
public var hasIssues: Bool
|
||||
public var progress: Double
|
||||
public var progressAccessibility: String
|
||||
|
||||
// Default memberwise initializers are never public by default, so we
|
||||
// declare one manually.
|
||||
public init(id: Int64, title: String, description: String, meta: String, openIssues: Int64, closedIssues: Int64) {
|
||||
public init(id: Int64, title: String, description: String, meta: String, hasIssues: Bool, progress: Double, progressAccessibility: String) {
|
||||
self.id = id
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.meta = meta
|
||||
self.openIssues = openIssues
|
||||
self.closedIssues = closedIssues
|
||||
self.hasIssues = hasIssues
|
||||
self.progress = progress
|
||||
self.progressAccessibility = progressAccessibility
|
||||
}
|
||||
|
||||
|
||||
@@ -2037,8 +2069,9 @@ public struct FfiConverterTypeMilestoneRow: FfiConverterRustBuffer {
|
||||
title: FfiConverterString.read(from: &buf),
|
||||
description: FfiConverterString.read(from: &buf),
|
||||
meta: FfiConverterString.read(from: &buf),
|
||||
openIssues: FfiConverterInt64.read(from: &buf),
|
||||
closedIssues: FfiConverterInt64.read(from: &buf)
|
||||
hasIssues: FfiConverterBool.read(from: &buf),
|
||||
progress: FfiConverterDouble.read(from: &buf),
|
||||
progressAccessibility: FfiConverterString.read(from: &buf)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2047,8 +2080,9 @@ public struct FfiConverterTypeMilestoneRow: FfiConverterRustBuffer {
|
||||
FfiConverterString.write(value.title, into: &buf)
|
||||
FfiConverterString.write(value.description, into: &buf)
|
||||
FfiConverterString.write(value.meta, into: &buf)
|
||||
FfiConverterInt64.write(value.openIssues, into: &buf)
|
||||
FfiConverterInt64.write(value.closedIssues, into: &buf)
|
||||
FfiConverterBool.write(value.hasIssues, into: &buf)
|
||||
FfiConverterDouble.write(value.progress, into: &buf)
|
||||
FfiConverterString.write(value.progressAccessibility, into: &buf)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2270,6 +2304,72 @@ public func FfiConverterTypeRepositoryContentRow_lower(_ value: RepositoryConten
|
||||
}
|
||||
|
||||
|
||||
public struct RepositoryFilePage: Equatable, Hashable {
|
||||
public var name: String
|
||||
public var kind: String
|
||||
public var language: String
|
||||
public var text: String
|
||||
public var data: Data
|
||||
|
||||
// Default memberwise initializers are never public by default, so we
|
||||
// declare one manually.
|
||||
public init(name: String, kind: String, language: String, text: String, data: Data) {
|
||||
self.name = name
|
||||
self.kind = kind
|
||||
self.language = language
|
||||
self.text = text
|
||||
self.data = data
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#if compiler(>=6)
|
||||
extension RepositoryFilePage: Sendable {}
|
||||
#endif
|
||||
|
||||
#if swift(>=5.8)
|
||||
@_documentation(visibility: private)
|
||||
#endif
|
||||
public struct FfiConverterTypeRepositoryFilePage: FfiConverterRustBuffer {
|
||||
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> RepositoryFilePage {
|
||||
return
|
||||
try RepositoryFilePage(
|
||||
name: FfiConverterString.read(from: &buf),
|
||||
kind: FfiConverterString.read(from: &buf),
|
||||
language: FfiConverterString.read(from: &buf),
|
||||
text: FfiConverterString.read(from: &buf),
|
||||
data: FfiConverterData.read(from: &buf)
|
||||
)
|
||||
}
|
||||
|
||||
public static func write(_ value: RepositoryFilePage, into buf: inout [UInt8]) {
|
||||
FfiConverterString.write(value.name, into: &buf)
|
||||
FfiConverterString.write(value.kind, into: &buf)
|
||||
FfiConverterString.write(value.language, into: &buf)
|
||||
FfiConverterString.write(value.text, into: &buf)
|
||||
FfiConverterData.write(value.data, into: &buf)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if swift(>=5.8)
|
||||
@_documentation(visibility: private)
|
||||
#endif
|
||||
public func FfiConverterTypeRepositoryFilePage_lift(_ buf: RustBuffer) throws -> RepositoryFilePage {
|
||||
return try FfiConverterTypeRepositoryFilePage.lift(buf)
|
||||
}
|
||||
|
||||
#if swift(>=5.8)
|
||||
@_documentation(visibility: private)
|
||||
#endif
|
||||
public func FfiConverterTypeRepositoryFilePage_lower(_ value: RepositoryFilePage) -> RustBuffer {
|
||||
return FfiConverterTypeRepositoryFilePage.lower(value)
|
||||
}
|
||||
|
||||
|
||||
public struct RepositoryRow: Equatable, Hashable {
|
||||
public var name: String
|
||||
public var owner: String
|
||||
@@ -3035,6 +3135,9 @@ private let initializationResult: InitializationResult = {
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_issue_filters() != 24054) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_issue_filters_active() != 51470) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_issues() != 1316) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
@@ -3059,7 +3162,7 @@ private let initializationResult: InitializationResult = {
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_repository_contents() != 8454) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_repository_file() != 27399) {
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_repository_file() != 44948) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_select_server() != 22721) {
|
||||
@@ -3109,4 +3212,4 @@ public func uniffiEnsureGotchaCoreInitialized() {
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:enable all
|
||||
// swiftlint:enable all
|
||||
@@ -304,6 +304,11 @@ uint64_t uniffi_gotcha_core_fn_method_gotchacore_issue(uint64_t ptr, RustBuffer
|
||||
uint64_t uniffi_gotcha_core_fn_method_gotchacore_issue_filters(uint64_t ptr, RustBuffer owner, RustBuffer repository
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_ISSUE_FILTERS_ACTIVE
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_ISSUE_FILTERS_ACTIVE
|
||||
int8_t uniffi_gotcha_core_fn_method_gotchacore_issue_filters_active(uint64_t ptr, RustBuffer owner, RustBuffer repository, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_ISSUES
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_ISSUES
|
||||
uint64_t uniffi_gotcha_core_fn_method_gotchacore_issues(uint64_t ptr, RustBuffer owner, RustBuffer repository
|
||||
@@ -706,6 +711,12 @@ uint16_t uniffi_gotcha_core_checksum_method_gotchacore_issue(void
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_ISSUE_FILTERS
|
||||
uint16_t uniffi_gotcha_core_checksum_method_gotchacore_issue_filters(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_ISSUE_FILTERS_ACTIVE
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_ISSUE_FILTERS_ACTIVE
|
||||
uint16_t uniffi_gotcha_core_checksum_method_gotchacore_issue_filters_active(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_ISSUES
|
||||
|
||||
@@ -135,13 +135,10 @@ final class IssuesViewController: RefreshingTableViewController {
|
||||
|
||||
private func milestoneMenu(_ options: IssueFilterOptions) -> UIMenu {
|
||||
let selected = options.selectedMilestone
|
||||
var milestones = options.milestones
|
||||
if !selected.isEmpty, !milestones.contains(selected) { milestones.append(selected) }
|
||||
let all = UIAction(title: "All Milestones", state: selected.isEmpty ? .on : .off) {
|
||||
[weak self] _ in self?.selectMilestone("")
|
||||
}
|
||||
let actions = milestones.sorted { $0.localizedCaseInsensitiveCompare($1) == .orderedAscending }
|
||||
.map { milestone in
|
||||
let actions = options.milestones.map { milestone in
|
||||
UIAction(
|
||||
title: milestone,
|
||||
state: selected == milestone ? .on : .off
|
||||
@@ -156,13 +153,10 @@ final class IssuesViewController: RefreshingTableViewController {
|
||||
}
|
||||
|
||||
private func labelMenu(_ options: IssueFilterOptions) -> UIMenu {
|
||||
let available = Set(options.labels)
|
||||
let selected = Set(options.selectedLabels)
|
||||
let labels = available.union(selected)
|
||||
.sorted { $0.localizedCaseInsensitiveCompare($1) == .orderedAscending }
|
||||
let actions = labels.map { label in
|
||||
let actions = options.labels.map { label in
|
||||
UIAction(
|
||||
title: available.contains(label) ? label : "\(label) (Unavailable)",
|
||||
title: options.unavailableLabels.contains(label) ? "\(label) (Unavailable)" : label,
|
||||
attributes: .keepsMenuPresented,
|
||||
state: selected.contains(label) ? .on : .off
|
||||
) { [weak self] action in
|
||||
@@ -172,7 +166,7 @@ final class IssuesViewController: RefreshingTableViewController {
|
||||
if labels.remove(label) == nil { labels.insert(label) }
|
||||
do {
|
||||
try self.saveFilters(milestone: options.selectedMilestone, labels: labels)
|
||||
self.filterOptions?.selectedLabels = labels.sorted()
|
||||
self.filterOptions?.selectedLabels = Array(labels)
|
||||
action.state = labels.contains(label) ? .on : .off
|
||||
self.updateFilterMenu()
|
||||
self.loadIssues(refreshing: false)
|
||||
@@ -208,14 +202,12 @@ final class IssuesViewController: RefreshingTableViewController {
|
||||
owner: owner,
|
||||
repository: repository,
|
||||
milestone: milestone,
|
||||
labels: labels.sorted()
|
||||
labels: Array(labels)
|
||||
)
|
||||
}
|
||||
|
||||
private var filtersActive: Bool {
|
||||
context.core.settings().issueStatus != "open"
|
||||
|| filterOptions?.selectedMilestone.isEmpty == false
|
||||
|| filterOptions?.selectedLabels.isEmpty == false
|
||||
(try? context.core.issueFiltersActive(owner: owner, repository: repository)) ?? false
|
||||
}
|
||||
|
||||
private func updateFilterTint() {
|
||||
@@ -519,11 +511,10 @@ final class MilestoneCell: UITableViewCell {
|
||||
titleLabel.text = row.title
|
||||
descriptionLabel.text = row.description
|
||||
metaLabel.text = row.meta
|
||||
let total = row.openIssues + row.closedIssues
|
||||
progress.progress = total == 0 ? 0 : Float(row.closedIssues) / Float(total)
|
||||
progress.trackTintColor = total == 0 ? .systemGray5 : .systemOrange
|
||||
progress.progress = Float(row.progress)
|
||||
progress.trackTintColor = row.hasIssues ? .systemOrange : .systemGray5
|
||||
progress.accessibilityLabel = "Milestone progress"
|
||||
progress.accessibilityValue = "\(row.closedIssues) closed, \(row.openIssues) open"
|
||||
progress.accessibilityValue = row.progressAccessibility
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,7 +590,7 @@ final class PullsViewController: RefreshingTableViewController {
|
||||
let row = rows[indexPath.row]
|
||||
configureTextCell(
|
||||
cell,
|
||||
title: "\(row.repository) #\(row.number)\n\(row.title)",
|
||||
title: row.title,
|
||||
detail: "\(row.summary)\n\(row.meta)"
|
||||
)
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
@@ -819,9 +810,7 @@ final class CommitCell: UITableViewCell {
|
||||
var content = defaultContentConfiguration()
|
||||
content.directionalLayoutMargins.leading = laneCount == 0 ? 0 : min(72, CGFloat(laneCount) * 10 + 8)
|
||||
content.text = row.title
|
||||
content.secondaryText = row.refs.isEmpty
|
||||
? "\(row.meta)\n\(row.sha.prefix(8))"
|
||||
: "\(row.refs)\n\(row.meta) · \(row.sha.prefix(8))"
|
||||
content.secondaryText = row.detail
|
||||
content.secondaryTextProperties.numberOfLines = 2
|
||||
contentConfiguration = content
|
||||
setNeedsDisplay()
|
||||
|
||||
@@ -3,7 +3,6 @@ import MarkdownUI
|
||||
import QuickLook
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
@MainActor
|
||||
class MarkdownPageViewController: UIViewController {
|
||||
@@ -273,13 +272,13 @@ final class RepositoryDirectoryViewController: RefreshingTableViewController {
|
||||
private let path: String
|
||||
private var rows: [RepositoryContentRow] = []
|
||||
|
||||
init(context: AppContext, owner: String, repository: String, path: String) {
|
||||
init(context: AppContext, owner: String, repository: String, path: String, name: String) {
|
||||
self.context = context
|
||||
self.owner = owner
|
||||
self.repository = repository
|
||||
self.path = path
|
||||
super.init()
|
||||
title = path.split(separator: "/").last.map(String.init) ?? repository
|
||||
title = name
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
@@ -349,18 +348,19 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
|
||||
private var loadingTask: Task<Void, Never>?
|
||||
private var previewURL: URL?
|
||||
private var markdownSource: String?
|
||||
private var fileLanguage: String?
|
||||
private var displayedController: UIViewController?
|
||||
private var displayedView: UIView?
|
||||
private weak var sourceScrollView: UIScrollView?
|
||||
private weak var sourceTextView: UITextView?
|
||||
|
||||
init(context: AppContext, owner: String, repository: String, path: String) {
|
||||
init(context: AppContext, owner: String, repository: String, path: String, name: String) {
|
||||
self.context = context
|
||||
self.owner = owner
|
||||
self.repository = repository
|
||||
self.path = path
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
title = path.split(separator: "/").last.map(String.init)
|
||||
title = name
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
@@ -372,19 +372,17 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
|
||||
beginNavigationLoading(spinner)
|
||||
loadingTask = Task {
|
||||
do {
|
||||
let data = try await context.core.repositoryFile(
|
||||
let page = try await context.core.repositoryFile(
|
||||
owner: owner,
|
||||
repository: repository,
|
||||
path: path
|
||||
)
|
||||
if !isMediaFile(path), let source = String(data: data, encoding: .utf8) {
|
||||
if isMarkdownFile {
|
||||
showMarkdown(source)
|
||||
} else {
|
||||
showSource(source)
|
||||
}
|
||||
} else {
|
||||
try showQuickLook(data)
|
||||
title = page.name
|
||||
fileLanguage = page.language.isEmpty ? nil : page.language
|
||||
switch page.kind {
|
||||
case "markdown": showMarkdown(page.text)
|
||||
case "source": showSource(page.text)
|
||||
default: try showQuickLook(page.data, name: page.name)
|
||||
}
|
||||
} catch {
|
||||
if !Task.isCancelled { show(error: error) }
|
||||
@@ -398,20 +396,6 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
|
||||
updateSourceLayout()
|
||||
}
|
||||
|
||||
private func isMediaFile(_ path: String) -> Bool {
|
||||
guard let type = UTType(filenameExtension: (path as NSString).pathExtension) else {
|
||||
return false
|
||||
}
|
||||
return type.conforms(to: .image)
|
||||
|| type.conforms(to: .audio)
|
||||
|| type.conforms(to: .audiovisualContent)
|
||||
|| type.conforms(to: .pdf)
|
||||
}
|
||||
|
||||
private var isMarkdownFile: Bool {
|
||||
["md", "markdown", "mdown", "mkd"].contains((path as NSString).pathExtension.lowercased())
|
||||
}
|
||||
|
||||
deinit {
|
||||
loadingTask?.cancel()
|
||||
if let previewURL { try? FileManager.default.removeItem(at: previewURL) }
|
||||
@@ -464,7 +448,7 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
|
||||
traitCollection.userInterfaceStyle == .dark ? "atom-one-dark" : "atom-one-light"
|
||||
)
|
||||
highlighter?.theme.setCodeFont(.monospacedSystemFont(ofSize: 13, weight: .regular))
|
||||
let highlighted = highlighter?.highlight(source, as: sourceLanguage(path))
|
||||
let highlighted = highlighter?.highlight(source, as: fileLanguage)
|
||||
?? NSAttributedString(string: source, attributes: [
|
||||
.font: UIFont.monospacedSystemFont(ofSize: 13, weight: .regular),
|
||||
.foregroundColor: UIColor.label,
|
||||
@@ -532,8 +516,7 @@ final class RepositoryFileViewController: UIViewController, QLPreviewControllerD
|
||||
scrollView.contentSize = contentSize
|
||||
}
|
||||
|
||||
private func showQuickLook(_ data: Data) throws {
|
||||
let name = path.split(separator: "/").last.map(String.init) ?? "Preview"
|
||||
private func showQuickLook(_ data: Data, name: String) throws {
|
||||
let url = FileManager.default.temporaryDirectory
|
||||
.appendingPathComponent("\(UUID().uuidString)-\(name)")
|
||||
try data.write(to: url, options: .atomic)
|
||||
|
||||
@@ -303,17 +303,6 @@ final class HomeViewController: RefreshingTableViewController {
|
||||
case all
|
||||
case issues
|
||||
case pulls
|
||||
|
||||
func includes(_ row: ActivityRow) -> Bool {
|
||||
switch self {
|
||||
case .all:
|
||||
return true
|
||||
case .issues:
|
||||
return row.icon.contains("issue")
|
||||
case .pulls:
|
||||
return row.icon.contains("pull")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private let context: AppContext
|
||||
@@ -321,7 +310,12 @@ final class HomeViewController: RefreshingTableViewController {
|
||||
private var filter = ActivityFilter.all
|
||||
|
||||
private var activities: [ActivityRow] {
|
||||
page?.activities.filter(filter.includes) ?? []
|
||||
guard let page else { return [] }
|
||||
switch filter {
|
||||
case .all: return page.activities
|
||||
case .issues: return page.issueActivities
|
||||
case .pulls: return page.pullActivities
|
||||
}
|
||||
}
|
||||
|
||||
init(context: AppContext) {
|
||||
@@ -443,20 +437,7 @@ final class HeatmapView: UIView {
|
||||
private let calendar = Calendar(identifier: .gregorian)
|
||||
|
||||
init(page: HomePage, selectedFilter: Int, onFilter: @escaping (Int) -> Void) {
|
||||
let latest = page.heatCells.last.map {
|
||||
Date(timeIntervalSince1970: TimeInterval($0.timestamp))
|
||||
} ?? Date()
|
||||
let latestMonth = Calendar(identifier: .gregorian).date(
|
||||
from: Calendar(identifier: .gregorian).dateComponents([.year, .month], from: latest)
|
||||
) ?? latest
|
||||
let firstMonth = Calendar(identifier: .gregorian).date(
|
||||
byAdding: .month,
|
||||
value: -8,
|
||||
to: latestMonth
|
||||
) ?? latestMonth
|
||||
cells = page.heatCells.filter {
|
||||
Date(timeIntervalSince1970: TimeInterval($0.timestamp)) >= firstMonth
|
||||
}
|
||||
cells = page.heatCells
|
||||
super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 180))
|
||||
backgroundColor = .systemBackground
|
||||
let title = UILabel(frame: CGRect(x: 16, y: 12, width: 300, height: 22))
|
||||
@@ -465,7 +446,7 @@ final class HeatmapView: UIView {
|
||||
title.textColor = .secondaryLabel
|
||||
addSubview(title)
|
||||
let total = UILabel(frame: CGRect(x: 16, y: 108, width: 300, height: 18))
|
||||
total.text = "\(cells.reduce(0) { $0 + $1.contributions }) contributions"
|
||||
total.text = "\(page.contributionCount) contributions"
|
||||
total.font = .preferredFont(forTextStyle: .caption1)
|
||||
total.textColor = .tertiaryLabel
|
||||
addSubview(total)
|
||||
|
||||
@@ -151,39 +151,19 @@ func showRepositoryContent(
|
||||
context: context,
|
||||
owner: owner,
|
||||
repository: repository,
|
||||
path: row.path
|
||||
path: row.path,
|
||||
name: row.name
|
||||
)
|
||||
: RepositoryFileViewController(
|
||||
context: context,
|
||||
owner: owner,
|
||||
repository: repository,
|
||||
path: row.path
|
||||
path: row.path,
|
||||
name: row.name
|
||||
)
|
||||
navigationController?.pushViewController(destination, animated: true)
|
||||
}
|
||||
|
||||
func sourceLanguage(_ path: String) -> String? {
|
||||
let filename = (path as NSString).lastPathComponent.lowercased()
|
||||
let filenames = [
|
||||
"cmakelists.txt": "cmake", "dockerfile": "dockerfile", "gemfile": "ruby",
|
||||
"makefile": "makefile", "podfile": "ruby",
|
||||
]
|
||||
if let language = filenames[filename] { return language }
|
||||
let languages = [
|
||||
"asm": "x86asm", "c": "c", "cc": "cpp", "clj": "clojure", "cpp": "cpp",
|
||||
"cs": "csharp", "css": "css", "dart": "dart", "ex": "elixir", "exs": "elixir",
|
||||
"fs": "fsharp", "go": "go", "groovy": "groovy", "h": "cpp", "hpp": "cpp",
|
||||
"hs": "haskell", "html": "xml", "java": "java", "jl": "julia", "js": "javascript",
|
||||
"json": "json", "jsx": "javascript", "kt": "kotlin", "kts": "kotlin", "lua": "lua",
|
||||
"m": "objectivec", "md": "markdown", "mm": "objectivec", "php": "php", "pl": "perl",
|
||||
"plist": "xml", "ps1": "powershell", "py": "python", "r": "r", "rb": "ruby",
|
||||
"rs": "rust", "scala": "scala", "scss": "scss", "sh": "bash", "sql": "sql",
|
||||
"swift": "swift", "toml": "ini", "ts": "typescript", "tsx": "typescript",
|
||||
"txt": "plaintext", "xml": "xml", "yaml": "yaml", "yml": "yaml",
|
||||
]
|
||||
return languages[(path as NSString).pathExtension.lowercased()]
|
||||
}
|
||||
|
||||
func symbolText(_ symbol: String, text: String, font: UIFont, color: UIColor) -> NSAttributedString {
|
||||
let output = NSMutableAttributedString()
|
||||
if let image = UIImage(systemName: symbol)?.withTintColor(color, renderingMode: .alwaysOriginal) {
|
||||
|
||||
Reference in New Issue
Block a user