Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Thanks for your interest. This repository is a release mirror, which changes the

## Before you open a PR

- Toolchain: Flutter 3.47.2 / Dart 3.13.2.
- Toolchain: Flutter 3.47.5 / Dart 3.13.4.
- Run the same gates CI runs:

```bash
Expand All @@ -28,3 +28,5 @@ flutter test
## Attribution and license

Your name and email, taken from your git commits, are preserved as the author when the maintainer applies your change privately and again when it reappears here in the next sync. By contributing you agree that your contribution is licensed under AGPL-3.0, the same license as the project.

Add yourself to [CONTRIBUTORS.md](CONTRIBUTORS.md) in your first PR.
10 changes: 10 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Contributors

People who have contributed code to Spectrum Pit, in the private repo or on
this mirror.

- Allen Gregory <allengregoryiv@gmail.com>
- project516 <project516@project516.dev>
- Spectrum3847 <spectrum3847@gmail.com>

Add yourself here in your first pull request.
661 changes: 661 additions & 0 deletions LICENSES/AGPL-3.0-only.txt

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ FRC pit logistics for Spectrum 3847. One app that keeps the team running at an e
- **Inventory**: every tool and part, where it lives in the lab or the pit, with a map of both so nothing goes missing.
- **Event packing**: the four-stage packing workflow (Packing, Staging, Loading, Ready); each item may have one optional packing photo.
- **Borrowed tools**: track what left the pit with whom, and what came back.
- **Maps**: lab and pit layout diagrams with tappable location pins linked back to inventory items.
- **Schedule**: pit staffing and load-in/load-out shifts, with conflict detection for double-booked members.

Built with Flutter for iOS, Android, and desktop (Windows, macOS, Linux).

Expand Down Expand Up @@ -56,8 +58,11 @@ This is the public mirror of Spectrum Pit. The team develops in a private reposi

Pull requests are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md). New to Git
or Flutter? [docs/setup-guide.md](docs/setup-guide.md) starts from scratch on
Windows, macOS, and Linux.
Windows, macOS, and Linux. See [CONTRIBUTORS.md](CONTRIBUTORS.md) for who has
worked on this project.

## License

[AGPL-3.0](LICENSE). If you distribute a modified version of this app, or run one as a service for others, you must make its source available under the same license.

[![REUSE status](https://api.reuse.software/badge/github.com/Spectrum3847/spectrum-pit)](https://api.reuse.software/info/github.com/Spectrum3847/spectrum-pit)
9 changes: 9 additions & 0 deletions REUSE.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version = 1
SPDX-PackageName = "spectrum-pit"
SPDX-PackageSupplier = "Organization: Spectrum 3847"
SPDX-PackageDownloadLocation = "https://github.com/Spectrum3847/spectrum-pit"

[[annotations]]
path = "**"
SPDX-FileCopyrightText = "The Spectrum Pit Contributors"
SPDX-License-Identifier = "AGPL-3.0-only"
12 changes: 12 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

<uses-permission android:name="android.permission.CAMERA" />

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

<uses-permission android:name="android.permission.INTERNET" />

<uses-feature android:name="android.hardware.camera" android:required="false" />
Expand Down Expand Up @@ -32,6 +34,16 @@
<meta-data
android:name="flutterEmbedding"
android:value="2" />

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>

<queries>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,70 @@
package org.spectrum3847.spectrumpit

import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import androidx.core.content.FileProvider
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import java.io.File

class MainActivity : FlutterActivity()
private const val APK_INSTALLER_CHANNEL = "org.spectrum3847.spectrumpit/apk_installer"

class MainActivity : FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(
flutterEngine.dartExecutor.binaryMessenger,
APK_INSTALLER_CHANNEL,
).setMethodCallHandler { call, result ->
if (call.method != "install") {
result.notImplemented()
return@setMethodCallHandler
}
val path = call.argument<String>("path")
if (path.isNullOrEmpty()) {
result.error("bad_args", "No APK path given", null)
return@setMethodCallHandler
}
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
!packageManager.canRequestPackageInstalls()
) {

startActivity(
Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).apply {
data = Uri.parse("package:$packageName")
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
},
)
result.success("permission_required")
return@setMethodCallHandler
}
installApk(path)
result.success(true)
} catch (error: ActivityNotFoundException) {
result.error("no_installer", "No package installer activity found", null)
} catch (error: IllegalArgumentException) {

result.error("bad_path", error.message, null)
}
}
}

private fun installApk(path: String) {
val uri = FileProvider.getUriForFile(
this,
"$packageName.fileprovider",
File(path),
)
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(uri, "application/vnd.android.package-archive")
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
startActivity(intent)
}
}
5 changes: 5 additions & 0 deletions android/app/src/main/res/xml/file_paths.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>

<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="update_cache" path="update/" />
</paths>
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.0-all.zip
4 changes: 2 additions & 2 deletions android/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ pluginManagement {

plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "9.4.0" apply false
id("com.android.application") version "9.4.1" apply false

id("com.google.gms.google-services") version("4.5.0") apply false

id("org.jetbrains.kotlin.android") version "2.4.10" apply false
id("org.jetbrains.kotlin.android") version "2.4.20" apply false
}

include(":app")
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ instructions for each are in [README.md](../README.md).

## Building it yourself

The toolchain is Flutter 3.47.2 / Dart 3.13.2. From a checkout:
The toolchain is Flutter 3.47.5 / Dart 3.13.4. From a checkout:

```bash
flutter pub get
Expand Down
14 changes: 9 additions & 5 deletions docs/self-hosting.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@ The central project id is a build define, so this is one flag you will pass in
step 8:

