Skip to content

Commit

Permalink
Merge pull request #30 from opatry/website-project-prez
Browse files Browse the repository at this point in the history
Website project presentation (closes #21)
  • Loading branch information
opatry authored Sep 30, 2024
2 parents e8b39b7 + ee940ed commit 11db8bf
Show file tree
Hide file tree
Showing 13 changed files with 447 additions and 9 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/deploy-website.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: 🌎 Deploy Website

on:
workflow_dispatch:

permissions:
contents: write
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build:

environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1

# allows Bundler gem installation (used for fastlane gem)
- name: 💎 Setup Ruby 3.0
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.0

- name: 🐙 Setup Github Pages
uses: actions/configure-pages@v5

- name: 🧪 Build with Jekyll
run: |
gem install bundler
bundle config set --local path .bundler
bundle install --jobs "$(nproc)"
cd website
bundle exec jekyll build
- name: 🚀 Deploy
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: website/_site

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ client_secret_*.apps.googleusercontent.com.json
_ci/*.keystore
_ci/api-*.json
bundletool-*.jar

_site/
9 changes: 8 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,11 @@

source 'https://rubygems.org'

gem 'fastlane'
gem 'fastlane', '~> 2.223.0'

gem 'jekyll', '~> 3.10.0'

# Jekyll theme
gem 'jekyll-theme-basically-basic'

gem 'kramdown-parser-gfm'
77 changes: 74 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,23 @@ GEM
babosa (1.0.4)
base64 (0.2.0)
claide (1.1.0)
colorator (1.1.0)
colored (1.2)
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
concurrent-ruby (1.3.4)
csv (3.3.0)
declarative (0.0.20)
digest-crc (0.6.5)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.6.20240107)
dotenv (2.8.1)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
emoji_regex (3.2.3)
eventmachine (1.2.7)
excon (0.111.0)
faraday (1.10.4)
faraday-em_http (~> 1.0)
Expand Down Expand Up @@ -109,6 +116,10 @@ GEM
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
ffi (1.17.0)
ffi (1.17.0-arm64-darwin)
ffi (1.17.0-x86_64-darwin)
forwardable-extended (2.6.0)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.54.0)
google-apis-core (>= 0.11.0, < 2.a)
Expand Down Expand Up @@ -149,11 +160,55 @@ GEM
highline (2.0.3)
http-cookie (1.0.7)
domain_name (~> 0.5)
http_parser.rb (0.8.0)
httpclient (2.8.3)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
jekyll (3.10.0)
addressable (~> 2.4)
colorator (~> 1.0)
csv (~> 3.0)
em-websocket (~> 0.5)
i18n (>= 0.7, < 2)
jekyll-sass-converter (~> 1.0)
jekyll-watch (~> 2.0)
kramdown (>= 1.17, < 3)
liquid (~> 4.0)
mercenary (~> 0.3.3)
pathutil (~> 0.9)
rouge (>= 1.7, < 4)
safe_yaml (~> 1.0)
webrick (>= 1.0)
jekyll-feed (0.17.0)
jekyll (>= 3.7, < 5.0)
jekyll-paginate (1.1.0)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-seo-tag (2.8.0)
jekyll (>= 3.8, < 5.0)
jekyll-sitemap (1.4.0)
jekyll (>= 3.7, < 5.0)
jekyll-theme-basically-basic (1.4.5)
jekyll (>= 3.6, < 5.0)
jekyll-feed (~> 0.1)
jekyll-paginate (~> 1.1)
jekyll-seo-tag (~> 2.6)
jekyll-sitemap (~> 1.3)
jekyll-watch (2.2.1)
listen (~> 3.0)
jmespath (1.6.2)
json (2.7.2)
jwt (2.9.1)
base64
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.4)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_magick (4.13.2)
mini_mime (1.1.5)
multi_json (1.15.0)
Expand All @@ -163,9 +218,14 @@ GEM
nkf (0.2.0)
optparse (0.5.0)
os (1.1.4)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
plist (3.7.1)
public_suffix (6.0.1)
rake (13.2.1)
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
Expand All @@ -175,6 +235,12 @@ GEM
rouge (2.0.7)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
safe_yaml (1.0.5)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
security (0.1.5)
signet (0.19.0)
addressable (~> 2.8)
Expand All @@ -194,6 +260,7 @@ GEM
tty-cursor (~> 0.7)
uber (0.1.0)
unicode-display_width (2.6.0)
webrick (1.8.2)
word_wrap (1.0.0)
xcodeproj (1.25.0)
CFPropertyList (>= 2.3.3, < 4.0)
Expand All @@ -208,11 +275,15 @@ GEM
xcpretty (~> 0.2, >= 0.0.7)

PLATFORMS
arm64-darwin-22
arm64-darwin
ruby
x86_64-darwin

DEPENDENCIES
fastlane
fastlane (~> 2.223.0)
jekyll (~> 3.10.0)
jekyll-theme-basically-basic
kramdown-parser-gfm

BUNDLED WITH
2.5.5
2.5.20
80 changes: 75 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,94 @@

[**Taskfolio**](https://opatry.github.io/taskfolio) is an Android task management app built using [Google Tasks API](https://developers.google.com/tasks/reference/rest). Developed to demonstrate my expertise in modern Android development, it highlights my skills in architecture, UI design with Jetpack Compose, OAuth authentication, and more—all packaged in a sleek, user-friendly interface.

> I set out to revisit the classical TODO app, ‘local-first’ syncing with Google Tasks—aiming for an <abbr title="Minimum Viable Experience">MVE</abbr> in 2 weeks, focusing on the 80/20 rule to nail the essentials.
| ![](assets/screens/task_lists_light.png) | ![](assets/screens/groceries_light.png) | ![](assets/screens/home_dark.png) |
| --------------------------------------- |--------------------------------------- | ---------------------------------- |

[![Taskfolio on Play Store](assets/GetItOnGooglePlay_Badge_Web_color_English.png)](https://play.google.com/store/apps/details?id=net.opatry.tasks.app)

## Tech stack
## 🎯 Project intentions

- [x] Showcase my expertise in Android application development
- [x] Demonstrate UI development using Jetpack Compose with Material Design 3.
- [x] Include local-first capabilities for local data storage using Room.
- [x] OAuth 2.0 authentication.
- [x] Provide sync capabilities with Google Tasks for seamless task management.
- [x] Illustrate my ability to set up CI/CD pipelines and publish apps to the Play Store.

## ❌ Out of scope

This project is not intended as a comprehensive task manager for public use.
I do not aim to implement advanced features beyond what is supported by the Google Tasks REST API.
- no starred task
- no task priority
- only due date, no custom time support
- no task recurrence
- limited hierarchy (2 levels)

## 🚧 Known Limitations

- Authentication flow isn't 100% reliable yet.
- Local-first support with Google Tasks sync is limited, in particular sorting & conflict management is barely implemented.
- Task deletion undo is not implemented
- Very limited move capabilities
- can't move task from one list to another
- can't indent/unindent
- can't create sub-task
- no drag'n'drop
- Task list ordering isn't supported (there is no API for that in the Google Tasks API)

## 🛠️ Tech stack

- [Kotlin](https://kotlinlang.org/), [Multiplatform (KMP)](https://kotlinlang.org/docs/multiplatform.html) (currently Desktop & Android are supported)
- iOS & Web are not planned any time soon (contribution are welcome 🤝)
- [Kotlin coroutines](https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html)
- [Kotlin multiplatform](https://kotlinlang.org/docs/multiplatform.html) (aka KMP)
- [Ktor client](https://ktor.io/) (+ [Kotlinx serialization](https://kotlinlang.org/docs/serialization.html))
- [Room](https://developer.android.com/training/data-storage/room)
- [Room](https://developer.android.com/training/data-storage/room) (local persistance)
- [Koin](https://insert-koin.io/) for dependency injection
- [Material Design Components](https://developer.android.com/develop/ui/compose/designsystems/material3)
- [Jetpack Compose](https://developer.android.com/jetpack/compose)
- Kinda follows [Google architecture guidelines](https://developer.android.com/topic/architecture)
- [Coil](https://coil-kt.github.io/coil/)

## Local development
- [GitHub Actions](https://docs.github.com/en/actions) for CI
- build Android & Desktop apps
- run tests
- publish app on Play Store
- publish companion website on [Github pages](https://pages.github.com/)

## 🗺️ Project breakdown

- `:google`
- [`:oauth`](google/oauth/) <span style="color: #00FF00;">■■■■■■■■■■</span> 100%
- [Google OAuth2](https://developers.google.com/identity/protocols/oauth2) authentication with Kotlin & Ktor
- KMP
- [`:tasks`](google/tasks) <span style="color: #00FF00;">■■■■■■■■■■</span> 100%
- [Google Tasks REST API](https://developers.google.com/tasks/reference/rest) bindings for Kotlin using Ktor HTTP client
- KMP
- [`:lucide-icons`](lucide-icons) <span style="color: #00FF00;">■■■■■■■■■■</span> 100%
- [Lucide Icons](https://lucide.dev/icons/) for Compose
- Made from [Compose Icons](https://composeicons.com/icon-libraries/lucide) (not using the direct Gradle dependency to tweak stroke width)
- Only integrates what seem relevant for the app needs
- KMP
- [`:tasks-core`](tasks-core) <span style="color: #CCFF00;">■■■■■■</span>□□□□ 60%
- Taskfolio business logic
- Local first with Room database, sync with Google Tasks
- KMP
- [`:tasks-app-shared`](tasks-app-shared) <span style="color: #99FF00;">■■■■■■■</span>□□□ 70%
- All screens & UI components integrating the `:tasks-core` business logic
in Compose
- KMP
- [`:tasks-app-desktop`](tasks-app-desktop) <span style="color: #33FF00;">■■■■■■■■■</span>□ 90%
- The Desktop application (thin layer fully reusing `:tasks-app-shared`)
- [`:tasks-app-android`](tasks-app-android) <span style="color: #66FF00;">■■■■■■■■</span>□□ 80%
- The Android application (thin layer fully reusing `:tasks-app-shared`)
- [`website/`](website) <span style="color: #FF6600;">■■</span>□□□□□□□□ 20%
- The [static site](https://opatry.github.io/taskfolio/) presenting the project
- Made with [Jekyll](https://jekyllrb.com/) and served by [Github pages](https://pages.github.com/)

## 🧑‍💻 Local development

<details>
<summary>See details…</summary>
Expand All @@ -39,7 +109,7 @@ and store this in `_ci/google-services.json.gpg`.
The `decrypt_secrets.sh` will take it into account.
</details>

## License
## ⚖️ License

```
The MIT License (MIT)
Expand Down
3 changes: 3 additions & 0 deletions website/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
_site
.sass-cache
.jekyll-metadata
24 changes: 24 additions & 0 deletions website/404.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
layout: default
---

<style type="text/css" media="screen">
.container {
margin: 10px auto;
max-width: 600px;
text-align: center;
}
h1 {
margin: 30px 0;
font-size: 4em;
line-height: 1;
letter-spacing: -1px;
}
</style>

<div class="container">
<h1>404</h1>

<p><strong>Page not found :(</strong></p>
<p>The requested page could not be found.</p>
</div>
13 changes: 13 additions & 0 deletions website/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
title: Taskfolio
email: [email protected]
description: >-
Taskfolio is an Android task management app built using Google Tasks API.
Developed to demonstrate my expertise in modern Android development, it highlights my skills in architecture,
UI design with Jetpack Compose, OAuth authentication, and more—all packaged in a sleek, user-friendly interface.
baseurl: '/taskfolio'
url: 'https://opatry.github.io'
twitter_username: o_patry
github_username: opatry

markdown: kramdown
theme: jekyll-theme-basically-basic
Loading

0 comments on commit 11db8bf

Please sign in to comment.