1
0
mirror of https://github.com/AllanWang/Frost-for-Facebook.git synced 2024-09-16 20:12:25 +02:00

Merge branch 'dev' of github.com:AllanWang/Frost-for-Facebook into dev

This commit is contained in:
Allan Wang 2023-12-14 21:30:49 -08:00
commit 653f67b5a9
No known key found for this signature in database
GPG Key ID: C93E3F9C679D7A56
4 changed files with 92 additions and 12 deletions

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
@ -7,12 +8,13 @@
</map>
</option>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="14">
<list size="18">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
@ -27,12 +29,16 @@
<item index="11" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.Nullable" />
<item index="12" class="java.lang.String" itemvalue="io.reactivex.annotations.Nullable" />
<item index="13" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.Nullable" />
<item index="14" class="java.lang.String" itemvalue="org.jspecify.nullness.Nullable" />
<item index="15" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
<item index="16" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
<item index="17" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="14">
<list size="18">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
@ -47,6 +53,10 @@
<item index="11" class="java.lang.String" itemvalue="io.reactivex.annotations.NonNull" />
<item index="12" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.NonNull" />
<item index="13" class="java.lang.String" itemvalue="lombok.NonNull" />
<item index="14" class="java.lang.String" itemvalue="org.jspecify.nullness.NonNull" />
<item index="15" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
<item index="16" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
<item index="17" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
</list>
</value>
</option>

View File

@ -1,5 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="IssueNavigationConfiguration">
<option name="links">
<list>
<IssueNavigationLink>
<option name="issueRegexp" value="\bb/(\d+)(#\w+)?\b" />
<option name="linkRegexp" value="https://buganizer.corp.google.com/issues/$1$2" />
</IssueNavigationLink>
<IssueNavigationLink>
<option name="issueRegexp" value="\b(?:BUG=|FIXED=)(\d+)\b" />
<option name="linkRegexp" value="https://buganizer.corp.google.com/issues/$1" />
</IssueNavigationLink>
<IssueNavigationLink>
<option name="issueRegexp" value="\b(?:cl/|cr/|OCL=|DIFFBASE=|ROLLBACK_OF=)(\d+)\b" />
<option name="linkRegexp" value="https://critique.corp.google.com/$1" />
</IssueNavigationLink>
<IssueNavigationLink>
<option name="issueRegexp" value="\bomg/(\d+)\b" />
<option name="linkRegexp" value="https://omg.corp.google.com/$1" />
</IssueNavigationLink>
<IssueNavigationLink>
<option name="issueRegexp" value="\b(?:go/|goto/)([^,.&lt;&gt;()&quot;\s]+(?:[.,][^,.&lt;&gt;()&quot;\s]+)*)" />
<option name="linkRegexp" value="https://goto.google.com/$1" />
</IssueNavigationLink>
<IssueNavigationLink>
<option name="issueRegexp" value="\bcs/([^\s]+[\w$])" />
<option name="linkRegexp" value="https://cs.corp.google.com/search/?q=$1" />
</IssueNavigationLink>
<IssueNavigationLink>
<option name="issueRegexp" value="(LINT\.IfChange)|(LINT\.ThenChange)" />
<option name="linkRegexp" value="https://goto.google.com/ifthisthenthatlint" />
</IssueNavigationLink>
</list>
</option>
</component>
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>

View File

