Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
66a08b6
Update build.yaml
LivingWithHippos Jan 11, 2026
38629d8
updated libraries
LivingWithHippos Jan 11, 2026
8cb75bf
added mega.nz support
LivingWithHippos Jan 11, 2026
ee47a24
removed youtube support
LivingWithHippos Jan 11, 2026
f7200be
formatted code
LivingWithHippos Jan 11, 2026
cee9d2c
fixed jvm target
LivingWithHippos Jan 11, 2026
590f5d5
fixed credentials lost on rotate
LivingWithHippos Jan 11, 2026
47fd7a5
fixed authentication view in landscape
LivingWithHippos Jan 11, 2026
702d323
formatted code
LivingWithHippos Jan 11, 2026
37cced7
tries to fix null navigation issue
LivingWithHippos Jan 11, 2026
299b60f
tries to fix more null binding crashes
LivingWithHippos Jan 11, 2026
0382377
format code
LivingWithHippos Jan 11, 2026
dde53c9
trying to fix binding crash
LivingWithHippos Jan 11, 2026
23cc796
Update proguard-rules.pro
LivingWithHippos Jan 11, 2026
703096c
ignore case il folder filter search
LivingWithHippos Feb 3, 2026
62f0d3c
Update proguard-rules.pro
LivingWithHippos Feb 3, 2026
b626b44
formatting
LivingWithHippos Feb 3, 2026
da5a53a
Update proguard-rules.pro
LivingWithHippos Feb 3, 2026
38c07af
updated dependencies
LivingWithHippos Feb 3, 2026
f8d1745
updated supported links
LivingWithHippos Feb 3, 2026
4672d2c
updated libraries
LivingWithHippos Feb 20, 2026
5b056bb
added docker compose for search services
LivingWithHippos Feb 20, 2026
ae57a8c
WIP added jackett to remote device
LivingWithHippos Feb 21, 2026
6882103
use new extension to set preferences
LivingWithHippos Feb 21, 2026
86bb2e2
Update fragment_remote_service.xml
LivingWithHippos Feb 21, 2026
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
18 changes: 12 additions & 6 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,28 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
- name: Run tests
run: ./gradlew ktfmtCheck
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
- name: Retrieve keystore for apk signing
env:
ENCODED_KEYSTORE: ${{ secrets.KEYSTORE }}
Expand All @@ -54,12 +58,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Setup
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
- name: Retrieve keystore for apk signing
env:
ENCODED_KEYSTORE: ${{ secrets.KEYSTORE }}
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,5 @@ app/app/src/main/assets/search_plugins/1337.json
app/app/src/main/assets/search_plugins/isohunt_nz.json
app/app/src/main/assets/search_plugins/zooqle.json
app/apikey.properties
/extra_assets/docker/jackett/data
/extra_assets/docker/prowlarr
3 changes: 2 additions & 1 deletion app/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ ktfmt {
kotlinLangStyle()
}

kotlin { jvmToolchain(11) }