```
--dart-define=SPECTRUM_CENTRAL_PROJECT_ID=yourteam-central
--dart-define=CENTRAL_PROJECT_ID=yourteam-central
```

The callable endpoint follows it automatically, resolving to
`https://us-central1-yourteam-central.cloudfunctions.net`. If you deploy the
function outside `us-central1` or behind a custom domain, override that too
with `--dart-define=SPECTRUM_CENTRAL_FUNCTIONS_BASE_URL=...`. It has to be
with `--dart-define=CENTRAL_FUNCTIONS_BASE_URL=...`. It has to be
https either way, since that URL carries a bearer token.

One file still needs editing by hand: replace the values in
Expand Down Expand Up @@ -144,7 +144,11 @@ exports.getCustomToken = functions.https.onCall(async (data, context) => {
throw new functions.https.HttpsError("unauthenticated", "Sign in first.");
}
const targetApp = data && data.targetApp;
if (typeof targetApp !== "string" || targetApp.length === 0) {
if (
typeof targetApp !== "string" ||
targetApp.length === 0 ||
targetApp.includes("/")
) {
throw new functions.https.HttpsError("invalid-argument", "targetApp required.");
}

Expand Down Expand Up @@ -233,7 +237,7 @@ to sign in and says so, which is deliberate.
```
flutter run \
--dart-define=SPECTRUM_APP_KEY=yourapp \
--dart-define=SPECTRUM_CENTRAL_PROJECT_ID=yourteam-central
--dart-define=CENTRAL_PROJECT_ID=yourteam-central
```

Use the same app-key string you wrote into `apps/{key}`. Pass both defines on
Expand All @@ -247,7 +251,7 @@ console:
```
flutter build linux \
--dart-define=SPECTRUM_APP_KEY=yourapp \
--dart-define=SPECTRUM_CENTRAL_PROJECT_ID=yourteam-central \
--dart-define=CENTRAL_PROJECT_ID=yourteam-central \
--dart-define=GOOGLE_OAUTH_CLIENT_ID=...apps.googleusercontent.com \
--dart-define=GOOGLE_OAUTH_CLIENT_SECRET=...
```
Expand Down
96 changes: 10 additions & 86 deletions docs/setup-guide.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Setup guide: contributing with no prior coding experience

This guide is for someone who has never used a terminal or contributed to a
project on GitHub before. It covers Windows, macOS, and Linux, and two ways
to get the project running: installing the Flutter SDK, or using Docker or
Podman so you do not have to install anything Flutter-specific at all.
project on GitHub before. It covers Windows, macOS, and Linux, and walks
through installing the Flutter SDK the project pins so its checks run the
same way locally as they do in CI.

If you already know Git and Flutter, you probably want
[CONTRIBUTING.md](../CONTRIBUTING.md) instead.
Expand Down Expand Up @@ -52,44 +52,18 @@ tells you what to run and check; you can run the terminal commands from
Desktop Plus's own terminal view, or from your OS terminal, whichever you
find easier.

## Two ways to run the project's checks
## Running the project's checks

Before you open a pull request, three checks need to pass. There are two ways
to get them running, and you only need one:
Before you open a pull request, three checks need to pass: format, analyze,
and test. Installing the Flutter SDK below also gives you `flutter run`, so
you can see the app itself, not just the checks.

1. **Install the Flutter SDK.** This gives you `flutter run` too, so you can
see the app itself, not just the checks.
2. **Use Docker or Podman.** The project ships a script,
[`scripts/docker-test.sh`](../scripts/docker-test.sh), that runs the
checks inside a container with Flutter already installed. Nothing
Flutter-specific touches your computer. This is the faster path if you
only want to fix a bug or docs and do not plan to run the app itself.

The script looks for a command literally named `docker`. Docker Desktop
provides that. If you installed Podman instead and it did not set up a
`docker` alias for you, either install your distribution's
`podman-docker` package (it makes `docker` point at `podman`), or skip
the script and run the equivalent command directly:

```
podman run --rm -v "$PWD":/app:Z -v flutter_pubcache:/root/.pub-cache \
-w /app ghcr.io/project516/flutter:3.47.2 \
bash -c "flutter pub get && dart format --output=none --set-exit-if-changed . \
&& flutter analyze --fatal-infos && flutter test"
```

Use that image rather than `ghcr.io/cirruslabs/flutter:stable`, which a lot
of Flutter guides still recommend. Cirrus Labs stopped publishing in May
2026, so its `stable` is frozen at Flutter 3.44.0 and cannot resolve this
project's SDK constraint. The named volume is a cache, so the second run is
much faster than the first.

The project pins Flutter 3.47.2 and Dart 3.13.2.
The project pins Flutter 3.47.5 and Dart 3.13.4. Install that version (not
whatever your OS package manager offers by default) so `dart format`'s output
matches what CI expects.

## Windows

### Option A: install Flutter

1. Install [Git for Windows](https://git-scm.com/download/win) if you do not
already have Git (Desktop Plus needs it, or you can use Git Bash directly).
2. Follow the official [Flutter install guide for
Expand All @@ -108,23 +82,8 @@ The project pins Flutter 3.47.2 and Dart 3.13.2.
flutter test
```

### Option B: Docker or Podman, no Flutter install

1. Install [Docker Desktop](https://www.docker.com/products/docker-desktop/)
for Windows, or [Podman](https://podman.io/docs/installation) if you
prefer it.
2. Clone the repository.
3. `scripts/docker-test.sh` is a bash script. Run it from Git Bash (installed
alongside Git for Windows) or from WSL:

```
./scripts/docker-test.sh
```

## macOS

### Option A: install Flutter

1. Install [Homebrew](https://brew.sh/) if you do not have it, then follow
the official [Flutter install guide for
macOS](https://docs.flutter.dev/get-started/install/macos).
Expand All @@ -139,21 +98,8 @@ The project pins Flutter 3.47.2 and Dart 3.13.2.
flutter test
```

### Option B: Docker or Podman, no Flutter install

1. Install [Docker Desktop](https://www.docker.com/products/docker-desktop/)
for Mac, or Podman (`brew install podman`, then `podman machine init &&
podman machine start`).
2. Clone the repository, open Terminal in that folder, and run:

```
./scripts/docker-test.sh
```

## Linux

### Option A: install Flutter

1. Follow the official [Flutter install guide for
Linux](https://docs.flutter.dev/get-started/install/linux).
2. Run `flutter doctor`. A missing Android toolchain is fine for the checks
Expand All @@ -167,20 +113,6 @@ The project pins Flutter 3.47.2 and Dart 3.13.2.
flutter test
```

### Option B: Docker or Podman, no Flutter install

1. Install Docker or Podman through your distribution's package manager
(for example `sudo apt install podman` on Debian/Ubuntu, or see the
[Podman install docs](https://podman.io/docs/installation) for others).
2. Clone the repository and run:

```
./scripts/docker-test.sh
```

Set `FLUTTER_DOCKER_IMAGE` first if you want to pin a specific Flutter
image tag instead of the default.

## What the checks mean

- `dart format --output=none --set-exit-if-changed .` checks that your code
Expand Down Expand Up @@ -218,11 +150,3 @@ before you push. Running them first just saves a round trip.
- `master` is the default branch; branch off it and target it.
- See [CONTRIBUTING.md](../CONTRIBUTING.md) for the rest, including the
license terms your contribution is made under.

## Further reading

Two videos the maintainer found useful, linked here as optional background,
not specific to this repository:

- ["You're reading way too much code"](https://www.youtube.com/watch?v=434cG4g5KLE)
- ["Claude Code's creator has some really good advice"](https://www.youtube.com/watch?v=xmGY276gEFY)
Loading
Loading