@ -11,16 +11,7 @@
alt="Get it on F-Droid"
height="80">](https://f-droid.org/packages/com.pitchedapps.frost)
**This project is undergoing a full rewrite**. The latest snapshot of the old project is available at https://github.com/AllanWang/Frost-for-Facebook/tree/legacy.
While a rewrite isn't necessary to keep the project going, I wanted to take some time to learn new things, and also to support some big features:
* Views to compose. This will make things a lot more structured, and will simplify dynamic colors/themes, which I've included in my projects well before Material You.
* WebView to GeckoView. This will add support for web extensions, and provide more functionality. Admittedly, this has been a huge pain to learn, and there are things that are far easier with webviews, but I think I'm at a point where I've answered my main questions.
* Web extensions allows for actual ad blocks, and theme updates without pushing new apks
* I intend on adding notification support for friend requests, though that could have been done with the old build
The direction I'm taking Frost v4.0.0 is to simplify a lot of things, and to leverage other extensions/libraries where possible. GeckoView also makes it easier to support multi account, in case I want to extend this beyond Facebook at some point in the future.
**This project is not actively maintained**. I'm occassionally updating the code to test things out, but the latest 'usable' snapshot of the old project is available at https://github.com/AllanWang/Frost-for-Facebook/tree/legacy. Until this is updated, the dev branch is not usable.
---

45
docs/Compose.md Normal file
View File

@ -0,0 +1,45 @@
# Jetpack Compose
Below are some findings and demos for jetpack compose during my explorations in this project. As with most implementation, I believe that anything is possible. This holds true with view implementations of the design below, though we will see that compose makes some elements considerably easier.
All links to code snippets are permalinks, but feel free to view changes at HEAD in case there are updates.
## Settings
> [Settings code](https://github.com/AllanWang/Frost-for-Facebook/tree/f5b003298ee91056e86a63c1f50c25285af45c9b/app-compose/src/main/kotlin/com/pitchedapps/frost/compose/settings)
Compose does not have any settings library, but it is actually very easy to do with [material `ListItem`s](https://m3.material.io/components/lists). This would also be easy with views + recyclerviews, though it seems like it is not being planned for MDC. With list items, we simply change the trailing content to provide what we need, be it a switch, checkbox, text, color selector, etc.
<todo add demo>
For most older apps, the standard is to use android preference xmls to build layouts. There are some downsides:
1. They are primarily built to use shared preferences, which we may not use
2. Custom views require some more wrapping to integrate with preferences
3. We don't control the base layouts at all (though we can modify some via themes)
4. Material no longer supports them
By converting to our own full implementation like in the snippet above, we have full control over the layouts, can add custom ones, and have all the benefits of compose to build relations between preferences, or between pages through the nav graph.
## Animations
### Stateless Animations
Compose makes it easy to animate from one state value to another. For instance, if scale is 1.0 by default, but should be 1.5 when pressed, we simply use `animateFloatAsState` and provide the expected value. However, there are cases where we may want to start and stop at the same value. This is pretty straightforward with views (`View.animate()`, `ValueAnimator`, etc), though compose supports this too:
We can look at the [overview graph](https://developer.android.com/jetpack/compose/animation/introduction#overview) and see some more basic building blocks, including `Animation` and `Animatable`. Both of these allow for initial values + velocity. Even if the initial and target values are the same, we can include velocity (or keyframes) to keep an animation going.
You can see an example through our [shake](https://github.com/AllanWang/Frost-for-Facebook/blob/f5b003298ee91056e86a63c1f50c25285af45c9b/app-compose/src/main/kotlin/com/pitchedapps/frost/compose/effects/Shake.kt) effect. `shake()` is called on click, and shakes that happen before the animation ends will smoothly restart the effect, but from the current rotation value using spring animations.
### Drag & Drop
Dragging between two visual elements is done similarly with views and compose:
* Replicate the element being dragged, and optionally hiding the original layout
* Ensure that the drag element can be drawn across the entire draggable region
* Provide reactions to the drag element when it hovers over other elements
* Make space for the dropped element and build the new layout after the transition is complete
With compose, it is extremely easy to listen to global coordinates, and to add/alter visual elements immediately in the next frame. We simply have listeners for all offsets, and a composable that optionally draws content. The same is possible with views, but takes a bit more coordination to actually add and remove the views. For dragging specifically, compose provides helpers including `detectDragGesturesAfterLongPress`, which does most of the work needed. No need for a `SimpleOnGestureListener`.
https://github.com/AllanWang/Frost-for-Facebook/assets/6251823/0cef497c-cbdc-4597-870f-a38ef8d23b35