android {
namespace = "com.github.livingwithhippos.unchained"
compileSdk = 36
Expand Down Expand Up @@ -134,7 +136,6 @@ android {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions { jvmTarget = "11" }
buildFeatures {
viewBinding = true
buildConfig = true
Expand Down
6 changes: 1 addition & 5 deletions app/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,12 @@
# hide the original source file name.
#-renamesourcefileattribute SourceFile

# avoid rewriting of proto datastore variables name. Remove when https://android-review.googlesource.com/c/platform/frameworks/support/+/1433465/ is available
-keep class * extends com.google.protobuf.GeneratedMessageLite {
<fields>;
}

# https://github.com/square/retrofit#r8--proguard
# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
-dontwarn com.google.re2j.**

# With R8 full mode generic signatures are stripped for classes that are not kept.
-keep,allowobfuscation,allowshrinking class retrofit2.Response
Expand Down
80 changes: 17 additions & 63 deletions app/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -273,143 +273,108 @@
<data android:host="4shared.com" />

<data android:host="alfafile.net" />
<data android:host="anzfile.net" />

<data android:host="backin.net" />
<data android:host="bayfiles.com" />
<data android:host="bdupload.in" />
<data android:host="brupload.net" />
<data android:host="btafile.com" />

<data android:host="catshare.net" />
<data android:host="clicknupload.me" />
<data android:host="clicknupload.click" />
<data android:host="clipwatching.com" />
<data android:host="cosmobox.org" />

<!-- confirmed -->
<data android:host="dailymotion.com" />
<!-- confirmed -->
<data android:host="dailyuploads.net" />
<data android:host="daofile.com" />
<data android:host="ddownload.com" />
<data android:host="ddl.to" />
<data android:host="depositfiles.com" />
<data android:host="dl.free.fr" />
<data android:host="douploads.net" />
<data android:host="drop.download" />
<data android:host="dropbox.com" />

<data android:host="earn4files.com" />
<data android:host="easybytez.com" />
<data android:host="ex-load.com" />
<data android:host="extmatrix.com" />

<data android:host="down.fast-down.com" />
<data android:host="fastclick.to" />
<data android:host="faststore.org" />
<data android:host="fikper.com" />
<data android:host="file.al" />
<data android:host="file4safe.com" />
<data android:host="fboom.me" />
<data android:host="filefactory.com" />
<data android:host="filefox.cc" />
<data android:host="filenext.com" />
<data android:host="filer.net" />
<data android:host="filerio.in" />
<data android:host="filesabc.com" />
<!-- confirmed -->
<data android:host="filespace.com" />
<data android:host="filestore.me" />
<data android:host="file-up.org" />
<data android:host="fileupload.pw" />
<data android:host="filextras.com" />
<data android:host="filezip.cc" />
<data android:host="fireget.com" />
<data android:host="flashbit.cc" />
<data android:host="flashx.tv" />
<data android:host="florenfile.com" />
<data android:host="fshare.vn" />

<data android:host="gigapeta.com" />
<data android:host="goloady.com" />
<data android:host="docs.google.com" />
<data android:host="drive.google.com" />
<data android:host="gounlimited.to" />

<data android:host="heroupload.com" />
<data android:host="hexupload.net" />
<data android:host="hexload.net" />
<!-- confirmed -->
<data android:host="hitfile.net" />
<!-- confirmed -->
<data android:host="htfl.net" />
<data android:host="hotlink.cc" />
<!-- confirmed -->
<data android:host="hulkshare.com" />

<data android:host="icerbox.com" />
<data android:host="icloud.com" />
<data android:host="inclouddrive.com" />
<data android:host="isra.cloud" />

<data android:host="katfile.cloud" />
<data android:host="katfile.com" />
<data android:host="keep2share.cc" />

<data android:host="letsupload.cc" />
<data android:host="load.to" />

<data android:host="down.mdiaload.com" />
<data android:host="mediafire.com" />
<data android:host="mega.nz" />
<data android:host="mega.co.nz" />
<data android:host="mixdrop.co" />
<data android:host="mixloads.com" />
<data android:host="mp4upload.com" />

<data android:host="nelion.me" />
<data android:host="ninjastream.to" />
<data android:host="nitroflare.com" />
<data android:host="nowvideo.club" />

<data android:host="oboom.com" />

<data android:host="prefiles.com" />

<!-- confirmed -->
<data android:host="radiotunes.com" />
<data android:host="rapidgator.net" />
<data android:host="rapidrar.com" />
<data android:host="rapidu.net" />
<data android:host="rarefile.net" />
<data android:host="redbunker.net" />
<data android:host="rockfile.eu" />
<!-- confirmed -->
<data android:host="rutube.ru" />

<data android:host="sky.fm" />
<data android:host="scribd.com" />
<data android:host="send.cm" />
<data android:host="sendit.cloud" />
<!-- confirmed -->
<data android:host="send.now" />
<data android:host="sendspace.com" />
<data android:host="simfileshare.net" />
<data android:host="solidfiles.com" />
<data android:host="soundcloud.com" />
<data android:host="speed-down.org" />
<data android:host="streamon.to" />
<data android:host="streamtape.com" />

<data android:host="takefile.link" />
<data android:host="terabytez.org" />
<data android:host="tezfiles.com" />
<data android:host="thevideo.me" />
<data android:host="turbobit.net" />
<data android:host="tusfiles.com" />
<!-- confirmed -->
<data android:host="trbt.cc" />

<data android:host="ubiqfile.com" />
<data android:host="uloz.to" />
<data android:host="unibytes.com" />
<data android:host="uploadbox.io" />
<data android:host="uploadboy.com" />
<data android:host="uploadc.com" />
<data android:host="uploadev.org" />
<data android:host="uploadgig.com" />
<data android:host="uploadrar.com" />
<data android:host="uploady.io" />
<data android:host="uppit.com" />
<data android:host="upstore.net" />
<data android:host="upstream.to" />
<data android:host="uptobox.com" />
<data android:host="userscloud.com" />
<data android:host="usersdrive.com" />

<data android:host="vidcloud.ru" />
<data android:host="videobin.co" />
Expand All @@ -420,19 +385,8 @@
<data android:host="vk.com" />
<data android:host="voe.sx" />

<data android:host="wdupload.com" />
<data android:host="wipfiles.net" />
<data android:host="world-files.com" />
<data android:host="worldbytez.com" />
<data android:host="wupfile.com" />
<data android:host="wushare.com" />
<data android:host="xubster.com" />

<data android:host="www.youtube.com" />
<data android:host="youtu.be" />
<data android:host="youtube.com" />

<data android:host="zippyshare.com" />
</intent-filter>
</activity>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,12 @@ class AuthenticationFragment : UnchainedFragment() {
val action = AuthenticationFragmentDirections.actionAuthenticationToUser()
findNavController().navigate(action)
}

FSMAuthenticationState.AuthenticatedPrivateToken -> {
val action = AuthenticationFragmentDirections.actionAuthenticationToUser()
findNavController().navigate(action)
}

FSMAuthenticationState.StartNewLogin -> {
// reset the current data
// token == null
Expand All @@ -125,21 +127,26 @@ class AuthenticationFragment : UnchainedFragment() {
// get the authentication link to start the process
viewModel.fetchAuthenticationInfo()
}

FSMAuthenticationState.WaitingUserConfirmation -> {
// start the next auth step
viewModel.fetchSecrets()
}

FSMAuthenticationState.WaitingToken -> {
viewModel.fetchToken()
}

FSMAuthenticationState.CheckCredentials,
FSMAuthenticationState.RefreshingOpenToken -> {
// managed by activity
}

is FSMAuthenticationState.WaitingUserAction -> {
// todo: depending on the action required show an error or restart the
// process
}

FSMAuthenticationState.Start -> {
// this shouldn't happen
}
Expand All @@ -148,28 +155,30 @@ class AuthenticationFragment : UnchainedFragment() {
}

// 1. start checking for the auth link
viewModel.authLiveData.observe(
viewLifecycleOwner,
EventObserver { auth ->
if (auth != null) {
binding.tvAuthenticationLink.text = auth.verificationUrl
binding.tvAuthenticationLink.visibility = View.VISIBLE
binding.cbLink.isChecked = true
binding.cbLink.text = getString(R.string.link_loaded)
// let the user copy the user code to enter in the website
binding.tvUserCodeValue.text = auth.userCode
binding.bCopyLink.isEnabled = true
// update the currently saved credentials
activityViewModel.updateCredentialsDeviceCode(auth.deviceCode)
// transition state machine
viewModel.authLiveData.observe(viewLifecycleOwner) { event ->
event?.peekContent()?.let { auth ->
binding.tvAuthenticationLink.text = auth.verificationUrl
binding.tvAuthenticationLink.visibility = View.VISIBLE
binding.cbLink.isChecked = true
binding.cbLink.text = getString(R.string.link_loaded)
// let the user copy the user code to enter in the website
binding.tvUserCodeValue.text = auth.userCode
binding.bCopyLink.isEnabled = true
// update the currently saved credentials
activityViewModel.updateCredentialsDeviceCode(auth.deviceCode)
// transition state machine
if (
activityViewModel.getAuthenticationMachineState()
is FSMAuthenticationState.StartNewLogin
) {
activityViewModel.transitionAuthenticationMachine(
FSMAuthenticationEvent.OnAuthLoaded
)
// set up values for calling the secrets endpoint
viewModel.setupSecretLoop(auth.expiresIn)
}
},
)
}
}

// 2. start checking for user confirmation
viewModel.secretLiveData.observe(
Expand All @@ -186,12 +195,14 @@ class AuthenticationFragment : UnchainedFragment() {
FSMAuthenticationEvent.OnUserConfirmationMissing
)
}

SecretResult.Expired -> {
// will restart the authentication process
activityViewModel.transitionAuthenticationMachine(
FSMAuthenticationEvent.OnUserConfirmationExpired
)
}

is SecretResult.Retrieved -> {
if (
activityViewModel.getAuthenticationMachineState()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,8 @@ constructor(
* secrets endpoint
*/
fun setupSecretLoop(expiresIn: Int) {
// this is just an estimate, keeping track of time would be more precise. As of now this
// value
// should be 120
// this is just an estimate, keeping track of time would be more precise.
// As of now this value should be 120
var calls = (expiresIn * 1000 / SECRET_CALLS_DELAY).toInt() - 10
// remove 10% of the calls to account for the api calls
calls -= calls / 10
Expand Down
Loading