├── .github └── workflows │ └── android.yml ├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── sust │ │ └── sustcast │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-playstore.png │ ├── java │ │ └── com │ │ │ └── sust │ │ │ └── sustcast │ │ │ ├── LandingActivity.java │ │ │ ├── authentication │ │ │ ├── ForgetPasswordActivity.java │ │ │ ├── LoginActivity.java │ │ │ ├── SignUpActivity.java │ │ │ └── TocActivity.java │ │ │ ├── data │ │ │ ├── AuthenticationRepository.java │ │ │ ├── AuthenticationViewModel.java │ │ │ ├── Config.java │ │ │ ├── Constants.java │ │ │ ├── IceUrl.java │ │ │ └── User.java │ │ │ ├── dialogs │ │ │ └── SimpleAlertDialog.java │ │ │ ├── fragment │ │ │ ├── FeedbackFragment.java │ │ │ ├── FragmentHolder.java │ │ │ ├── NewsReaderFragment.java │ │ │ └── StreamFragment.java │ │ │ ├── services │ │ │ └── RadioService.java │ │ │ ├── splash │ │ │ ├── SplashActivity.java │ │ │ ├── SplashRepository.java │ │ │ └── SplashViewModel.java │ │ │ └── utils │ │ │ ├── ConnectionLiveData.java │ │ │ ├── DataBindingAdapters.java │ │ │ ├── FirebaseMessageReceiver.java │ │ │ ├── FontHelper.java │ │ │ ├── LoadBalancingUtil.java │ │ │ └── StringValidationRules.java │ └── res │ │ ├── drawable-hdpi │ │ └── ic_small_notification_icon.png │ │ ├── drawable-mdpi │ │ └── ic_small_notification_icon.png │ │ ├── drawable-v23 │ │ ├── bottom_navigation_background.xml │ │ ├── bottom_navigation_color_selector.xml │ │ ├── extras.xml │ │ ├── facebook.xml │ │ ├── feedback.xml │ │ ├── google_play.xml │ │ ├── log_out.xml │ │ ├── meow.xml │ │ ├── news.xml │ │ ├── news_bottom_button.xml │ │ ├── pause_button.xml │ │ ├── play_button.xml │ │ ├── splash_screen_background.xml │ │ ├── stream.xml │ │ ├── stream_bottom_button.xml │ │ └── sustcast_logo_circle_only.xml │ │ ├── drawable-v24 │ │ ├── bottom_navigation_background.xml │ │ ├── bottom_navigation_color_selector.xml │ │ ├── extras.xml │ │ ├── facebook.xml │ │ ├── feedback.xml │ │ ├── google_play.xml │ │ ├── log_out.xml │ │ ├── meow.xml │ │ ├── news.xml │ │ ├── news_bottom_button.xml │ │ ├── pause_button.xml │ │ ├── play_button.xml │ │ ├── stream.xml │ │ ├── stream_bottom_button.xml │ │ └── sustcast_logo_circle_only.xml │ │ ├── drawable-xhdpi │ │ └── ic_small_notification_icon.png │ │ ├── drawable-xxhdpi │ │ └── ic_small_notification_icon.png │ │ ├── drawable-xxxhdpi │ │ └── ic_small_notification_icon.png │ │ ├── drawable │ │ ├── bg_button_text_white_yellow_active_pressed.xml │ │ ├── bg_button_white_yellow_active_pressed.xml │ │ ├── bg_oval_button.xml │ │ ├── bottom_navigation_background.xml │ │ ├── bottom_navigation_color_selector.xml │ │ ├── button_rounded.xml │ │ ├── extras.xml │ │ ├── facebook.xml │ │ ├── feedback.xml │ │ ├── google_play.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_login_rectangle.xml │ │ ├── ic_logo.xml │ │ ├── ic_rectangle_white_with_yellow_border.xml │ │ ├── ic_robosust.xml │ │ ├── ic_signup_rectangle.xml │ │ ├── line_contributors.xml │ │ ├── line_landing.xml │ │ ├── line_login.xml │ │ ├── log_out.xml │ │ ├── meow.xml │ │ ├── news.xml │ │ ├── news_bottom_button.xml │ │ ├── pause_button.xml │ │ ├── play_button.xml │ │ ├── rounded_button.xml │ │ ├── splash_screen_background.xml │ │ ├── stream.xml │ │ ├── stream_bottom_button.xml │ │ └── sustcast_logo_circle_only.xml │ │ ├── font-v26 │ │ └── kollektif_family.xml │ │ ├── font │ │ ├── kollektif.ttf │ │ ├── kollektif_bold.ttf │ │ ├── kollektif_boldtalic.ttf │ │ ├── kollektif_family.xml │ │ └── kollektif_italic.ttf │ │ ├── layout-v21 │ │ └── activity_landing.xml │ │ ├── layout │ │ ├── activity_forget_password.xml │ │ ├── activity_fragment_holder.xml │ │ ├── activity_landing.xml │ │ ├── activity_login.xml │ │ ├── activity_sign_up.xml │ │ ├── activity_toc.xml │ │ ├── alert_simple.xml │ │ ├── dropdown_department_items.xml │ │ ├── fragment_feedback.xml │ │ ├── fragment_news_reader.xml │ │ ├── fragment_stream.xml │ │ ├── notification.xml │ │ └── playback_notification.xml │ │ ├── menu │ │ └── bottom_navigation_menu.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values-v23 │ │ └── styles.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── drawables.xml │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── network_security_config.xml │ └── test │ └── java │ └── com │ └── sust │ └── sustcast │ └── ExampleUnitTest.java ├── auth-ss.jpg ├── bhungbhang.gif ├── build.gradle ├── frag-ss.jpg ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── sustcast-architecture (1)-1.png /.github/workflows/android.yml: -------------------------------------------------------------------------------- 1 | name: SUSTcast Android CI 2 | 3 | on: 4 | push: 5 | branches: [ master , develop*] 6 | paths-ignore: 7 | - '**/README.md' 8 | pull_request: 9 | branches: [ master , develop*] 10 | paths-ignore: 11 | - '**/README.md' 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | jobs: 17 | build: 18 | 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: set up JDK 1.8 24 | uses: actions/setup-java@v1 25 | with: 26 | java-version: 1.8 27 | - name: Grant execute permission for gradlew 28 | run: chmod +x gradlew 29 | - name: Build with Gradle 30 | run: ./gradlew packageDebugUniversalApk 31 | - name: Get app version 32 | run: echo "APP_VERSION=v$(cat ./app/build.gradle | grep -m1 versionName | awk -F \" '{print $2}')" >> $GITHUB_ENV 33 | - name: Get app name 34 | run: echo "APP_NAME=SUSTcast-DEBUG#${{ github.run_number }}" >> $GITHUB_ENV 35 | - name: Rename the APK file 36 | run: mv ./app/build/outputs/universal_apk/debug/app-debug-universal.apk ./${{ env.APP_NAME }}.apk 37 | - name: Store generated APK file 38 | uses: actions/upload-artifact@v1 39 | with: 40 | name: ${{ env.APP_NAME }} 41 | path: ./${{ env.APP_NAME }}.apk 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.aar 4 | *.ap_ 5 | *.aab 6 | 7 | 8 | # Commenting out for build with CI 9 | # google-services.json 10 | 11 | # Files for the ART/Dalvik VM 12 | *.dex 13 | 14 | # Java class files 15 | *.class 16 | 17 | # Generated files 18 | bin/ 19 | gen/ 20 | out/ 21 | # Uncomment the following line in case you need and you don't have the release build type files in your app 22 | # release/ 23 | 24 | # Gradle files 25 | .gradle/ 26 | build/ 27 | 28 | # Local configuration file (sdk path, etc) 29 | local.properties 30 | 31 | # Proguard folder generated by Eclipse 32 | proguard/ 33 | 34 | # Log Files 35 | *.log 36 | 37 | # Android Studio Navigation editor temp files 38 | .navigation/ 39 | 40 | # Android Studio captures folder 41 | captures/ 42 | 43 | # IntelliJ 44 | *.iml 45 | .idea* 46 | .idea/workspace.xml 47 | .idea/tasks.xml 48 | .idea/gradle.xml 49 | .idea/assetWizardSettings.xml 50 | .idea/dictionaries 51 | .idea/libraries 52 | # Android Studio 3 in .gitignore file. 53 | .idea/caches 54 | .idea/modules.xml 55 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 56 | .idea/navEditor.xml 57 | 58 | # Keystore files 59 | # Uncomment the following lines if you do not want to check your keystore files in. 60 | #*.jks 61 | #*.keystore 62 | 63 | # External native build folder generated in Android Studio 2.2 and later 64 | .externalNativeBuild 65 | .cxx/ 66 | 67 | # Google Services (e.g. APIs or Firebase) 68 | # google-services.json 69 | 70 | # Freeline 71 | freeline.py 72 | freeline/ 73 | freeline_project_description.json 74 | 75 | # fastlane 76 | fastlane/report.xml 77 | fastlane/Preview.html 78 | fastlane/screenshots 79 | fastlane/test_output 80 | fastlane/readme.md 81 | 82 | # Version control 83 | vcs.xml 84 | 85 | # lint 86 | lint/intermediates/ 87 | lint/generated/ 88 | lint/outputs/ 89 | lint/tmp/ 90 | # lint/reports/ 91 | /.idea/ 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SUSTCast App-end 2 | ## Your Pocket-portal to SUST 3 | 4 | [![forthebadge](https://forthebadge.com/images/badges/open-source.svg)](https://forthebadge.com) 5 | [![forthebadge](https://forthebadge.com/images/badges/built-for-android.svg)](https://forthebadge.com) 6 | ![GitHub release (latest by date)](https://img.shields.io/github/v/release/sustcast/sustcast-android-app-v1?color=FFD700&style=for-the-badge&labelColor=black) 7 | 8 | [![SUSTcast Android CI](https://github.com/sustcast/sustcast-android-app-v1/actions/workflows/android.yml/badge.svg)](https://github.com/sustcast/sustcast-android-app-v1/actions/workflows/android.yml) 9 | 10 | 11 | 12 | SUSTCast is an AI-enhanced online radio app built for the SUSTians, by the SUSTians!!
13 | The fully-automated system is first of it's kind and runs on most low to high-end android phones, seemlessly.
14 | Currently our features include : 15 | ``` 16 | - automated music selections 17 | - 24/7 radio streaming 18 | - Broadcasts from BBC news 19 | - Weekly podcasts from special guests 20 | ``` 21 | 22 | ## App Structure and Tools 23 | 24 | * App Front-end follows the MVVM architecture and created with ![badge-java](https://img.shields.io/badge/java-FFD700?style=for-the-badge&logo=java&logoColor=white) on ![badge-android](https://img.shields.io/badge/androidstudio-FFD700?style=for-the-badge&logo=android&logoColor=white) . 25 | App is integrated with ![badge-firebase](https://img.shields.io/badge/firebase-FFD700?style=for-the-badge&logo=firebase&logoColor=white). Supports a minimum SDK *21* and above. 26 | 27 | ## Showcase 28 |

