Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
FreshRSS-Android
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
30
Issues
30
List
Boards
Labels
Service Desk
Milestones
Merge Requests
2
Merge Requests
2
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Christophe Henry
FreshRSS-Android
Commits
e73411ba
Commit
e73411ba
authored
Mar 01, 2019
by
Christophe Henry
1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Solves
#14
and
#8
: implement auto-refresh and make notification unclosable
parent
a18b445c
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
198 additions
and
115 deletions
+198
-115
app/src/main/AndroidManifest.xml
app/src/main/AndroidManifest.xml
+20
-19
app/src/main/java/fr/chenry/android/freshrss/FreshRSSApplication.kt
...in/java/fr/chenry/android/freshrss/FreshRSSApplication.kt
+44
-5
app/src/main/java/fr/chenry/android/freshrss/RefresherService.kt
.../main/java/fr/chenry/android/freshrss/RefresherService.kt
+69
-0
app/src/main/java/fr/chenry/android/freshrss/activities/MainActivity.kt
...ava/fr/chenry/android/freshrss/activities/MainActivity.kt
+7
-3
app/src/main/java/fr/chenry/android/freshrss/components/subscriptions/MainSubscriptionFragment.kt
...hrss/components/subscriptions/MainSubscriptionFragment.kt
+3
-1
app/src/main/java/fr/chenry/android/freshrss/store/Store.kt
app/src/main/java/fr/chenry/android/freshrss/store/Store.kt
+1
-30
app/src/main/java/fr/chenry/android/freshrss/utils/KotlinExtensions.kt
...java/fr/chenry/android/freshrss/utils/KotlinExtensions.kt
+3
-0
app/src/main/java/fr/chenry/android/freshrss/utils/NotificationHelper.kt
...va/fr/chenry/android/freshrss/utils/NotificationHelper.kt
+21
-50
app/src/main/java/fr/chenry/android/freshrss/utils/Try.kt
app/src/main/java/fr/chenry/android/freshrss/utils/Try.kt
+22
-0
app/src/main/res/values/strings.xml
app/src/main/res/values/strings.xml
+8
-7
No files found.
app/src/main/AndroidManifest.xml
View file @
e73411ba
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:dist=
"http://schemas.android.com/apk/distribution"
xmlns:tools=
"http://schemas.android.com/tools"
package=
"fr.chenry.android.freshrss"
>
<!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission
android:name=
"android.permission.GET_ACCOUNTS"
/>
<uses-permission
android:name=
"android.permission.READ_PROFILE"
/>
<uses-permission
android:name=
"android.permission.READ_CONTACTS"
/>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
xmlns:dist=
"http://schemas.android.com/apk/distribution"
xmlns:tools=
"http://schemas.android.com/tools"
package=
"fr.chenry.android.freshrss"
>
<dist:module
dist:instant=
"true"
/>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<dist:module
dist:instant=
"true"
/>
<application
android:name=
"
fr.chenry.android.freshrss
.FreshRSSApplication"
android:name=
".FreshRSSApplication"
android:allowBackup=
"true"
android:icon=
"@mipmap/ic_launcher"
android:label=
"@string/app_name"
...
...
@@ -21,20 +18,24 @@
android:supportsPictureInPicture=
"false"
android:supportsRtl=
"true"
android:theme=
"@style/AppTheme"
tools:ignore=
"GoogleAppIndexingWarning"
>
<activity
android:name=
"fr.chenry.android.freshrss.activities.TestActivity"
>
</activity>
tools:ignore=
"GoogleAppIndexingWarning,UnusedAttribute"
>
<service
android:name=
".RefresherService"
android:enabled=
"true"
android:exported=
"false"
>
</service>
<activity
android:name=
".activities.TestActivity"
></activity>
<activity
android:name=
"
fr.chenry.android.freshrss
.activities.LoginActivity"
android:label=
"@string/
title_activity_login
"
>
android:name=
".activities.LoginActivity"
android:label=
"@string/
app_name
"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
<activity
android:name=
"
fr.chenry.android.freshrss
.activities.MainActivity"
android:name=
".activities.MainActivity"
android:label=
"@string/app_name"
>
</activity>
</application>
...
...
app/src/main/java/fr/chenry/android/freshrss/FreshRSSApplication.kt
View file @
e73411ba
package
fr.chenry.android.freshrss
import
android.app.Application
import
android.content.Context
import
android.content.*
import
android.os.Handler
import
android.os.IBinder
import
androidx.core.app.NotificationManagerCompat
import
androidx.core.os.postDelayed
import
com.facebook.stetho.Stetho
import
fr.chenry.android.freshrss.RefresherService.RefresherBinder
import
fr.chenry.android.freshrss.store.Store
import
fr.chenry.android.freshrss.store.database.FreshRSSDabatabase
import
fr.chenry.android.freshrss.utils.whenNotNull
import
nl.komponents.kovenant.android.startKovenant
import
nl.komponents.kovenant.android.stopKovenant
import
nl.komponents.kovenant.deferred
import
java.util.*
class
FreshRSSApplication
:
Application
()
{
private
val
refreshDelay
:
Long
get
()
=
30
var
refresherService
:
RefresherService
?
=
null
private
set
private
val
serviceConnection
=
RefresherServiceConnection
()
override
fun
onCreate
()
{
super
.
onCreate
()
startKovenant
()
// Stupid hack because Android is still not able to provide the current application application globally
// even though it is effectively a singleton...
FreshRSSApplication
.
applicationPromise
.
resolve
(
this
)
startKovenant
()
bindService
(
Intent
(
this
,
RefresherService
::
class
.
java
),
serviceConnection
,
Context
.
BIND_AUTO_CREATE
)
Store
.
debugMode
=
try
{
val
properties
=
Properties
()
properties
.
load
(
baseContext
.
assets
.
open
(
"config.properties"
))
...
...
@@ -25,9 +40,7 @@ class FreshRSSApplication: Application() {
false
}
if
(
Store
.
debugMode
)
{
Stetho
.
initializeWithDefaults
(
this
)
}
if
(
Store
.
debugMode
)
Stetho
.
initializeWithDefaults
(
this
)
}
override
fun
onTerminate
()
{
...
...
@@ -44,5 +57,31 @@ class FreshRSSApplication: Application() {
val
notificationManager
:
NotificationManagerCompat
get
()
=
NotificationManagerCompat
.
from
(
FreshRSSApplication
.
application
)
fun
getStringR
(
id
:
Int
)
=
application
.
resources
.
getString
(
id
)
}
inner
class
RefresherServiceConnection
:
ServiceConnection
{
private
val
handler
=
Handler
()
private
val
token
=
object
{}
override
fun
onServiceDisconnected
(
name
:
ComponentName
?)
{
handler
.
removeCallbacksAndMessages
(
token
)
refresherService
=
null
}
override
fun
onServiceConnected
(
name
:
ComponentName
?,
service
:
IBinder
?)
{
refresherService
=
(
service
as
RefresherBinder
).
service
postDelayedRefesh
()
}
private
fun
postDelayedRefesh
()
{
handler
.
postDelayed
(
this
@FreshRSSApplication
.
refreshDelay
*
60
*
1000
,
token
)
{
this
@FreshRSSApplication
.
refresherService
.
whenNotNull
{
it
.
refresh
()
postDelayedRefesh
()
}
}
}
}
}
\ No newline at end of file
app/src/main/java/fr/chenry/android/freshrss/RefresherService.kt
0 → 100644
View file @
e73411ba
package
fr.chenry.android.freshrss
import
android.app.Notification
import
android.app.Service
import
android.content.Intent
import
android.os.Binder
import
android.widget.RemoteViews
import
androidx.core.app.NotificationCompat
import
androidx.lifecycle.MutableLiveData
import
fr.chenry.android.freshrss.store.Store
import
fr.chenry.android.freshrss.utils.NotificationChanels
import
fr.chenry.android.freshrss.utils.NotificationHelper
import
nl.komponents.kovenant.Promise
import
nl.komponents.kovenant.all
import
nl.komponents.kovenant.functional.bind
import
nl.komponents.kovenant.ui.failUi
import
nl.komponents.kovenant.ui.successUi
class
RefresherService
:
Service
()
{
private
val
refreshingPromise
=
MutableLiveData
<
Promise
<
Unit
,
Exception
>>()
private
val
refreshNotification
=
createNotification
(
R
.
string
.
notification_refresh_title
,
R
.
string
.
notification_refresh_description
)
.
setCategory
(
Notification
.
CATEGORY_PROGRESS
)
.
build
()
private
val
failNotification
=
createNotification
(
R
.
string
.
notification_refresh_failed_title
,
R
.
string
.
notification_refresh_failed_description
)
.
setCategory
(
Notification
.
CATEGORY_ERROR
)
.
build
()
override
fun
onBind
(
intent
:
Intent
)
=
RefresherBinder
()
fun
refresh
():
Promise
<
Unit
,
Exception
>
{
if
(
refreshingPromise
.
value
!=
null
)
return
refreshingPromise
.
value
!!
this
.
startForeground
(
NotificationHelper
.
ONGOING_REFRESH_NOTIFICATION
,
refreshNotification
)
val
promise
=
Store
.
getSubscriptions
()
.
bind
{
Store
.
getUnreadCount
()}
.
bind
{
all
(
Store
.
subscriptions
.
keys
.
map
{
Store
.
getStreamContents
(
it
)},
cancelOthersOnError
=
false
)}
.
bind
{
Store
.
getUnreadItems
()}
refreshingPromise
.
postValue
(
promise
)
promise
.
always
{
refreshingPromise
.
postValue
(
null
)}
.
successUi
{
stopForeground
(
true
)}
.
failUi
{
FreshRSSApplication
.
notificationManager
.
notify
(
NotificationHelper
.
FAIL_REFRESH_NOTIFICATION
,
failNotification
)
}
return
promise
}
private
fun
createNotification
(
title
:
Int
,
text
:
Int
)
=
NotificationCompat
.
Builder
(
FreshRSSApplication
.
application
,
NotificationChanels
.
REFRESH
.
channelId
)
.
setSmallIcon
(
R
.
drawable
.
ic_rss_feed_black_24dp
)
.
setStyle
(
NotificationCompat
.
BigTextStyle
()
.
setSummaryText
(
FreshRSSApplication
.
getStringR
(
title
))
.
bigText
(
FreshRSSApplication
.
getStringR
(
text
)))
.
setPriority
(
NotificationCompat
.
PRIORITY_LOW
)
.
setShowWhen
(
false
)
.
setContentInfo
(
FreshRSSApplication
.
getStringR
(
title
))
inner
class
RefresherBinder
:
Binder
()
{
val
service
:
RefresherService
get
()
=
this
@RefresherService
}
}
app/src/main/java/fr/chenry/android/freshrss/activities/MainActivity.kt
View file @
e73411ba
...
...
@@ -4,10 +4,10 @@ import android.os.Bundle
import
android.view.MenuItem
import
androidx.appcompat.app.AppCompatActivity
import
androidx.fragment.app.Fragment
import
fr.chenry.android.freshrss.
R
import
fr.chenry.android.freshrss.
*
import
fr.chenry.android.freshrss.components.waiting.WaitingFragment
import
fr.chenry.android.freshrss.store.*
import
fr.chenry.android.freshrss.utils.
e
import
fr.chenry.android.freshrss.utils.
*
import
nl.komponents.kovenant.deferred
import
nl.komponents.kovenant.resolve
import
nl.komponents.kovenant.ui.failUi
...
...
@@ -17,7 +17,11 @@ class MainActivity: AppCompatActivity() {
private
val
deferred
=
deferred
<
Unit
,
Exception
>()
init
{
Store
.
refresh
().
successUi
{
deferred
.
resolve
()}.
failUi
(
deferred
::
reject
)
FreshRSSApplication
.
application
.
refresherService
.
whenNotNull
{
it
.
refresh
().
successUi
{
deferred
.
resolve
()}.
failUi
(
deferred
::
reject
)
}.
whenNull
{
deferred
.
reject
(
Exception
(
"${FreshRSSApplication::class.qualifiedName}: Service ${RefresherService::class.qualifiedName} not bound"
))
}
}
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
...
...
app/src/main/java/fr/chenry/android/freshrss/components/subscriptions/MainSubscriptionFragment.kt
View file @
e73411ba
...
...
@@ -6,11 +6,13 @@ import androidx.fragment.app.Fragment
import
androidx.lifecycle.LiveData
import
androidx.recyclerview.widget.LinearLayoutManager
import
androidx.recyclerview.widget.RecyclerView
import
fr.chenry.android.freshrss.FreshRSSApplication
import
fr.chenry.android.freshrss.R
import
fr.chenry.android.freshrss.store.Store
import
fr.chenry.android.freshrss.store.api.models.Subscription
import
fr.chenry.android.freshrss.store.api.models.Subscriptions
import
fr.chenry.android.freshrss.utils.getOrDefault
import
fr.chenry.android.freshrss.utils.whenNotNull
import
kotlinx.android.synthetic.main.fragment_main_subscription.*
import
kotlin.reflect.KClass
...
...
@@ -66,7 +68,7 @@ class MainSubscriptionFragment: Fragment() {
override
fun
onCreateOptionsMenu
(
menu
:
Menu
?,
inflater
:
MenuInflater
?)
{
inflater
?.
inflate
(
R
.
menu
.
main_actionbar
,
menu
)
menu
?.
findItem
(
R
.
id
.
action_refresh
)
?.
setOnMenuItemClickListener
{
Store
.
refresh
().
getOrDefault
(
null
)
.
let
{
true
}
FreshRSSApplication
.
application
.
refresherService
.
whenNotNull
{
it
.
refresh
()}
.
let
{
true
}
}
super
.
onCreateOptionsMenu
(
menu
,
inflater
)
...
...
app/src/main/java/fr/chenry/android/freshrss/store/Store.kt
View file @
e73411ba
package
fr.chenry.android.freshrss.store
import
androidx.lifecycle.MutableLiveData
import
fr.chenry.android.freshrss.R
import
fr.chenry.android.freshrss.R.string
import
fr.chenry.android.freshrss.components.subscriptions.SubscriptionSection
import
fr.chenry.android.freshrss.store.api.Api
import
fr.chenry.android.freshrss.store.database.models.Account
import
fr.chenry.android.freshrss.store.api.models.StreamId
import
fr.chenry.android.freshrss.store.api.models.Subscription
import
fr.chenry.android.freshrss.store.database.FreshRSSDabatabase
import
fr.chenry.android.freshrss.store.database.models.*
import
fr.chenry.android.freshrss.store.database.models.ReadStatus.UNREAD
import
fr.chenry.android.freshrss.store.databindingsupport.GenericLiveData
import
fr.chenry.android.freshrss.utils.NotificationHelper
import
fr.chenry.android.freshrss.utils.NotificationHelper.NotificationChanels.REFRESH
import
fr.chenry.android.freshrss.utils.e
import
nl.komponents.kovenant.*
import
nl.komponents.kovenant.combine.and
import
nl.komponents.kovenant.functional.bind
import
nl.komponents.kovenant.ui.failUi
import
nl.komponents.kovenant.ui.successUi
object
Store
{
lateinit
var
api
:
Api
...
...
@@ -30,7 +22,6 @@ object Store {
val
subscriptionsSection
=
MutableLiveData
<
SubscriptionSection
>().
apply
{
this
.
value
=
SubscriptionSection
.
ALL
}
val
tags
=
MutableLiveData
<
List
<
String
>>().
apply
{
this
.
value
=
listOf
()}
val
favorites
=
GenericLiveData
<
String
,
Subscription
>(
mutableMapOf
())
private
val
refreshingPromise
=
MutableLiveData
<
Promise
<
Unit
,
Exception
>>()
private
var
lastFetchTimestamp
=
0L
fun
init
(
account
:
Account
)
{
...
...
@@ -41,26 +32,6 @@ object Store {
fun
login
(
instance
:
String
,
user
:
String
,
password
:
String
):
Promise
<
Unit
,
Exception
>
=
Api
.
login
(
instance
,
user
,
password
)
then
{
init
(
it
)}
fun
refresh
():
Promise
<
Unit
,
Exception
>
{
if
(
refreshingPromise
.
value
!=
null
)
return
refreshingPromise
.
value
!!
val
notificationId
=
NotificationHelper
.
post
(
REFRESH
,
R
.
string
.
notification_refresh_title
)
ensureToken
()
val
promise
=
getSubscriptions
()
.
bind
{
getUnreadCount
()}
.
bind
{
all
(
subscriptions
.
keys
.
map
{
getStreamContents
(
it
)},
cancelOthersOnError
=
false
)}
.
bind
{
getUnreadItems
()}
refreshingPromise
.
postValue
(
promise
)
promise
.
always
{
refreshingPromise
.
postValue
(
null
)}
.
successUi
{
NotificationHelper
.
cancel
(
notificationId
)}
.
failUi
{
NotificationHelper
.
update
(
REFRESH
,
notificationId
,
string
.
notification_refresh_failed_title
)}
return
promise
}
fun
getSubscriptions
():
Promise
<
Unit
,
Exception
>
=
api
.
getSubscriptions
()
then
{
subscriptions
.
addAll
(
it
.
map
{
self
->
self
.
id
to
self
})}
...
...
@@ -109,7 +80,7 @@ object Store {
fun
postReadStatus
(
article
:
Article
,
readStatus
:
ReadStatus
):
Promise
<
Unit
,
Exception
>
=
ensureToken
()
bind
{
api
.
postReadStatus
(
article
.
id
,
readStatus
)
.
success
{
FreshRSSDabatabase
.
instance
.
upsertArticle
(
article
.
copy
(
readStatus
=
readStatus
))
}
.
success
{
FreshRSSDabatabase
.
instance
.
upsertArticle
(
article
.
copy
(
readStatus
=
readStatus
))
}
}
private
fun
ensureToken
():
Promise
<
Unit
,
Exception
>
{
...
...
app/src/main/java/fr/chenry/android/freshrss/utils/KotlinExtensions.kt
View file @
e73411ba
...
...
@@ -95,3 +95,6 @@ fun <V, E>Promise<V, E>.getOrDefault(default: V) = try {
this
.
w
(
e
)
default
}
fun
<
T
:
Any
>
T
?.
whenNotNull
(
body
:
(
T
)
->
Unit
)
=
if
(
this
!==
null
)
body
(
this
).
let
{
this
}
else
this
fun
<
T
:
Any
>
T
?.
whenNull
(
body
:
()
->
Unit
)
=
this
?:
body
().
let
{
this
}
\ No newline at end of file
app/src/main/java/fr/chenry/android/freshrss/utils/NotificationHelper.kt
View file @
e73411ba
...
...
@@ -9,58 +9,29 @@ import fr.chenry.android.freshrss.FreshRSSApplication
import
fr.chenry.android.freshrss.R
object
NotificationHelper
{
fun
post
(
channel
:
NotificationChanels
,
contentTitleId
:
Int
,
notificationId
:
Int
=
channel
.
channelId
):
Int
{
NotificationManagerCompat
.
from
(
FreshRSSApplication
.
application
)
.
notify
(
notificationId
,
getNotification
(
channel
,
contentTitleId
))
return
notificationId
}
fun
update
(
channel
:
NotificationChanels
,
notificationId
:
Int
,
contentTitleId
:
Int
)
=
FreshRSSApplication
.
notificationManager
.
notify
(
notificationId
,
getNotification
(
channel
,
contentTitleId
))
private
fun
getNotification
(
channel
:
NotificationChanels
,
contentTitleId
:
Int
):
Notification
=
NotificationCompat
.
Builder
(
FreshRSSApplication
.
application
,
channel
.
channelTitle
)
.
setSmallIcon
(
R
.
drawable
.
ic_rss_feed_black_24dp
)
.
setContentTitle
(
FreshRSSApplication
.
application
.
resources
.
getString
(
contentTitleId
))
.
setPriority
(
NotificationCompat
.
PRIORITY_DEFAULT
)
.
build
()
const
val
ONGOING_REFRESH_NOTIFICATION
=
1
const
val
FAIL_REFRESH_NOTIFICATION
=
2
fun
cancel
(
id
:
Int
)
=
NotificationManagerCompat
.
from
(
FreshRSSApplication
.
application
).
cancel
(
id
)
private
fun
createNotificationChannel
(
channelNameId
:
Int
,
channelDescription
:
Int
):
Pair
<
Int
,
String
>
{
if
(
Build
.
VERSION
.
SDK_INT
<=
Build
.
VERSION_CODES
.
O
)
return
0
to
""
return
try
{
val
name
=
FreshRSSApplication
.
application
.
resources
.
getString
(
channelNameId
)
val
descriptionText
=
FreshRSSApplication
.
application
.
resources
.
getString
(
channelDescription
)
val
importance
=
NotificationManager
.
IMPORTANCE_DEFAULT
val
channelId
=
FreshRSSApplication
.
application
.
resources
.
getString
(
R
.
string
.
notification_channel_refresh
)
val
channel
=
NotificationChannel
(
channelId
,
name
,
importance
).
apply
{
description
=
descriptionText
}
// Register the channel with the system
val
notificationManager
=
FreshRSSApplication
.
application
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
notificationManager
.
createNotificationChannel
(
channel
)
channelNameId
to
channelId
}
catch
(
_
:
Throwable
)
{
0
to
"DEFAULT"
}
enum
class
NotificationChanels
(
nameResourceId
:
Int
,
descriptionResourceId
:
Int
,
importance
:
Int
?
=
null
)
{
REFRESH
(
R
.
string
.
notification_channel_refresh_title
,
R
.
string
.
notification_channel_refresh_description
);
val
channelId
:
String
get
()
=
this
.
name
init
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
Try
{
FreshRSSApplication
.
application
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
).
apply
{
this
as
NotificationManager
val
n
=
FreshRSSApplication
.
getStringR
(
nameResourceId
)
val
i
=
importance
?:
NotificationManager
.
IMPORTANCE_LOW
NotificationChannel
(
channelId
,
n
,
i
).
let
{
it
.
description
=
FreshRSSApplication
.
getStringR
(
descriptionResourceId
)
createNotificationChannel
(
it
)
}
}
}
}
}
enum
class
NotificationChanels
(
channel
:
Pair
<
Int
,
String
>)
{
REFRESH
(
createNotificationChannel
(
R
.
string
.
notification_refresh_title
,
R
.
string
.
notification_refresh_description
)
);
val
channelId
=
channel
.
first
val
channelTitle
=
channel
.
second
}
}
\ No newline at end of file
app/src/main/java/fr/chenry/android/freshrss/utils/Try.kt
0 → 100644
View file @
e73411ba
package
fr.chenry.android.freshrss.utils
class
Try
<
T
:
Any
>(
body
:
()
->
T
)
{
private
lateinit
var
_error
:
Throwable
private
lateinit
var
_value
:
T
val
isSuccess
:
Boolean
get
()
=
::
_error
.
isInitialized
val
value
:
T
get
()
=
_value
val
error
:
Throwable
get
()
=
_error
init
{
try
{
_value
=
body
()
}
catch
(
err
:
Throwable
)
{
_error
=
err
}
}
fun
<
U
:
Any
>
map
(
body
:
(
Try
<
T
>)
->
U
):
Try
<
U
>
=
Try
{
body
(
this
)}
fun
<
U
:
Any
>
whenSuccess
(
body
:
(
T
)
->
U
):
Try
<
T
>
=
if
(
isSuccess
)
body
(
value
).
let
{
this
}
else
this
fun
<
U
:
Any
>
whenError
(
body
:
(
Throwable
)
->
U
):
Try
<
T
>
=
if
(!
isSuccess
)
body
(
error
).
let
{
this
}
else
this
}
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
e73411ba
<resources>
<!-- Do not translate -->
<string
name=
"notification_channel_refresh"
>
REFRESH
</string>
<string
name=
"app_name"
>
FreshRSS
</string>
<string
name=
"title_activity_login"
>
Sign in
</string>
<string
name=
"prompt_login"
>
Login
</string>
<string
name=
"prompt_password"
>
Password
</string>
<string
name=
"action_sign_in"
>
Sign in
</string>
...
...
@@ -34,10 +31,6 @@
<string
name=
"next"
>
Next
</string>
<string
name=
"error_invalid_password"
>
This password is too short
</string>
<string
name=
"original_page"
>
Open in browser
</string>
<string
name=
"notification_refresh_title"
>
Refreshing your RSS feeds
</string>
<string
name=
"notification_refresh_description"
>
FreshRSS is fetching your content from the server
</string>
<string
name=
"notification_refresh_failed_title"
>
FresshRSS failed to retrieve content from your FreshRSS server
</string>
<string
name=
"refresh"
>
Refresh
</string>
<string
name=
"mark_read"
>
Mark read
</string>
<string
name=
"mark_unread"
>
Mark unread
</string>
...
...
@@ -47,4 +40,12 @@
<string
name=
"unread"
>
unread
</string>
<string
name=
"request_already_ongoing"
>
A request is already ongoing. Please retry later.
</string>
<string
name=
"unable_to"
>
Sorry, the application failed to %s
</string>
<!-- Notifications -->
<string
name=
"notification_refresh_title"
>
Refreshing your RSS feeds
</string>
<string
name=
"notification_refresh_description"
>
FreshRSS is fetching your content from the server
</string>
<string
name=
"notification_refresh_failed_title"
>
Refreshing failed
</string>
<string
name=
"notification_refresh_failed_description"
>
FresshRSS failed to retrieve content from your FreshRSS server
</string>
<string
name=
"notification_channel_refresh_title"
>
Refresh events
</string>
<string
name=
"notification_channel_refresh_description"
>
Events occuring when trying to fetch content from your FreshRSS server
</string>
</resources>
Christophe Henry
@christophehenry
mentioned in issue
#13 (closed)
·
Mar 04, 2019
mentioned in issue
#13 (closed)
mentioned in issue #13
Toggle commit list
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment