Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da1e7a180c
|
||
|
|
57eae9f643
|
||
|
|
0da26e0fed
|
||
|
|
6ffba3be02
|
||
|
|
187f2eaa25
|
||
|
|
3fadd008f4
|
||
|
|
410049d161
|
||
|
|
5301187413
|
||
|
|
fe275ac17c
|
@@ -1,3 +1,6 @@
|
||||
[submodule "docs/reference/outline-openapi"]
|
||||
path = docs/reference/outline-openapi
|
||||
url = https://github.com/outline/openapi.git
|
||||
[submodule "Vendor/swift-markdown-engine"]
|
||||
path = Vendor/swift-markdown-engine
|
||||
url = https://github.com/nodes-app/swift-markdown-engine.git
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
FA7596B230366A1D0000167E /* MarkdownEngine in Frameworks */ = {isa = PBXBuildFile; productRef = FA7596B130366A1D0000167E /* MarkdownEngine */; };
|
||||
FA7596B430366A1D0000167E /* MarkdownEngineCodeBlocks in Frameworks */ = {isa = PBXBuildFile; productRef = FA7596B330366A1D0000167E /* MarkdownEngineCodeBlocks */; };
|
||||
FA7596B630366A1D0000167E /* MarkdownEngineLatex in Frameworks */ = {isa = PBXBuildFile; productRef = FA7596B530366A1D0000167E /* MarkdownEngineLatex */; };
|
||||
FAF99C44302CF1BD00C9949F /* OutlineKit in Frameworks */ = {isa = PBXBuildFile; productRef = FAF99C43302CF1BD00C9949F /* OutlineKit */; };
|
||||
FAF99CAF302D120500C9949F /* MarkdownEngine in Frameworks */ = {isa = PBXBuildFile; productRef = FAF99CAE302D120500C9949F /* MarkdownEngine */; };
|
||||
FAF99CB1302D120500C9949F /* MarkdownEngineCodeBlocks in Frameworks */ = {isa = PBXBuildFile; productRef = FAF99CB0302D120500C9949F /* MarkdownEngineCodeBlocks */; };
|
||||
FAF99CB3302D120500C9949F /* MarkdownEngineLatex in Frameworks */ = {isa = PBXBuildFile; productRef = FAF99CB2302D120500C9949F /* MarkdownEngineLatex */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -59,9 +59,9 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
files = (
|
||||
FAF99C44302CF1BD00C9949F /* OutlineKit in Frameworks */,
|
||||
FAF99CB1302D120500C9949F /* MarkdownEngineCodeBlocks in Frameworks */,
|
||||
FAF99CB3302D120500C9949F /* MarkdownEngineLatex in Frameworks */,
|
||||
FAF99CAF302D120500C9949F /* MarkdownEngine in Frameworks */,
|
||||
FA7596B430366A1D0000167E /* MarkdownEngineCodeBlocks in Frameworks */,
|
||||
FA7596B630366A1D0000167E /* MarkdownEngineLatex in Frameworks */,
|
||||
FA7596B230366A1D0000167E /* MarkdownEngine in Frameworks */,
|
||||
);
|
||||
};
|
||||
FAF99C24302CE96200C9949F /* Frameworks */ = {
|
||||
@@ -116,9 +116,9 @@
|
||||
name = Outpost;
|
||||
packageProductDependencies = (
|
||||
FAF99C43302CF1BD00C9949F /* OutlineKit */,
|
||||
FAF99CAE302D120500C9949F /* MarkdownEngine */,
|
||||
FAF99CB0302D120500C9949F /* MarkdownEngineCodeBlocks */,
|
||||
FAF99CB2302D120500C9949F /* MarkdownEngineLatex */,
|
||||
FA7596B130366A1D0000167E /* MarkdownEngine */,
|
||||
FA7596B330366A1D0000167E /* MarkdownEngineCodeBlocks */,
|
||||
FA7596B530366A1D0000167E /* MarkdownEngineLatex */,
|
||||
);
|
||||
productName = Outpost;
|
||||
productReference = FAF99C18302CE96100C9949F /* Outpost.app */;
|
||||
@@ -200,7 +200,7 @@
|
||||
minimizedProjectReferenceProxies = 1;
|
||||
packageReferences = (
|
||||
FAF99C42302CF1BD00C9949F /* XCLocalSwiftPackageReference "OutlineKit" */,
|
||||
FAF99CAD302D120500C9949F /* XCRemoteSwiftPackageReference "swift-markdown-engine" */,
|
||||
FA7596B030366A1D0000167E /* XCLocalSwiftPackageReference "Vendor/swift-markdown-engine" */,
|
||||
);
|
||||
preferredProjectObjectVersion = 77;
|
||||
productRefGroup = FAF99C19302CE96100C9949F /* Products */;
|
||||
@@ -622,43 +622,33 @@
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCLocalSwiftPackageReference section */
|
||||
FA7596B030366A1D0000167E /* XCLocalSwiftPackageReference "Vendor/swift-markdown-engine" */ = {
|
||||
isa = XCLocalSwiftPackageReference;
|
||||
relativePath = "Vendor/swift-markdown-engine";
|
||||
};
|
||||
FAF99C42302CF1BD00C9949F /* XCLocalSwiftPackageReference "OutlineKit" */ = {
|
||||
isa = XCLocalSwiftPackageReference;
|
||||
relativePath = OutlineKit;
|
||||
};
|
||||
/* End XCLocalSwiftPackageReference section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
FAF99CAD302D120500C9949F /* XCRemoteSwiftPackageReference "swift-markdown-engine" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/nodes-app/swift-markdown-engine";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 0.12.0;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
FA7596B130366A1D0000167E /* MarkdownEngine */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = MarkdownEngine;
|
||||
};
|
||||
FA7596B330366A1D0000167E /* MarkdownEngineCodeBlocks */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = MarkdownEngineCodeBlocks;
|
||||
};
|
||||
FA7596B530366A1D0000167E /* MarkdownEngineLatex */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = MarkdownEngineLatex;
|
||||
};
|
||||
FAF99C43302CF1BD00C9949F /* OutlineKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = OutlineKit;
|
||||
};
|
||||
FAF99CAE302D120500C9949F /* MarkdownEngine */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = FAF99CAD302D120500C9949F /* XCRemoteSwiftPackageReference "swift-markdown-engine" */;
|
||||
productName = MarkdownEngine;
|
||||
};
|
||||
FAF99CB0302D120500C9949F /* MarkdownEngineCodeBlocks */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = FAF99CAD302D120500C9949F /* XCRemoteSwiftPackageReference "swift-markdown-engine" */;
|
||||
productName = MarkdownEngineCodeBlocks;
|
||||
};
|
||||
FAF99CB2302D120500C9949F /* MarkdownEngineLatex */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = FAF99CAD302D120500C9949F /* XCRemoteSwiftPackageReference "swift-markdown-engine" */;
|
||||
productName = MarkdownEngineLatex;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
};
|
||||
rootObject = FAF99C10302CE96100C9949F /* Project object */;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"originHash" : "f233fa96f0c6bdcdbf87f726af38f25704f6d46a156a27dfac47541baa63bf97",
|
||||
"originHash" : "4127e8224149bef00a33500e8db49748a735e1c07626f2255faea52554afef5e",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "highlighterswift",
|
||||
@@ -10,15 +10,6 @@
|
||||
"version" : "3.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-markdown-engine",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/nodes-app/swift-markdown-engine",
|
||||
"state" : {
|
||||
"revision" : "e5f7607fc4021181056ef7a09dbb7573dc0237d9",
|
||||
"version" : "0.12.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swiftmath",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
import AppKit
|
||||
import SwiftUI
|
||||
|
||||
/// Bare content (icon, name, version, links) with no window chrome — reused
|
||||
/// by both the standalone "About Outpost" window (`AboutView`, the standard
|
||||
/// macOS app-menu affordance) and the Settings page's own About section, so
|
||||
/// the two can't drift out of sync.
|
||||
/// Bare content (icon, name, version, links) with no window chrome — the
|
||||
/// macOS "About Outpost" app-menu command now opens Settings' own About
|
||||
/// section directly (no separate popup window), so this is its only caller.
|
||||
struct AboutInfoView: View {
|
||||
private let repositoryURL = URL(string: "https://git.psmattas.com/psmattas/Outpost")!
|
||||
private let releasesURL = URL(string: "https://git.psmattas.com/psmattas/Outpost/releases")!
|
||||
|
||||
var appName: String {
|
||||
Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String ?? "Outpost"
|
||||
@@ -45,35 +43,15 @@ struct AboutInfoView: View {
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
VStack(spacing: 10) {
|
||||
Link(destination: repositoryURL) {
|
||||
Label("View Source on Git", systemImage: "link")
|
||||
}
|
||||
.font(.callout)
|
||||
|
||||
Button("Check for Updates…") {
|
||||
checkForUpdates()
|
||||
}
|
||||
}
|
||||
|
||||
Text("© \(copyrightYear) Puranjay Savar Mattas")
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.tertiary)
|
||||
}
|
||||
}
|
||||
|
||||
// No Sparkle-style in-app updater yet — this just opens the releases page
|
||||
// on the self-hosted Gitea instance so the user can check/download manually.
|
||||
private func checkForUpdates() {
|
||||
NSWorkspace.shared.open(releasesURL)
|
||||
}
|
||||
}
|
||||
|
||||
struct AboutView: View {
|
||||
var body: some View {
|
||||
AboutInfoView()
|
||||
.padding(32)
|
||||
.frame(width: 320)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,6 @@ struct OutpostApp: App {
|
||||
@AppStorage("outpost.appearance") private var appearance: AppAppearance = .system
|
||||
|
||||
#if os(macOS)
|
||||
@Environment(\.openWindow) private var openWindow
|
||||
@State private var isShowingLogoutConfirmation = false
|
||||
#endif
|
||||
|
||||
@@ -40,7 +39,8 @@ struct OutpostApp: App {
|
||||
.commands {
|
||||
CommandGroup(replacing: .appInfo) {
|
||||
Button("About Outpost") {
|
||||
openWindow(id: "about")
|
||||
navigation.selectedSettingsSection = .about
|
||||
navigation.isShowingSettings = true
|
||||
}
|
||||
}
|
||||
// No `Settings {}` scene anymore — Settings renders inside the
|
||||
@@ -64,12 +64,6 @@ struct OutpostApp: App {
|
||||
#endif
|
||||
|
||||
#if os(macOS)
|
||||
Window("About Outpost", id: "about") {
|
||||
AboutView()
|
||||
.disablesFullScreen()
|
||||
}
|
||||
.windowResizability(.contentSize)
|
||||
|
||||
Window("Keyboard Shortcuts", id: "keyboard-shortcuts") {
|
||||
KeyboardShortcutsView()
|
||||
.disablesFullScreen()
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
# Outpost
|
||||
<p align="center">
|
||||
<img src="Outpost/Assets.xcassets/AppLogo.imageset/outpost-ios-1024.png" width="120" alt="Outpost logo">
|
||||
</p>
|
||||
|
||||
<h1 align="center">Outpost</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://testflight.apple.com/join/y1mYcYAM">
|
||||
<img src="https://img.shields.io/badge/Download-TestFlight-0D96F6?style=for-the-badge&logo=apple&logoColor=white" alt="Download on TestFlight">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
A native Apple ecosystem client for [Outline](https://github.com/outline/outline) — built for iOS, iPadOS, and macOS from a single SwiftUI codebase, aiming for full editing parity with Outline's web app, including realtime collaborative editing.
|
||||
|
||||
> **Early alpha — macOS only for now.** Expect missing features and rough edges. iOS/iPadOS support is planned but not in the current build. See the [releases page](https://git.psmattas.com/psmattas/Outpost/releases) for changelogs, and [open an issue](https://git.psmattas.com/psmattas/Outpost/issues) if you hit anything.
|
||||
|
||||
## Why
|
||||
|
||||
Outline's web app is great, but there's no native Apple client with full editing parity. This project connects to a self-hosted Outline instance over its REST API and realtime collaboration socket to provide a proper native experience across the Apple ecosystem.
|
||||
|
||||
## Status
|
||||
|
||||
Early development. See `CLAUDE.md` for the current architecture and phased build plan.
|
||||
|
||||
- [ ] Phase 1 — Auth, browse, search, REST-only editing
|
||||
- [ ] Phase 2 — Realtime collaborative editing (Yjs/Hocuspocus)
|
||||
- [ ] Phase 3 — Offline cache, tables, embeds, comments, macOS polish
|
||||
|
||||
## Requirements
|
||||
|
||||
- Xcode 16+
|
||||
- iOS 17+ / iPadOS 17+ / macOS 14+
|
||||
- Xcode 27+ (currently developed against an Xcode 27 beta — this is a hard minimum, not a suggestion)
|
||||
- macOS 27+. iOS/iPadOS support is planned but not in the current build (see the alpha note above) — same 27+ minimum will apply once it lands
|
||||
- A self-hosted (or hosted) Outline instance with API access
|
||||
|
||||
> They will be updated. These are old requirements.
|
||||
|
||||
## Setup
|
||||
|
||||
1. Clone the repo and open the `.xcodeproj` in Xcode.
|
||||
@@ -42,6 +44,16 @@ Parts of this codebase are AI-assisted (built with the help of AI coding tools).
|
||||
|
||||
This project is a client only — it does not include, vendor, or redistribute any of Outline's (BSL 1.1 licensed) server source. See [`LICENSE`](./LICENSE) for this repository's own license.
|
||||
|
||||
## Privacy
|
||||
|
||||
Outpost collects nothing about you — no analytics, no telemetry, no crash reporting of its own, no age or demographic data, nothing. The only thing stored locally is your Outline server URL and API token (in the device Keychain) and, optionally, a local offline cache of what you've viewed. Everything else goes straight from your device to whatever Outline server you configure — there's no backend in between, and the developer has no access to your data or your server.
|
||||
|
||||
Full policy, terms of service, and data-processing statement are on the [wiki](https://git.psmattas.com/psmattas/Outpost/wiki):
|
||||
|
||||
- [Privacy Policy](https://git.psmattas.com/psmattas/Outpost/wiki/Privacy-Policy.-)
|
||||
- [Terms of Service](https://git.psmattas.com/psmattas/Outpost/wiki/Terms-of-Service.-)
|
||||
- [Data Processing Statement](https://git.psmattas.com/psmattas/Outpost/wiki/Data-Processing-Statement.-)
|
||||
|
||||
## Not affiliated with Outline
|
||||
|
||||
This is an independent, unofficial client. Not affiliated with or endorsed by General Outline, Inc.
|
||||
|
||||
+1
Submodule Vendor/swift-markdown-engine added at 05c1720f44
Reference in New Issue
Block a user