29 | 30 |

31 |

32 | 33 |

34 | 35 | 36 | 37 | ## Demo 38 |

39 | 40 |

41 | 42 | [![badge-play](https://img.shields.io/badge/Download-playstore-FFD700?style=for-the-badge&logo=google-play&logoColor=white&labelColor=black)](https://play.google.com/store/apps/details?id=com.sust.sustcast) 43 |
44 | [![badge-facebook](https://img.shields.io/badge/Visit-facebook-FFD700?style=for-the-badge&logo=facebook&logoColor=white&labelColor=black)](https://www.facebook.com/sustcast) 45 | ## Contributors 46 | 47 | 48 | 49 | 50 | Made with [contributors-img](https://contributors-img.web.app). 51 |
52 | 53 | trackgit-views 54 | 55 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.google.gms.google-services' 3 | apply plugin: 'com.google.firebase.crashlytics' 4 | 5 | android { 6 | compileSdkVersion 29 7 | buildToolsVersion "29.0.3" 8 | 9 | defaultConfig { 10 | applicationId "com.sust.sustcast" 11 | minSdkVersion 21 12 | targetSdkVersion 29 13 | versionCode 6 14 | versionName "Apollo v1.1.1" 15 | multiDexEnabled true 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | compileOptions { 27 | sourceCompatibility = 1.8 28 | targetCompatibility = 1.8 29 | } 30 | 31 | buildFeatures { 32 | dataBinding = true 33 | } 34 | } 35 | apply plugin: 'com.android.application' 36 | apply plugin: 'com.google.gms.google-services' 37 | 38 | dependencies { 39 | implementation fileTree(dir: 'libs', include: ['*.jar']) 40 | 41 | implementation 'androidx.appcompat:appcompat:1.1.0' 42 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 43 | implementation 'com.google.android.material:material:1.3.0-alpha02' 44 | implementation 'androidx.annotation:annotation:1.1.0' 45 | implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' 46 | implementation 'com.android.support:multidex:1.0.3' 47 | implementation 'com.rm:rmswitch:1.2.2' 48 | implementation 'com.google.android.exoplayer:exoplayer:2.11.2' 49 | implementation 'com.jakewharton:butterknife:10.2.1' 50 | implementation 'com.google.firebase:firebase-crashlytics:17.3.1' 51 | implementation 'com.google.firebase:firebase-analytics:18.0.2' 52 | 53 | implementation 'com.google.firebase:firebase-database:19.3.0' 54 | 55 | implementation 'com.google.firebase:firebase-auth:19.3.1' 56 | implementation 'com.google.firebase:firebase-firestore:21.4.3' 57 | implementation 'com.google.android.play:core:1.8.0' 58 | 59 | implementation 'com.google.firebase:firebase-messaging:20.2.4' 60 | annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' 61 | testImplementation 'junit:junit:4.13' 62 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 63 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 64 | } -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "911091727898", 4 | "firebase_url": "https://sustcast-android-app-v1.firebaseio.com", 5 | "project_id": "sustcast-android-app-v1", 6 | "storage_bucket": "sustcast-android-app-v1.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:911091727898:android:eac5b1ddf3001f144f9ba3", 12 | "android_client_info": { 13 | "package_name": "com.sust.sustcast" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "911091727898-56taajmjgg1v2uhqoquojrum4nvk4djo.apps.googleusercontent.com", 19 | "client_type": 1, 20 | "android_info": { 21 | "package_name": "com.sust.sustcast", 22 | "certificate_hash": "21eb58e30c7bec4022b8a68c33223f6d11fba98c" 23 | } 24 | }, 25 | { 26 | "client_id": "911091727898-bfu0b08sbfq0mk03pjmetqjhn157t4hi.apps.googleusercontent.com", 27 | "client_type": 1, 28 | "android_info": { 29 | "package_name": "com.sust.sustcast", 30 | "certificate_hash": "4e927ff9c1dedf2f81f4f291115fd4ca475d7e8f" 31 | } 32 | }, 33 | { 34 | "client_id": "911091727898-sr6bihouagtp047p9e58okla3i7umc2v.apps.googleusercontent.com", 35 | "client_type": 3 36 | } 37 | ], 38 | "api_key": [ 39 | { 40 | "current_key": "AIzaSyCTBgUDakwfp3P569_1I-3v7yPgLC8DYpo" 41 | } 42 | ], 43 | "services": { 44 | "appinvite_service": { 45 | "other_platform_oauth_client": [ 46 | { 47 | "client_id": "911091727898-sr6bihouagtp047p9e58okla3i7umc2v.apps.googleusercontent.com", 48 | "client_type": 3 49 | } 50 | ] 51 | } 52 | } 53 | } 54 | ], 55 | "configuration_version": "1" 56 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/sust/sustcast/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.ext.junit.runners.AndroidJUnit4; 6 | import androidx.test.platform.app.InstrumentationRegistry; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.assertEquals; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | 25 | assertEquals("com.sust.sustcast", appContext.getPackageName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 24 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 45 | 46 | 50 | 54 | 58 | 63 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustcast/sustcast-android-app-v1/1d42b1c696ff2a082062dd9d280a87cbeb8839e0/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/LandingActivity.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast; 2 | 3 | import android.content.Intent; 4 | import android.os.Build; 5 | import android.os.Bundle; 6 | import android.util.Log; 7 | import android.widget.Toast; 8 | 9 | import androidx.appcompat.app.AppCompatActivity; 10 | import androidx.databinding.DataBindingUtil; 11 | 12 | import com.sust.sustcast.authentication.LoginActivity; 13 | import com.sust.sustcast.authentication.SignUpActivity; 14 | import com.sust.sustcast.databinding.ActivityLandingBinding; 15 | import com.sust.sustcast.utils.ConnectionLiveData; 16 | import com.sust.sustcast.utils.FontHelper; 17 | import com.sust.sustcast.utils.FirebaseMessageReceiver; 18 | 19 | import static com.sust.sustcast.data.Constants.CHECKNET; 20 | 21 | public class LandingActivity extends AppCompatActivity { 22 | 23 | private static final String TAG = "LandingActivity"; 24 | 25 | @Override 26 | protected void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | 29 | ActivityLandingBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_landing); 30 | binding.setLandingActivity(this); 31 | 32 | ConnectionLiveData connectionLiveData = new ConnectionLiveData(this); 33 | connectionLiveData.observe(this, aBoolean -> { 34 | if (!aBoolean) { 35 | Log.d(TAG, "No internet"); 36 | Toast.makeText(getApplicationContext(), CHECKNET, Toast.LENGTH_LONG).show(); 37 | } 38 | }); 39 | 40 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 41 | FontHelper.adjustFontScale(this, getResources().getConfiguration()); 42 | } 43 | } 44 | 45 | public void startSignUp() { 46 | startActivity(new Intent(LandingActivity.this, SignUpActivity.class)); 47 | } 48 | 49 | public void startLogin() { 50 | startActivity(new Intent(LandingActivity.this, LoginActivity.class)); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/authentication/ForgetPasswordActivity.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.authentication; 2 | 3 | import android.os.Build; 4 | import android.os.Bundle; 5 | import android.text.Editable; 6 | import android.text.TextUtils; 7 | import android.text.TextWatcher; 8 | import android.widget.Toast; 9 | 10 | import androidx.appcompat.app.AppCompatActivity; 11 | import androidx.databinding.DataBindingUtil; 12 | 13 | import com.google.firebase.auth.FirebaseAuth; 14 | import com.sust.sustcast.R; 15 | import com.sust.sustcast.databinding.ActivityForgetPasswordBinding; 16 | import com.sust.sustcast.utils.FontHelper; 17 | import com.sust.sustcast.utils.StringValidationRules; 18 | 19 | import static com.sust.sustcast.data.Constants.CHECKMAIL; 20 | import static com.sust.sustcast.data.Constants.EMPTYMAIL; 21 | import static com.sust.sustcast.data.Constants.FAILMAIL; 22 | import static com.sust.sustcast.data.Constants.INVALIDEMAIL; 23 | 24 | public class ForgetPasswordActivity extends AppCompatActivity { 25 | private FirebaseAuth mAuth; 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | 31 | ActivityForgetPasswordBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_forget_password); 32 | binding.setForgetPassActivity(this); 33 | 34 | binding.etEmailForget.addTextChangedListener(new TextWatcher() { 35 | @Override 36 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 37 | } 38 | 39 | @Override 40 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 41 | } 42 | 43 | @Override 44 | public void afterTextChanged(Editable editable) { 45 | if (StringValidationRules.EMAIL.validate(editable)) { 46 | binding.etEmailForget.setError(INVALIDEMAIL); 47 | } 48 | } 49 | }); 50 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 51 | FontHelper.adjustFontScale(this, getResources().getConfiguration()); 52 | } 53 | } 54 | 55 | public void resetPassword(String email) { 56 | mAuth = FirebaseAuth.getInstance(); 57 | if (!TextUtils.isEmpty(email)) { 58 | mAuth.sendPasswordResetEmail(email).addOnCompleteListener(task -> { 59 | if (task.isSuccessful()) { 60 | Toast.makeText(ForgetPasswordActivity.this, CHECKMAIL, Toast.LENGTH_SHORT).show(); 61 | } else { 62 | Toast.makeText(ForgetPasswordActivity.this, FAILMAIL, Toast.LENGTH_SHORT).show(); 63 | } 64 | } 65 | ); 66 | } 67 | else{ 68 | Toast.makeText(ForgetPasswordActivity.this, EMPTYMAIL, Toast.LENGTH_SHORT).show(); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/authentication/LoginActivity.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.authentication; 2 | 3 | import android.content.Intent; 4 | import android.os.Build; 5 | import android.os.Bundle; 6 | import android.widget.Toast; 7 | 8 | import androidx.appcompat.app.AppCompatActivity; 9 | import androidx.databinding.DataBindingUtil; 10 | import androidx.databinding.ObservableBoolean; 11 | import androidx.lifecycle.ViewModelProvider; 12 | 13 | import com.sust.sustcast.R; 14 | import com.sust.sustcast.data.AuthenticationViewModel; 15 | import com.sust.sustcast.databinding.ActivityLoginBinding; 16 | import com.sust.sustcast.fragment.FragmentHolder; 17 | import com.sust.sustcast.utils.FontHelper; 18 | 19 | import static com.sust.sustcast.data.Constants.DATAERROR; 20 | import static com.sust.sustcast.data.Constants.LOGINERROR; 21 | import static com.sust.sustcast.data.Constants.USERS; 22 | 23 | public class LoginActivity extends AppCompatActivity { 24 | public ObservableBoolean visibility = new ObservableBoolean(false); 25 | private AuthenticationViewModel authViewModel; 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | 31 | ActivityLoginBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_login); 32 | binding.setLoginActivity(this); 33 | 34 | 35 | authViewModel = new ViewModelProvider(this).get(AuthenticationViewModel.class); 36 | authViewModel.getAuthenticatedUser().observe(this, authenticatedUser -> { 37 | startActivity(new Intent(LoginActivity.this, FragmentHolder.class).putExtra(USERS, authenticatedUser)); 38 | finish(); 39 | }); 40 | 41 | authViewModel.getSignError().observe(this, errorObserver -> { 42 | if (errorObserver) { 43 | visibility.set(false); 44 | Toast.makeText(LoginActivity.this, LOGINERROR, Toast.LENGTH_SHORT).show(); 45 | } 46 | }); 47 | 48 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 49 | FontHelper.adjustFontScale(this, getResources().getConfiguration()); 50 | } 51 | 52 | } 53 | 54 | public void signIn(String email, String password) { 55 | 56 | if (email.length() != 0 && password.length() != 0 && password.length() > 5) { 57 | visibility.set(true); 58 | authViewModel.signIn(email, password); 59 | } else { 60 | Toast.makeText(LoginActivity.this, DATAERROR, Toast.LENGTH_SHORT).show(); 61 | } 62 | } 63 | 64 | public void startForget() { 65 | startActivity(new Intent(LoginActivity.this, ForgetPasswordActivity.class)); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/authentication/TocActivity.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.authentication; 2 | 3 | import android.os.Build; 4 | import android.os.Bundle; 5 | 6 | import androidx.appcompat.app.AppCompatActivity; 7 | import androidx.databinding.DataBindingUtil; 8 | 9 | import com.sust.sustcast.R; 10 | import com.sust.sustcast.databinding.ActivityTocBinding; 11 | import com.sust.sustcast.utils.FontHelper; 12 | 13 | import static com.sust.sustcast.data.Constants.TOC; 14 | 15 | public class TocActivity extends AppCompatActivity { 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | 21 | ActivityTocBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_toc); 22 | binding.setTocActivity(this); 23 | binding.tvToc.setText(TOC); 24 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 25 | FontHelper.adjustFontScale(this, getResources().getConfiguration()); 26 | } 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/data/AuthenticationRepository.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.data; 2 | 3 | import com.google.firebase.auth.FirebaseAuth; 4 | import com.google.firebase.auth.FirebaseUser; 5 | import com.google.firebase.firestore.CollectionReference; 6 | import com.google.firebase.firestore.DocumentReference; 7 | import com.google.firebase.firestore.DocumentSnapshot; 8 | import com.google.firebase.firestore.FirebaseFirestore; 9 | 10 | import java.util.Objects; 11 | 12 | import static com.sust.sustcast.data.Constants.USERS; 13 | 14 | public abstract class AuthenticationRepository { 15 | private FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(); 16 | private FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance(); 17 | private CollectionReference collectionReference = firebaseFirestore.collection(USERS); 18 | 19 | abstract void setUser(User user); 20 | 21 | abstract void setSignError(Boolean status); 22 | 23 | // abstract void setVerificationStatus(Boolean status); 24 | 25 | void firebaseSignIn(String emailAddress, String password) { 26 | firebaseAuth.signInWithEmailAndPassword(emailAddress, password).addOnCompleteListener(authTask -> { 27 | if (authTask.isSuccessful()) { 28 | FirebaseUser firebaseUser = firebaseAuth.getCurrentUser(); 29 | // if (firebaseUser.isEmailVerified()) { 30 | if (firebaseUser != null) { 31 | String uid = firebaseUser.getUid(); 32 | collectionReference.document(uid).get().addOnCompleteListener(dataTask -> { 33 | if (dataTask.isSuccessful()) { 34 | DocumentSnapshot documentSnapshot = dataTask.getResult(); 35 | assert documentSnapshot != null; 36 | if (documentSnapshot.exists()) { 37 | setSignError(false); 38 | User user = documentSnapshot.toObject(User.class); 39 | assert user != null; 40 | user.setAuthenticated(true); 41 | setUser(user); 42 | } 43 | } 44 | }); 45 | } 46 | // } else { 47 | // setSignError(true); 48 | // firebaseAuth.signOut(); 49 | // } 50 | } else 51 | setSignError(true); 52 | }); 53 | } 54 | 55 | void firebaseSignUp(String userName, String emailAddress, String password, String phoneNumber, String department) { 56 | User user = new User(userName, emailAddress, phoneNumber, department); 57 | firebaseAuth.createUserWithEmailAndPassword(emailAddress, password).addOnCompleteListener(authTask -> { 58 | if (authTask.isSuccessful()) { 59 | user.uid = Objects.requireNonNull(Objects.requireNonNull(authTask.getResult()).getUser()).getUid(); 60 | DocumentReference documentReference = collectionReference.document(user.uid); 61 | documentReference.get().addOnCompleteListener(dataTask -> { 62 | if (dataTask.isSuccessful()) { 63 | DocumentSnapshot documentSnapshot = dataTask.getResult(); 64 | assert documentSnapshot != null; 65 | if (!documentSnapshot.exists()) { 66 | documentReference.set(user).addOnCompleteListener(userCreationTask -> { 67 | if (userCreationTask.isSuccessful()) { 68 | // setVerificationStatus(true); 69 | // Objects.requireNonNull(firebaseAuth.getCurrentUser()).sendEmailVerification(); 70 | // firebaseAuth.signOut(); 71 | user.setAuthenticated(true); 72 | setUser(user); 73 | } 74 | }); 75 | } 76 | } 77 | }); 78 | } else setSignError(true); 79 | }); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/data/AuthenticationViewModel.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.data; 2 | 3 | import android.app.Application; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.lifecycle.AndroidViewModel; 7 | import androidx.lifecycle.LiveData; 8 | import androidx.lifecycle.MutableLiveData; 9 | 10 | public class AuthenticationViewModel extends AndroidViewModel { 11 | public MutableLiveData authenticatedUserLiveData; 12 | public MutableLiveData authenticationError; 13 | public MutableLiveData verificationStatus; 14 | private AuthenticationRepository authRepo; 15 | 16 | public AuthenticationViewModel(@NonNull Application application) { 17 | super(application); 18 | authenticatedUserLiveData = new MutableLiveData<>(); 19 | authenticationError = new MutableLiveData<>(); 20 | verificationStatus = new MutableLiveData<>(); 21 | authRepo = new AuthenticationRepository() { 22 | @Override 23 | void setUser(User user) { 24 | authenticatedUserLiveData.setValue(user); 25 | } 26 | 27 | @Override 28 | void setSignError(Boolean status) { 29 | authenticationError.setValue(status); 30 | } 31 | // 32 | // @Override 33 | // void setVerificationStatus(Boolean status) { 34 | // verificationStatus.setValue(status); 35 | // } 36 | }; 37 | } 38 | 39 | public void signIn(String emailAddress, String password) { 40 | authRepo.firebaseSignIn(emailAddress, password); 41 | } 42 | 43 | public void signUp(String userName, String emailAddress, String password, String phoneNumber, String department) { 44 | authRepo.firebaseSignUp(userName, emailAddress, password, phoneNumber, department); 45 | } 46 | 47 | public LiveData getSignError() { 48 | return authenticationError; 49 | } 50 | 51 | // public LiveData getVerificationStats() { 52 | // return verificationStatus; 53 | // } 54 | 55 | public LiveData getAuthenticatedUser() { 56 | return authenticatedUserLiveData; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/data/Config.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.data; 2 | 3 | import com.google.firebase.database.IgnoreExtraProperties; 4 | 5 | @IgnoreExtraProperties 6 | public class Config { 7 | 8 | private String mail_id; 9 | private String mail_subject; 10 | private String page_id; 11 | private String page_link; 12 | 13 | public Config(String mail_id, String mail_subject, String page_id, String page_link) { 14 | this.mail_id = mail_id; 15 | this.mail_subject = mail_subject; 16 | this.page_id = page_id; 17 | this.page_link = page_link; 18 | } 19 | 20 | public Config() { 21 | 22 | } 23 | 24 | public String getMail_id() { 25 | return mail_id; 26 | } 27 | 28 | 29 | public String getMail_subject() { 30 | return mail_subject; 31 | } 32 | 33 | 34 | public String getPage_id() { 35 | return page_id; 36 | } 37 | 38 | 39 | public String getPage_link() { 40 | return page_link; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/data/IceUrl.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.data; 2 | 3 | import com.google.firebase.database.IgnoreExtraProperties; 4 | 5 | @IgnoreExtraProperties 6 | public class IceUrl { 7 | 8 | private int limit; 9 | private int numlisteners; 10 | private String url; 11 | 12 | public IceUrl(int limit, int numlisteners, String url) { 13 | this.limit = limit; 14 | this.numlisteners = numlisteners; 15 | this.url = url; 16 | } 17 | 18 | public IceUrl() { 19 | 20 | } 21 | 22 | public int getLimit() { 23 | return limit; 24 | } 25 | 26 | public int getNumlisteners() { 27 | return numlisteners; 28 | } 29 | 30 | public String getUrl() { 31 | return url; 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/data/User.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.data; 2 | 3 | import java.io.Serializable; 4 | 5 | public class User implements Serializable { 6 | public String uid; 7 | public String userName; 8 | public String emailAddress; 9 | public String phoneNumber; 10 | public String department; 11 | private boolean isAuthenticated; 12 | 13 | public User() { 14 | } 15 | 16 | public User(String userName, String emailAddress, String phoneNumber, String department) { 17 | this.userName = userName; 18 | this.emailAddress = emailAddress; 19 | this.phoneNumber = phoneNumber; 20 | this.department = department; 21 | } 22 | 23 | public boolean getAuthenticated() { 24 | return isAuthenticated; 25 | } 26 | 27 | public void setAuthenticated(boolean isAuthenticated) { 28 | this.isAuthenticated = isAuthenticated; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/dialogs/SimpleAlertDialog.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.dialogs; 2 | 3 | import android.app.Dialog; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.view.LayoutInflater; 7 | import android.view.Window; 8 | 9 | import androidx.annotation.NonNull; 10 | import androidx.databinding.DataBindingUtil; 11 | 12 | import com.sust.sustcast.R; 13 | import com.sust.sustcast.databinding.AlertSimpleBinding; 14 | 15 | public abstract class SimpleAlertDialog extends Dialog { 16 | 17 | private static final String TAG = "SimpleAlertDialog"; 18 | private AlertSimpleBinding binding; 19 | private Context context; 20 | private int iconResource; 21 | private String buttonText; 22 | private String alertMessage; 23 | private boolean cancelable; 24 | 25 | public SimpleAlertDialog(@NonNull Context context, int iconResource, String buttonText, String alertMessage) { 26 | super(context); 27 | this.context = context; 28 | this.alertMessage = alertMessage; 29 | this.buttonText = buttonText; 30 | this.iconResource = iconResource; 31 | this.cancelable = true; 32 | } 33 | 34 | public SimpleAlertDialog(@NonNull Context context, int iconResource, String buttonText, String alertMessage, boolean cancelable) { 35 | super(context); 36 | this.context = context; 37 | this.alertMessage = alertMessage; 38 | this.buttonText = buttonText; 39 | this.iconResource = iconResource; 40 | this.cancelable = cancelable; 41 | } 42 | 43 | 44 | @Override 45 | protected void onCreate(Bundle savedInstanceState) { 46 | super.onCreate(savedInstanceState); 47 | requestWindowFeature(Window.FEATURE_NO_TITLE); 48 | 49 | binding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.alert_simple, null, false); 50 | setContentView(binding.getRoot()); 51 | 52 | this.setCancelable(cancelable); 53 | 54 | 55 | binding.button.setText(buttonText); 56 | binding.ivIcon.setImageResource(iconResource); 57 | binding.tvAlertMessage.setText(alertMessage); 58 | 59 | binding.button.setOnClickListener(view -> { 60 | buttonAction(); 61 | }); 62 | } 63 | 64 | public abstract void buttonAction(); 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/fragment/FeedbackFragment.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.fragment; 2 | 3 | import android.content.Intent; 4 | import android.content.pm.PackageManager; 5 | import android.net.Uri; 6 | import android.os.Bundle; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.Toast; 11 | 12 | import androidx.annotation.NonNull; 13 | import androidx.databinding.DataBindingUtil; 14 | import androidx.fragment.app.Fragment; 15 | 16 | import com.google.firebase.auth.FirebaseAuth; 17 | import com.google.firebase.auth.FirebaseUser; 18 | import com.google.firebase.database.DataSnapshot; 19 | import com.google.firebase.database.DatabaseError; 20 | import com.google.firebase.database.DatabaseReference; 21 | import com.google.firebase.database.FirebaseDatabase; 22 | import com.google.firebase.database.ValueEventListener; 23 | import com.sust.sustcast.LandingActivity; 24 | import com.sust.sustcast.R; 25 | import com.sust.sustcast.data.Config; 26 | import com.sust.sustcast.databinding.FragmentFeedbackBinding; 27 | 28 | import java.util.Objects; 29 | 30 | import static com.sust.sustcast.data.Constants.MAILBODY; 31 | import static com.sust.sustcast.data.Constants.MAILERROR; 32 | 33 | 34 | public class FeedbackFragment extends Fragment implements FirebaseAuth.AuthStateListener { 35 | private FirebaseAuth firebaseAuth; 36 | private DatabaseReference configRef; 37 | private ValueEventListener vListener; 38 | private String FACEBOOK_PAGE_ID; 39 | private String FACEBOOK_PAGE_LINK; 40 | private String MAILADDRESS; 41 | private String MAILSUBJECT; 42 | 43 | public FeedbackFragment() { 44 | } 45 | 46 | public static FeedbackFragment newInstance() { 47 | return new FeedbackFragment(); 48 | } 49 | 50 | @Override 51 | public void onCreate(Bundle savedInstanceState) { 52 | super.onCreate(savedInstanceState); 53 | } 54 | 55 | @Override 56 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 57 | FragmentFeedbackBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_feedback, container, false); 58 | firebaseAuth = FirebaseAuth.getInstance(); 59 | configRef = FirebaseDatabase.getInstance().getReference().child("config"); 60 | getConfig(); 61 | 62 | MAILADDRESS = Objects.requireNonNull(getActivity()).getString(R.string.mail_address); 63 | binding.setFeedbackFragment(this); 64 | return binding.getRoot(); 65 | } 66 | 67 | public void giveRate() { 68 | startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.sust.sustcast"))); 69 | 70 | } 71 | 72 | public Intent visitFacebook() { 73 | try { 74 | 75 | int versionCode = getContext().getPackageManager().getPackageInfo("com.facebook.katana", 0).versionCode; 76 | if (versionCode >= 3002850) { 77 | //newer versions of fb app 78 | return new Intent(Intent.ACTION_VIEW, Uri.parse("fb://facewebmodal/f?href=" + FACEBOOK_PAGE_LINK)); 79 | } else { //older versions of fb app 80 | return new Intent(Intent.ACTION_VIEW, Uri.parse("fb://page/" + FACEBOOK_PAGE_ID)); 81 | } 82 | 83 | } catch (PackageManager.NameNotFoundException e) { 84 | return new Intent(Intent.ACTION_VIEW, Uri.parse(FACEBOOK_PAGE_LINK)); 85 | } 86 | 87 | 88 | // getContext().getPackageManager().getPackageInfo(FACEBOOKAPP, 0); 89 | // return new Intent(Intent.ACTION_VIEW, Uri.parse(FACEBOOKAPPLINK)); 90 | // } catch (Exception e) { 91 | // return new Intent(Intent.ACTION_VIEW, Uri.parse(FACEBOOKLINK)); 92 | // } 93 | } 94 | 95 | private void getConfig() { 96 | vListener = configRef.addValueEventListener(new ValueEventListener() { 97 | @Override 98 | public void onDataChange(@NonNull DataSnapshot dataSnapshot) { 99 | Config config = dataSnapshot.getValue(Config.class); 100 | FACEBOOK_PAGE_ID = config.getPage_id(); 101 | FACEBOOK_PAGE_LINK = config.getPage_link(); 102 | MAILSUBJECT = config.getMail_subject(); 103 | 104 | } 105 | 106 | @Override 107 | public void onCancelled(@NonNull DatabaseError databaseError) { 108 | 109 | } 110 | }); 111 | } 112 | 113 | public void giveFeedback() { 114 | Intent emailIntent = new Intent(Intent.ACTION_SENDTO); 115 | emailIntent.setData(Uri.parse("mailto:" + MAILADDRESS)); 116 | emailIntent.putExtra(Intent.EXTRA_SUBJECT, MAILSUBJECT); 117 | emailIntent.putExtra(Intent.EXTRA_TEXT, MAILBODY); 118 | try { 119 | startActivity(Intent.createChooser(emailIntent, "Send email using...")); 120 | } catch (android.content.ActivityNotFoundException ex) { 121 | Toast.makeText(getContext(), MAILERROR, Toast.LENGTH_SHORT).show(); 122 | } 123 | } 124 | 125 | public void logOut() { 126 | firebaseAuth.signOut(); 127 | } 128 | 129 | @Override 130 | public void onStart() { 131 | super.onStart(); 132 | firebaseAuth.addAuthStateListener(this); 133 | } 134 | 135 | 136 | @Override 137 | public void onStop() { 138 | super.onStop(); 139 | firebaseAuth.removeAuthStateListener(this); 140 | } 141 | 142 | public void onDestroyView() { 143 | super.onDestroyView(); 144 | configRef.removeEventListener(vListener); 145 | 146 | } 147 | 148 | @Override 149 | public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { 150 | FirebaseUser firebaseUser = firebaseAuth.getCurrentUser(); 151 | if (firebaseUser == null) { 152 | startActivity(new Intent(getContext(), LandingActivity.class)); 153 | getActivity().finish(); 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/splash/SplashActivity.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.splash; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | 6 | import androidx.appcompat.app.AppCompatActivity; 7 | import androidx.lifecycle.ViewModelProvider; 8 | 9 | import com.sust.sustcast.LandingActivity; 10 | import com.sust.sustcast.fragment.FragmentHolder; 11 | 12 | public class SplashActivity extends AppCompatActivity { 13 | SplashViewModel splashViewModel; 14 | 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | 18 | splashViewModel = new ViewModelProvider(this).get(SplashViewModel.class); 19 | 20 | splashViewModel.checkAuthentication(); 21 | splashViewModel.checkAuthenticationLiveData.observe(this, user -> { 22 | if (!user.getAuthenticated()) { 23 | startActivity(new Intent(SplashActivity.this, LandingActivity.class)); 24 | finish(); 25 | } else { 26 | splashViewModel.getData(user.uid); 27 | splashViewModel.userData.observe(this, userData -> { 28 | startActivity(new Intent(SplashActivity.this, FragmentHolder.class)); 29 | finish(); 30 | }); 31 | } 32 | }); 33 | 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/splash/SplashRepository.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.splash; 2 | 3 | import androidx.lifecycle.MutableLiveData; 4 | 5 | import com.google.firebase.auth.FirebaseAuth; 6 | import com.google.firebase.auth.FirebaseUser; 7 | import com.google.firebase.firestore.CollectionReference; 8 | import com.google.firebase.firestore.DocumentSnapshot; 9 | import com.google.firebase.firestore.FirebaseFirestore; 10 | import com.sust.sustcast.data.User; 11 | 12 | import static com.sust.sustcast.data.Constants.USERS; 13 | 14 | public class SplashRepository { 15 | private FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(); 16 | private FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance(); 17 | private CollectionReference collectionReference = firebaseFirestore.collection(USERS); 18 | private User user = new User(); 19 | 20 | MutableLiveData checkAuthentication() { 21 | MutableLiveData authenticatedUserMutableLiveData = new MutableLiveData<>(); 22 | FirebaseUser firebaseUser = firebaseAuth.getCurrentUser(); 23 | 24 | if (firebaseUser == null) { 25 | user.setAuthenticated(false); 26 | } else { 27 | user.uid = firebaseUser.getUid(); 28 | user.setAuthenticated(true); 29 | } 30 | authenticatedUserMutableLiveData.setValue(user); 31 | return authenticatedUserMutableLiveData; 32 | } 33 | 34 | MutableLiveData userLiveData(String uid) { 35 | MutableLiveData authenticatedUserMutableLiveData = new MutableLiveData<>(); 36 | collectionReference.document(uid).get().addOnCompleteListener(dataTask -> { 37 | if (dataTask.isSuccessful()) { 38 | DocumentSnapshot documentSnapshot = dataTask.getResult(); 39 | assert documentSnapshot != null; 40 | if (documentSnapshot.exists()) { 41 | User user = documentSnapshot.toObject(User.class); 42 | authenticatedUserMutableLiveData.setValue(user); 43 | } 44 | } 45 | }); 46 | return authenticatedUserMutableLiveData; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/splash/SplashViewModel.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.splash; 2 | 3 | import android.app.Application; 4 | 5 | import androidx.lifecycle.AndroidViewModel; 6 | import androidx.lifecycle.LiveData; 7 | 8 | import com.sust.sustcast.data.User; 9 | 10 | public class SplashViewModel extends AndroidViewModel { 11 | LiveData checkAuthenticationLiveData; 12 | LiveData userData; 13 | private SplashRepository splashRepository; 14 | 15 | public SplashViewModel(Application application) { 16 | super(application); 17 | splashRepository = new SplashRepository(); 18 | } 19 | 20 | void checkAuthentication() { 21 | checkAuthenticationLiveData = splashRepository.checkAuthentication(); 22 | } 23 | 24 | void getData(String uid) { 25 | userData = splashRepository.userLiveData(uid); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/utils/ConnectionLiveData.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.utils; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.Context; 5 | import android.net.ConnectivityManager; 6 | import android.net.Network; 7 | import android.net.NetworkCapabilities; 8 | import android.net.NetworkInfo; 9 | import android.net.NetworkRequest; 10 | import android.os.Build; 11 | 12 | import androidx.annotation.NonNull; 13 | import androidx.lifecycle.LiveData; 14 | 15 | import com.google.firebase.crashlytics.FirebaseCrashlytics; 16 | 17 | public class ConnectionLiveData extends LiveData { 18 | 19 | private final ConnectivityManager connectivityManager; 20 | private ConnectivityManager.NetworkCallback connectivityManagerCallback; 21 | public static final String TAG = "ConnectionLiveData"; 22 | 23 | private final NetworkRequest.Builder networkRequestBuilder; 24 | 25 | 26 | @Override 27 | protected void onActive() { 28 | super.onActive(); 29 | updateConnection(); 30 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 31 | connectivityManager.registerDefaultNetworkCallback(getConnectivityMarshmallowManagerCallback()); 32 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 33 | marshmallowNetworkAvailableRequest(); 34 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 35 | lollipopNetworkAvailableRequest(); 36 | } 37 | } 38 | 39 | 40 | @Override 41 | protected void onInactive() { 42 | super.onInactive(); 43 | 44 | /* 45 | * 46 | * It is necessary to clean up the Callbacks. 47 | * 48 | */ 49 | 50 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 51 | try { 52 | connectivityManager.unregisterNetworkCallback(connectivityManagerCallback); 53 | } catch (Exception exception) { 54 | FirebaseCrashlytics.getInstance().recordException(exception); 55 | } 56 | } 57 | 58 | } 59 | 60 | public ConnectionLiveData(Context context) { 61 | connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 62 | networkRequestBuilder = new NetworkRequest.Builder() 63 | .addTransportType(android.net.NetworkCapabilities.TRANSPORT_CELLULAR) 64 | .addTransportType(android.net.NetworkCapabilities.TRANSPORT_WIFI); 65 | 66 | 67 | } 68 | 69 | private ConnectivityManager.NetworkCallback getConnectivityMarshmallowManagerCallback() { 70 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 71 | connectivityManagerCallback = new ConnectivityManager.NetworkCallback() { 72 | 73 | 74 | @Override 75 | public void onLost(@NonNull Network network) { 76 | postValue(false); 77 | } 78 | 79 | @Override 80 | public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) { 81 | if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) { 82 | postValue(true); 83 | } 84 | } 85 | }; 86 | return connectivityManagerCallback; 87 | } else { 88 | throw new IllegalAccessError("Accessing wrong API version"); 89 | } 90 | } 91 | 92 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 93 | private void lollipopNetworkAvailableRequest() { 94 | connectivityManager.registerNetworkCallback(networkRequestBuilder.build(), getConnectivityLollipopManagerCallback()); 95 | } 96 | 97 | @TargetApi(Build.VERSION_CODES.M) 98 | private void marshmallowNetworkAvailableRequest() { 99 | connectivityManager.registerNetworkCallback(networkRequestBuilder.build(), getConnectivityMarshmallowManagerCallback()); 100 | } 101 | 102 | private ConnectivityManager.NetworkCallback getConnectivityLollipopManagerCallback() { 103 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 104 | connectivityManagerCallback = new ConnectivityManager.NetworkCallback() { 105 | @Override 106 | public void onAvailable(@NonNull Network network) { 107 | postValue(true); 108 | } 109 | 110 | @Override 111 | public void onLost(@NonNull Network network) { 112 | postValue(false); 113 | } 114 | }; 115 | return connectivityManagerCallback; 116 | } else { 117 | throw new IllegalAccessError("Accessing wrong API version"); 118 | } 119 | } 120 | 121 | private void updateConnection() { 122 | NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo(); 123 | postValue(activeNetwork != null && activeNetwork.isConnected()); 124 | } 125 | 126 | 127 | } 128 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/utils/DataBindingAdapters.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.utils; 2 | 3 | import android.os.Build; 4 | import android.transition.TransitionManager; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import androidx.annotation.RequiresApi; 9 | import androidx.databinding.BindingAdapter; 10 | 11 | public class DataBindingAdapters { 12 | @RequiresApi(api = Build.VERSION_CODES.KITKAT) 13 | @BindingAdapter("android:animatedVisibility") 14 | public static void setAnimatedVisibility(View view, boolean isVisible) { 15 | TransitionManager.beginDelayedTransition((ViewGroup) view.getRootView()); 16 | if (isVisible) 17 | view.setVisibility(View.VISIBLE); 18 | else 19 | view.setVisibility(View.GONE); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/utils/FirebaseMessageReceiver.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.utils; 2 | 3 | import android.app.NotificationChannel; 4 | import android.app.NotificationManager; 5 | import android.app.PendingIntent; 6 | import android.content.Context; 7 | import android.content.Intent; 8 | import android.graphics.Color; 9 | import android.os.Build; 10 | import android.widget.RemoteViews; 11 | 12 | import androidx.annotation.NonNull; 13 | import androidx.core.app.NotificationCompat; 14 | 15 | import com.google.firebase.database.DatabaseReference; 16 | import com.google.firebase.database.FirebaseDatabase; 17 | import com.google.firebase.messaging.FirebaseMessagingService; 18 | import com.google.firebase.messaging.RemoteMessage; 19 | import com.sust.sustcast.R; 20 | import com.sust.sustcast.fragment.FragmentHolder; 21 | 22 | import static com.sust.sustcast.R.drawable.ic_small_notification_icon; 23 | import static com.sust.sustcast.R.drawable.sustcast_logo_circle_only; 24 | 25 | public class FirebaseMessageReceiver 26 | extends FirebaseMessagingService { 27 | private DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); 28 | private DatabaseReference tokenRef; 29 | @Override 30 | public void 31 | onMessageReceived(RemoteMessage remoteMessage) { 32 | 33 | if (remoteMessage.getNotification() != null) { 34 | showNotification( 35 | remoteMessage.getNotification().getTitle(), 36 | remoteMessage.getNotification().getBody()); 37 | } 38 | } 39 | @Override 40 | public void onNewToken(@NonNull String token) { 41 | tokenRef = rootRef.child("tokens"); 42 | tokenRef.push().setValue(token); 43 | } 44 | private RemoteViews getCustomDesign(String title, 45 | String message) { 46 | RemoteViews remoteViews = new RemoteViews( 47 | getApplicationContext().getPackageName(), 48 | R.layout.notification); 49 | remoteViews.setTextViewText(R.id.title, title); 50 | remoteViews.setTextViewText(R.id.message, message); 51 | 52 | return remoteViews; 53 | } 54 | 55 | public void showNotification(String title, 56 | String message) { 57 | Intent intent 58 | = new Intent(this, FragmentHolder.class); 59 | String channel_id = "notification_channel"; 60 | 61 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 62 | PendingIntent pendingIntent 63 | = PendingIntent.getActivity( 64 | this, 0, intent, 65 | PendingIntent.FLAG_ONE_SHOT); 66 | NotificationCompat.Builder builder 67 | = new NotificationCompat 68 | .Builder(getApplicationContext(), 69 | channel_id) 70 | .setSmallIcon(ic_small_notification_icon) 71 | .setColor(Color.parseColor("#FED500")) 72 | .setStyle(new NotificationCompat.BigTextStyle().bigText(message).setBigContentTitle(title)) 73 | .setAutoCancel(true) 74 | .setVibrate(new long[]{400, 400, 300, 75 | 400, 300}) 76 | .setOnlyAlertOnce(true) 77 | .setContentIntent(pendingIntent); 78 | System.out.println("BuildVersion : " + Build.VERSION.SDK_INT); 79 | builder = builder.setContentTitle(title) 80 | .setContentText(message) 81 | .setSmallIcon(ic_small_notification_icon) 82 | .setColor(Color.parseColor("#FED500")) 83 | .setPriority(2) 84 | .setStyle(new NotificationCompat.BigTextStyle().bigText(message).setBigContentTitle(title)); 85 | 86 | NotificationManager notificationManager 87 | = (NotificationManager) getSystemService( 88 | Context.NOTIFICATION_SERVICE); 89 | if (Build.VERSION.SDK_INT 90 | >= Build.VERSION_CODES.O) { 91 | NotificationChannel notificationChannel 92 | = new NotificationChannel( 93 | channel_id, "web_app", 94 | NotificationManager.IMPORTANCE_HIGH); 95 | notificationManager.createNotificationChannel( 96 | notificationChannel); 97 | } 98 | notificationManager.notify(0, builder.build()); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/utils/FontHelper.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.utils; 2 | 3 | import android.content.Context; 4 | import android.content.res.Configuration; 5 | import android.util.DisplayMetrics; 6 | import android.util.Log; 7 | import android.view.WindowManager; 8 | 9 | import static android.content.Context.WINDOW_SERVICE; 10 | 11 | public class FontHelper { 12 | public static void adjustFontScale(Context context, Configuration configuration) { 13 | if (configuration.fontScale != 1.00) { 14 | Log.w("FONT", "fontScale=" + configuration.fontScale); 15 | configuration.fontScale = (float) 1.00; 16 | DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 17 | WindowManager wm = (WindowManager) context.getSystemService(WINDOW_SERVICE); 18 | wm.getDefaultDisplay().getMetrics(metrics); 19 | metrics.scaledDensity = configuration.fontScale * metrics.density; 20 | context.getApplicationContext().getResources().updateConfiguration(configuration, metrics); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/utils/LoadBalancingUtil.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.utils; 2 | 3 | import com.sust.sustcast.data.IceUrl; 4 | 5 | import java.util.List; 6 | 7 | public class LoadBalancingUtil { 8 | 9 | public static IceUrl selectIceCastSource(List iceUrlList){ 10 | IceUrl bestIceUrl = new IceUrl(); 11 | 12 | float minLoad = Float.MAX_VALUE; 13 | 14 | for(IceUrl iceUrl : iceUrlList){ 15 | int limit = iceUrl.getLimit(); 16 | String url = iceUrl.getUrl(); 17 | int numList = iceUrl.getNumlisteners(); 18 | 19 | float load = (float) numList / (float) limit; 20 | 21 | if (load < 1 && load < minLoad) { 22 | minLoad = load; 23 | bestIceUrl = iceUrl; 24 | } 25 | } 26 | 27 | return bestIceUrl; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/sust/sustcast/utils/StringValidationRules.java: -------------------------------------------------------------------------------- 1 | package com.sust.sustcast.utils; 2 | 3 | import android.text.Editable; 4 | import android.text.TextUtils; 5 | import android.util.Patterns; 6 | 7 | public class StringValidationRules { 8 | public static StringRule NOT_EMPTY = s -> TextUtils.isEmpty(s.toString()); 9 | public static StringRule EMAIL = s -> !android.util.Patterns.EMAIL_ADDRESS.matcher(s).matches(); 10 | public static StringRule PASSWORD = s -> s.length() < 6; 11 | public static StringRule PHONE = s -> !Patterns.PHONE.matcher(s).matches(); 12 | 13 | public interface StringRule { 14 | boolean validate(Editable s); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_small_notification_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustcast/sustcast-android-app-v1/1d42b1c696ff2a082062dd9d280a87cbeb8839e0/app/src/main/res/drawable-hdpi/ic_small_notification_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_small_notification_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustcast/sustcast-android-app-v1/1d42b1c696ff2a082062dd9d280a87cbeb8839e0/app/src/main/res/drawable-mdpi/ic_small_notification_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/bottom_navigation_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/bottom_navigation_color_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/extras.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/facebook.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/feedback.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/google_play.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/log_out.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/news.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/news_bottom_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/pause_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/play_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/splash_screen_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/stream.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | 27 | 30 | 33 | 36 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v23/stream_bottom_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | 27 | 30 | 33 | 36 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/bottom_navigation_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/bottom_navigation_color_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | \ 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/extras.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/facebook.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/feedback.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/google_play.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/log_out.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/news.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/news_bottom_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/pause_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/play_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/stream.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | 27 | 30 | 33 | 36 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/stream_bottom_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | 27 | 30 | 33 | 36 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_small_notification_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustcast/sustcast-android-app-v1/1d42b1c696ff2a082062dd9d280a87cbeb8839e0/app/src/main/res/drawable-xhdpi/ic_small_notification_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_small_notification_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustcast/sustcast-android-app-v1/1d42b1c696ff2a082062dd9d280a87cbeb8839e0/app/src/main/res/drawable-xxhdpi/ic_small_notification_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_small_notification_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustcast/sustcast-android-app-v1/1d42b1c696ff2a082062dd9d280a87cbeb8839e0/app/src/main/res/drawable-xxxhdpi/ic_small_notification_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button_text_white_yellow_active_pressed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button_white_yellow_active_pressed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_oval_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bottom_navigation_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bottom_navigation_color_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_rounded.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/extras.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/facebook.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/feedback.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/google_play.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_login_rectangle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_rectangle_white_with_yellow_border.xml: -------------------------------------------------------------------------------- 1 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_signup_rectangle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/line_contributors.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/line_landing.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/line_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/log_out.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/news.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/news_bottom_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/pause_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/play_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/rounded_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/splash_screen_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/stream.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | 27 | 30 | 33 | 36 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/stream_bottom_button.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 18 | 21 | 24 | 27 | 30 | 33 | 36 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/font-v26/kollektif_family.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/font/kollektif.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustcast/sustcast-android-app-v1/1d42b1c696ff2a082062dd9d280a87cbeb8839e0/app/src/main/res/font/kollektif.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/kollektif_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustcast/sustcast-android-app-v1/1d42b1c696ff2a082062dd9d280a87cbeb8839e0/app/src/main/res/font/kollektif_bold.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/kollektif_boldtalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustcast/sustcast-android-app-v1/1d42b1c696ff2a082062dd9d280a87cbeb8839e0/app/src/main/res/font/kollektif_boldtalic.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/kollektif_family.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/font/kollektif_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sustcast/sustcast-android-app-v1/1d42b1c696ff2a082062dd9d280a87cbeb8839e0/app/src/main/res/font/kollektif_italic.ttf -------------------------------------------------------------------------------- /app/src/main/res/layout-v21/activity_landing.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 17 | 18 | 24 | 25 | 35 | 36 | 37 | 45 | 46 | 58 | 59 |