/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 1 . ĠM ats uda , ĠA ki hit Ġ( ak ih ito 1 0 4 ) Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġcom . fresh digit able . ud on road 2 . data . local Ċ Ċ import Ġandroid . app . Application Ċ import Ġandroid . content . SharedPreferences Ċ import Ġandroidx . core . content . edit Ċ import Ġcom . fresh digit able . db . R Ċ import Ġcom . fresh digit able . ud on road 2 . data . App Setting DataSource Ċ import Ġcom . fresh digit able . ud on road 2 . data . OAuth Token DataSource Ċ import Ġcom . fresh digit able . ud on road 2 . data . local . di . SharedPreferences Module Ċ import Ġcom . fresh digit able . ud on road 2 . model . AccessToken Entity Ċ import Ġcom . fresh digit able . ud on road 2 . model . Request Token Item Ċ import Ġcom . fresh digit able . ud on road 2 . model . UserId Ċ import Ġcom . fresh digit able . ud on road 2 . model . user . User Entity Ċ import Ġkotlinx . coroutines . channels . await Close Ċ import Ġkotlinx . coroutines . channels . send Blocking Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġkotlinx . coroutines . flow . callback Flow Ċ import Ġkotlinx . coroutines . flow . onStart Ċ import Ġjavax . inject . Inject Ċ import Ġjavax . inject . Named Ċ import Ġjavax . inject . Singleton Ċ Ċ @ Singleton Ċ class ĠShared Preference DataSource Ġ@ Inject Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġtwitter Prefs : ĠTwitter Preferences , ĊĠĠĠ Ġprivate Ġval Ġapp Prefs : ĠApp Preferences , Ċ ) Ġ: ĠApp Setting DataSource . Local , ĠOAuth Token DataSource . Local Ġ{ ĊĊĠĠĠ Ġoverride Ġval Ġcurrent UserId : ĠUserId ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġtwitter Prefs . current UserId ĊĠĠĠ Ġoverride Ġval Ġcurrent UserId Source : ĠFlow < UserId > Ġ= Ġtwitter Prefs . current UserId Source ĊĠĠĠ Ġoverride Ġval Ġregistered User Ids Source : ĠFlow < Set < UserId >> Ġ= Ġtwitter Prefs . registered User Ids Source ĊĠĠĠ Ġoverride Ġval Ġlogin Account On Launch : ĠUserId ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġapp Prefs . login Account On Launch ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġupdate CurrentUser ( accessToken : ĠAccess Token Entity ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtwitter Prefs . update CurrentUser ( accessToken ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġadd AccessToken Entity ( token : ĠAccess Token Entity ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtwitter Prefs . add AccessToken Entity ( token ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġfind User AccessToken Entity ( userId : ĠUserId ): ĠAccess Token Entity ? Ġ= ĊĠĠĠĠĠĠĠ Ġtwitter Prefs . find User AccessToken Entity ( userId ) ĊĊĠĠĠ Ġoverride Ġval Ġis Po ss ibly Sensitive Hidden : ĠFlow < Boolean > Ġ= Ġapp Prefs . is Po ss ibly Sensitive Hidden ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġget Request Token Item (): ĠRequest Token Item Ġ= Ġthrow ĠNotImplementedError () ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġget AccessToken ( ĊĠĠĠĠĠĠĠ Ġrequest Token : ĠRequest Token Item , ĊĠĠĠĠĠĠĠ Ġverifier : ĠString , ĊĠĠĠ Ġ): ĠAccess Token Entity Ġ= Ġthrow ĠNotImplementedError () ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġverify Credentials (): ĠUser Entity Ġ= Ġthrow ĠNotImplementedError () Ċ } Ċ Ċ fun ĠApp Setting DataSource . Local . require Current UserId (): ĠUserId Ġ= Ġrequire NotNull ( current UserId ) Ċ Ċ @ Singleton Ċ class ĠTwitter Preferences Ġ@ Inject Ġconstructor ( ĊĠĠĠ Ġ@ Named ( SharedPreferences Module . NAMED _ SETTING _ TW IT TER ) ĊĠĠĠ Ġprivate Ġval Ġprefs : ĠSharedPreferences , Ċ ) Ġ{ ĊĠĠĠ Ġinternal Ġval Ġcurrent UserId : ĠUserId ? ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠuserId Ġ= Ġprefs . getLong ( CURRENT _ USER _ ID , Ġ- 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( userId Ġ!= Ġ- 1 L ) ĠUserId ( userId ) Ġelse Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġinternal Ġval Ġcurrent UserId Source : ĠFlow < UserId > Ġ= ĊĠĠĠĠĠĠĠ Ġprefs . create Source ( CURRENT _ USER _ ID ) Ġ{ ĠUserId ( it . getLong ( CURRENT _ USER _ ID , Ġ- 1 )) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. onStart Ġ{ Ġcurrent UserId ?. let Ġ{ Ġemit ( it ) Ġ} Ġ} ĊĊĠĠĠ Ġinternal Ġval Ġregistered User Ids Source : ĠFlow < Set < UserId >> Ġ= ĊĠĠĠĠĠĠĠ Ġprefs . create Source ( AUTHENT IC ATED _ USERS ) Ġ{ Ġit . getAll Authenticated User Ids Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. onStart Ġ{ Ġemit ( prefs . getAll Authenticated User Ids ) Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġupdate CurrentUser ( accessToken : ĠAccess Token Entity ) Ġ{ ĊĠĠĠĠĠĠĠ Ġprefs . edit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput Long ( CURRENT _ USER _ ID , ĠaccessToken . userId . value ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġadd AccessToken Entity ( token : ĠAccess Token Entity ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠuserId Ġ= Ġtoken . userId ĊĠĠĠĠĠĠĠ Ġcheck ( userId . isValid ) Ġ{ Ġ" invalid Ġtoken : Ġ$ token " Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġusers Ġ= Ġprefs . getString Set ( AUTHENT IC ATED _ USERS , Ġset Of ()) Ġ?: Ġset Of () ĊĊĠĠĠĠĠĠĠ Ġprefs . edit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput String Set ( AUTHENT IC ATED _ USERS , Ġusers Ġ+ Ġ"${ userId . value }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput String ("$ ACCESS _ TOKEN _ PREFIX ${ userId . value }", Ġtoken . token ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġput String ("$ TOKEN _ SECRET _ PREFIX ${ userId . value }", Ġtoken . token Secret ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġfind User AccessToken Entity ( userId : ĠUserId ): ĠAccess Token Entity ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġprefs . getString ("$ ACCESS _ TOKEN _ PREFIX ${ userId . value }", Ġnull ) Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġsecret Ġ= Ġprefs . getString ("$ TOKEN _ SECRET _ PREFIX ${ userId . value }", Ġnull ) Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġreturn ĠAccess Token Entity . create ( userId , Ġtoken , Ġsecret ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠAUTH ENT IC ATED _ USERS Ġ= Ġ" authenticated Users " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠCURRENT _ USER _ ID Ġ= Ġ" current UserId " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠACCESS _ TOKEN _ PREFIX Ġ= Ġ" accessToken _" ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTOKEN _ SECRET _ PREFIX Ġ= Ġ" token Secret _" Ċ // ĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠT WIT TER _ API _ CONFIG _ DATE Ġ= Ġ" twitter API Config Date " ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠSharedPreferences . getAll Authenticated User Ids : ĠSet < UserId > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget () Ġ= Ġ( getString Set ( AUTHENT IC ATED _ USERS , Ġempty Set ()) Ġ?: Ġempty Set ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠUserId ( it . to Long ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toSet () ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Singleton Ċ class ĠApp Preferences Ġ@ Inject Ġconstructor ( ĊĠĠĠ Ġ@ Named ( SharedPreferences Module . NAMED _ SETTING _ APP ) ĊĠĠĠ Ġprivate Ġval Ġprefs : ĠSharedPreferences , ĊĠĠĠ Ġapplication : ĠApplication , Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġpossibly Sensitive Hidden Key Ġ= Ġapplication . getString ( R . string . settings _ key _ sensitive ) ĊĠĠĠ Ġprivate Ġval Ġpossibly Sensitive Hidden Default Ġ= ĊĠĠĠĠĠĠĠ Ġapplication . resources . getBoolean ( R . bool . settings _ sensitive _ default ) ĊĊĠĠĠ Ġinternal Ġval Ġis Po ss ibly Sensitive Hidden : ĠFlow < Boolean > Ġ= ĊĠĠĠĠĠĠĠ Ġprefs . create Source ( possibly Sensitive Hidden Key ) Ġ{ Ġit . is Po ss ibly Sensitive Hidden Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. onStart Ġ{ Ġemit ( prefs . is Po ss ibly Sensitive Hidden ) Ġ} ĊĊĠĠĠ Ġprivate Ġval ĠSharedPreferences . is Po ss ibly Sensitive Hidden : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġget Boolean ( possibly Sensitive Hidden Key , Ġpossibly Sensitive Hidden Default ) ĊĊĠĠĠ Ġprivate Ġval Ġlogin Account Key Ġ= Ġapplication . getString ( R . string . settings _ key _ login User ) ĊĠĠĠ Ġprivate Ġval Ġlogin Account Default Ġ= Ġapplication . getString ( R . string . settings _ login User _ default ) ĊĠĠĠ Ġinternal Ġval Ġlogin Account On Launch : ĠUserId ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġprefs . getString ( login Account Key , Ġlogin Account Default ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĠUserId . create ( it . to Long ()) Ġ} Ċ } Ċ Ċ private Ġfun Ġ< T > ĠSharedPreferences . create Source ( ĊĠĠĠ Ġkey : ĠString , ĊĠĠĠ Ġupdate : Ġ( SharedPreferences ) Ġ-> ĠT , Ċ ): ĠFlow < T > Ġ= Ġcallback Flow Ġ{ ĊĠĠĠ Ġval Ġlistener Ġ= ĠSharedPreferences . On Shared Preference ChangeListener Ġ{ Ġsp , Ġk Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( k Ġ== Ġkey ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Blocking ( update ( sp )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġregister On Shared Preference ChangeListener ( listener ) ĊĠĠĠ Ġawait Close Ġ{ Ġunregister On Shared Preference ChangeListener ( listener ) Ġ} Ċ } Ċ