├── .gitattributes ├── .gitignore ├── .idea ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── gradle.xml ├── jarRepositories.xml ├── misc.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── instaapp │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── ic_addStory-playstore.png │ ├── ic_launcher-playstore.png │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── instaapp │ │ │ ├── AccountSettings.kt │ │ │ ├── Adapter │ │ │ ├── CommentAdapter.kt │ │ │ ├── MyPostAdapter.kt │ │ │ ├── NotificationAdapter.kt │ │ │ ├── PostAdapter.kt │ │ │ ├── StoryAdapter.kt │ │ │ └── UserAdapter.kt │ │ │ ├── AddCommentActivity.kt │ │ │ ├── AddPostActivity.kt │ │ │ ├── AddStoryActivity.kt │ │ │ ├── Fragments │ │ │ ├── HomeFragment.kt │ │ │ ├── NotificationFragment.kt │ │ │ ├── PostDetailFragment.kt │ │ │ ├── ProfileFragment.kt │ │ │ └── SearchFragment.kt │ │ │ ├── LoginActivity.kt │ │ │ ├── MainActivity.kt │ │ │ ├── Model │ │ │ ├── Comment.kt │ │ │ ├── Notification.kt │ │ │ ├── Post.kt │ │ │ ├── Story.kt │ │ │ └── User.kt │ │ │ ├── ShowUsersActivity.kt │ │ │ ├── SignUpActivity.kt │ │ │ ├── SplashScreenActivity.kt │ │ │ └── StoryActivity.kt │ └── res │ │ ├── drawable │ │ ├── add.png │ │ ├── add_image_icon.png │ │ ├── app_ic.png │ │ ├── back_ui.png │ │ ├── button_black_background.xml │ │ ├── buttons_background.xml │ │ ├── camera.png │ │ ├── close.png │ │ ├── comment.png │ │ ├── download.png │ │ ├── grid.png │ │ ├── heart.png │ │ ├── heart_clicked.png │ │ ├── heart_not_clicked.png │ │ ├── home.png │ │ ├── ic_addstory_background.xml │ │ ├── ic_addstory_foreground.xml │ │ ├── ic_dashboard_black_24dp.xml │ │ ├── ic_home_black_24dp.xml │ │ ├── ic_notifications_black_24dp.xml │ │ ├── inputs_background.xml │ │ ├── instagram.png │ │ ├── instagramlogo.png │ │ ├── itv.png │ │ ├── itv2.png │ │ ├── itv24.png │ │ ├── itv64.png │ │ ├── metalogo.png │ │ ├── options.png │ │ ├── profile.png │ │ ├── profile_icon.png │ │ ├── round_btn.xml │ │ ├── save_edited_info.png │ │ ├── save_large_icon.png │ │ ├── save_post_unfilled.png │ │ ├── save_unfilled_large_icon.png │ │ ├── saved_post_filled.png │ │ ├── search.png │ │ ├── send_icon.png │ │ ├── tagged.png │ │ ├── taggedpost.png │ │ └── vertical_view.png │ │ ├── font │ │ └── arimo.ttf │ │ ├── layout │ │ ├── activity_account_settings.xml │ │ ├── activity_add_comment.xml │ │ ├── activity_add_post.xml │ │ ├── activity_add_story.xml │ │ ├── activity_login.xml │ │ ├── activity_main.xml │ │ ├── activity_show_users.xml │ │ ├── activity_sign_up.xml │ │ ├── activity_splash_screen.xml │ │ ├── activity_story.xml │ │ ├── add_story_item.xml │ │ ├── comment_item_layout.xml │ │ ├── fragment_home.xml │ │ ├── fragment_notification.xml │ │ ├── fragment_post_detail.xml │ │ ├── fragment_profile.xml │ │ ├── fragment_search.xml │ │ ├── mypost_layout.xml │ │ ├── notification_item.xml │ │ ├── posts_layout.xml │ │ ├── story_item.xml │ │ └── user_item_layout.xml │ │ ├── menu │ │ └── bottom_nav_menu.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── navigation │ │ └── mobile_navigation.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── example │ └── instaapp │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── instagram (1).png └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | xmlns:android 17 | 18 | ^$ 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | xmlns:.* 28 | 29 | ^$ 30 | 31 | 32 | BY_NAME 33 | 34 |
35 |
36 | 37 | 38 | 39 | .*:id 40 | 41 | http://schemas.android.com/apk/res/android 42 | 43 | 44 | 45 |
46 |
47 | 48 | 49 | 50 | .*:name 51 | 52 | http://schemas.android.com/apk/res/android 53 | 54 | 55 | 56 |
57 |
58 | 59 | 60 | 61 | name 62 | 63 | ^$ 64 | 65 | 66 | 67 |
68 |
69 | 70 | 71 | 72 | style 73 | 74 | ^$ 75 | 76 | 77 | 78 |
79 |
80 | 81 | 82 | 83 | .* 84 | 85 | ^$ 86 | 87 | 88 | BY_NAME 89 | 90 |
91 |
92 | 93 | 94 | 95 | .* 96 | 97 | http://schemas.android.com/apk/res/android 98 | 99 | 100 | ANDROID_ATTRIBUTE_ORDER 101 | 102 |
103 |
104 | 105 | 106 | 107 | .* 108 | 109 | .* 110 | 111 | 112 | BY_NAME 113 | 114 |
115 |
116 |
117 |
118 | 119 | 121 |
122 |
-------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

HTML5 logo 2 |

3 |

🎉 A social media app built with Kotlin (Android Studio) with multiple features

4 | 5 | ### ▷ Screenshots: 6 | 7 | ![splash](https://user-images.githubusercontent.com/99815527/170834196-6c5e96c0-0432-4a47-9874-bf2ff5427fb4.jpg) 8 | ![login](https://user-images.githubusercontent.com/99815527/170835571-312e4765-3509-41c9-b95c-d702573f99d7.jpg) 9 | ![register](https://user-images.githubusercontent.com/99815527/170835006-5ec5e936-37e6-4b72-b2fe-27a4f2e87576.jpg) 10 | ![home](https://user-images.githubusercontent.com/99815527/170835010-efed8645-5785-45b9-b23e-74b9d2954dd7.jpg) 11 | ![story](https://user-images.githubusercontent.com/99815527/170835053-a9652e34-3b1a-42a1-9a35-c680750be058.jpg) 12 | ![detail](https://user-images.githubusercontent.com/99815527/170835593-44826e50-e3ef-409e-be7a-038cf07dc744.jpg) 13 | ![comment](https://user-images.githubusercontent.com/99815527/170835225-4d04217a-cc10-4332-b1cf-6dbfd460d989.jpg) 14 | ![search](https://user-images.githubusercontent.com/99815527/170835059-4630cc8e-9066-4c8c-9f4a-964cb28d59ae.jpg) 15 | ![follow](https://user-images.githubusercontent.com/99815527/170835612-7babfac6-788b-4e73-9604-9f75019061f2.jpg) 16 | ![notification](https://user-images.githubusercontent.com/99815527/170835097-d0af36b4-206a-4cca-9111-4b2499162d4c.jpg) 17 | ![profile](https://user-images.githubusercontent.com/99815527/170835107-051406e7-badc-46cb-ab25-6d7497299400.jpg) 18 | ![accountsetting](https://user-images.githubusercontent.com/99815527/170835113-5c9ca065-ad2e-4fe3-80b9-b8e2edf70cb6.jpg) 19 | 20 | 21 | 22 | ### ▷ Features: 23 | 24 | - Sign up using Firebase Authentication & save user data to Firebase Database. 25 | - Sign in using Firebase. 26 | - Create profile. 27 | - Account setting. 28 | - Search users. 29 | - Follow and Unfollow users on Search Fragment. 30 | - Navigate user from Search Page to searched user Profile. 31 | - Allow an Online user to Edit Account Info. 32 | - Upload image to Firebase Storage & Firebase Database and Retrieve & Display. 33 | - Upload new post picture. 34 | - User Timeline. 35 | - Likes and Total Number of Likes. 36 | - Add Comments on Pictures. 37 | - Retrieve and Display Comments & Total Number of Comments. 38 | - Display user Own Posts on User's Profile Page. 39 | - Navigate user to Post Details Fragment from Profile Fragment. 40 | - Display Total Number of Posts & Allow user Save Photos to Collection on Profile. 41 | - Display user Saved Images Collection on user Profile. 42 | - Display Followings List, Followers List and Picture Likes. 43 | - Add anf Display Notifications for Likes, Comments & Followings. 44 | - Upload Stories. 45 | - Implement Story Features - Next Story, Previous Sory, Display Viewed by People. 46 | - Manage UI for Already Seen Stories & for New Stories. 47 | 48 | ### ▷ About Application: 49 | 50 | ▷ Create an android app like instagram 51 | 52 | ▷ Tools Used In this Project: 53 | - Android Studio; 54 | - Firebase: 55 | - Realtime database 56 | - Authentication 57 | - Storage 58 | 59 | ▷ Libraries Used In this Project: 60 | - com.theartofdev.edmodo:android-image-cropper:2.8.0 61 | - com.github.shts:StoriesProgressView:3.0.0 62 | - com.squareup.picasso:picasso:2.71828 63 | - de.hdodenhof:circleimageview:3.1.0 64 | 65 | PS: If you're going to download the full project please use your on firebase API, the one in the project will NOT be mantained and the app may not work. 66 | 67 | ### ▷ Installation: 68 | 69 | #### 1. [Setup Android Studio & Kotlin](https://developer.android.com/studio/install) 70 | 71 | #### 2. Clone the repo 72 | 73 | - !!!!IMPORTANT!!!! Change the Package Name. You can check how to do that here (https://stackoverflow.com/questions/16804093/android-studio-rename-package)
74 | 75 | #### 3. Setup the firebase app 76 | 77 | - You'll need to create a Firebase instance. Follow the instructions at https://console.firebase.google.com. 78 | - Once your Firebase instance is created, you'll need to enable Google authentication. 79 | 80 | * Go to the Firebase Console for your new instance. 81 | * Click "Authentication" in the left-hand menu 82 | * Click the "sign-in method" tab 83 | * Click "Email and Password" and enable it 84 | * Create an app within your Firebase instance for Android, with package name com.yourcompany.news 85 | * Follow instructions to download google-services.json 86 | * place `google-services.json` into `/android/app/`. 87 | * Create an app within your Firebase instance for Android, with your app package name 88 | 89 | - You can also use my firebase if you wish! 90 | 91 | ### ▷ Author: F.O.G_ntp(nguyenthanhphong) 92 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 30 7 | buildToolsVersion "30.0.2" 8 | 9 | defaultConfig { 10 | applicationId "com.example.instaapp" 11 | minSdkVersion 19 12 | targetSdkVersion 30 13 | versionCode 1 14 | versionName "1.0" 15 | multiDexEnabled true 16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | compileOptions { 26 | sourceCompatibility JavaVersion.VERSION_1_8 27 | targetCompatibility JavaVersion.VERSION_1_8 28 | } 29 | kotlinOptions { 30 | jvmTarget = '1.8' 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation fileTree(dir: "libs", include: ["*.jar"]) 36 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 37 | implementation 'androidx.core:core-ktx:1.3.2' 38 | implementation 'androidx.appcompat:appcompat:1.2.0' 39 | implementation 'com.google.android.material:material:1.0.0' 40 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4' 41 | implementation 'androidx.vectordrawable:vectordrawable:1.1.0' 42 | implementation 'androidx.navigation:navigation-fragment:2.1.0' 43 | implementation 'androidx.navigation:navigation-ui:2.1.0' 44 | implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' 45 | implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0' 46 | implementation 'androidx.navigation:navigation-ui-ktx:2.1.0' 47 | implementation 'androidx.legacy:legacy-support-v4:1.0.0' 48 | implementation 'de.hdodenhof:circleimageview:3.1.0' 49 | implementation 'com.github.shts:StoriesProgressView:3.0.0' 50 | implementation platform('com.google.firebase:firebase-bom:30.0.1') 51 | implementation 'com.google.firebase:firebase-analytics-ktx' 52 | implementation 'com.google.firebase:firebase-auth-ktx' 53 | implementation 'com.google.firebase:firebase-database-ktx' 54 | implementation 'com.google.firebase:firebase-storage-ktx' 55 | implementation 'com.squareup.picasso:picasso:2.71828' 56 | implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0' 57 | implementation 'com.github.shts:StoriesProgressView:3.0.0' 58 | implementation 'com.android.support:multidex:2.0.0' 59 | testImplementation 'junit:junit:4.12' 60 | androidTestImplementation 'androidx.test.ext:junit:1.1.2' 61 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' 62 | 63 | } 64 | //connects to firebase 65 | apply plugin: 'com.google.gms.google-services' -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "48789833762", 4 | "project_id": "instagram-clone-app-205f9", 5 | "storage_bucket": "instagram-clone-app-205f9.appspot.com" 6 | }, 7 | "client": [ 8 | { 9 | "client_info": { 10 | "mobilesdk_app_id": "1:48789833762:android:3d581826bde2e13d21a27b", 11 | "android_client_info": { 12 | "package_name": "com.example.instaapp" 13 | } 14 | }, 15 | "oauth_client": [ 16 | { 17 | "client_id": "48789833762-lsjo3gcm8jgu5h6g8ggu8oq9f7l5dfig.apps.googleusercontent.com", 18 | "client_type": 3 19 | } 20 | ], 21 | "api_key": [ 22 | { 23 | "current_key": "AIzaSyDxGb5kSeh9ooqX7CWFziDJXVHO15lWMtY" 24 | } 25 | ], 26 | "services": { 27 | "appinvite_service": { 28 | "other_platform_oauth_client": [ 29 | { 30 | "client_id": "48789833762-lsjo3gcm8jgu5h6g8ggu8oq9f7l5dfig.apps.googleusercontent.com", 31 | "client_type": 3 32 | } 33 | ] 34 | } 35 | } 36 | } 37 | ], 38 | "configuration_version": "1" 39 | } -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/instaapp/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.example.instaapp", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 41 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/ic_addStory-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/ic_addStory-playstore.png -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/AccountSettings.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp 2 | 3 | import android.app.Activity 4 | import android.app.ProgressDialog 5 | import android.content.Intent 6 | import android.net.Uri 7 | import androidx.appcompat.app.AppCompatActivity 8 | import android.os.Bundle 9 | import android.text.TextUtils 10 | import android.widget.Toast 11 | import com.example.instaapp.Model.User 12 | import com.google.android.gms.tasks.Continuation 13 | import com.google.android.gms.tasks.OnCompleteListener 14 | import com.google.android.gms.tasks.Task 15 | import com.google.firebase.auth.FirebaseAuth 16 | import com.google.firebase.auth.FirebaseUser 17 | import com.google.firebase.database.* 18 | import com.google.firebase.storage.FirebaseStorage 19 | import com.google.firebase.storage.StorageReference 20 | import com.google.firebase.storage.StorageTask 21 | import com.google.firebase.storage.UploadTask 22 | import com.squareup.picasso.Picasso 23 | import com.theartofdev.edmodo.cropper.CropImage 24 | import kotlinx.android.synthetic.main.activity_account_settings.* 25 | 26 | class AccountSettings : AppCompatActivity() { 27 | 28 | private lateinit var firebaseUser: FirebaseUser 29 | private var checker="" 30 | private var myUrl="" 31 | private var imageUri: Uri?=null 32 | private var storageProfileRef:StorageReference?=null 33 | 34 | override fun onCreate(savedInstanceState: Bundle?) { 35 | super.onCreate(savedInstanceState) 36 | setContentView(R.layout.activity_account_settings) 37 | 38 | firebaseUser = FirebaseAuth.getInstance().currentUser!! 39 | storageProfileRef = FirebaseStorage.getInstance().reference.child("Profile Pictures") 40 | getUserInfo() 41 | 42 | accountSettings_logoutbtn.setOnClickListener { 43 | FirebaseAuth.getInstance().signOut() 44 | 45 | val intent = Intent(this@AccountSettings, LoginActivity::class.java) 46 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) 47 | startActivity(intent) 48 | finish() 49 | } 50 | 51 | close_button.setOnClickListener { 52 | val intent=Intent(this@AccountSettings,MainActivity::class.java) 53 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) 54 | startActivity(intent) 55 | finish() 56 | } 57 | 58 | 59 | accountSettings_change_profile.setOnClickListener { 60 | checker="clicked" 61 | 62 | CropImage.activity() 63 | .setAspectRatio(1,1) 64 | .start(this@AccountSettings) 65 | } 66 | 67 | save_edited_info.setOnClickListener { 68 | if (checker == "clicked") 69 | { 70 | uploadProfileImageandInfo() 71 | } 72 | else 73 | { 74 | updateUserInfoOnly() 75 | } 76 | 77 | } 78 | } 79 | 80 | private fun uploadProfileImageandInfo() { 81 | 82 | when { 83 | imageUri == null -> Toast.makeText(this, "Please select image", Toast.LENGTH_SHORT) 84 | .show() 85 | 86 | TextUtils.isEmpty(accountSettings_fullname_profile.text.toString()) -> { 87 | Toast.makeText(this, "Full Name is required", Toast.LENGTH_SHORT).show() 88 | } 89 | TextUtils.isEmpty(accountSettings_username_profile.text.toString()) -> { 90 | Toast.makeText(this, "Username is required", Toast.LENGTH_SHORT).show() 91 | } 92 | else -> { 93 | val progressDialog=ProgressDialog(this) 94 | progressDialog.setTitle("Profile Settings") 95 | progressDialog.setMessage("Please wait! Updating...") 96 | progressDialog.show() 97 | 98 | val fileRef = storageProfileRef!!.child(firebaseUser!!.uid+ ".png") 99 | 100 | val uploadTask: StorageTask<*> 101 | uploadTask = fileRef.putFile(imageUri!!) 102 | 103 | uploadTask.continueWithTask(Continuation> { task -> 104 | if (!task.isSuccessful) 105 | { 106 | task.exception?.let { 107 | throw it 108 | Toast.makeText(this, "exception:--"+it, Toast.LENGTH_SHORT).show() 109 | progressDialog.dismiss() 110 | } 111 | } 112 | return@Continuation fileRef.downloadUrl 113 | }).addOnCompleteListener ( OnCompleteListener{task -> 114 | if(task.isSuccessful) 115 | { 116 | val downloadUrl=task.result 117 | myUrl=downloadUrl.toString() 118 | 119 | val ref=FirebaseDatabase.getInstance().reference.child("Users") 120 | val userMap = HashMap() 121 | userMap["fullname"] = accountSettings_fullname_profile.text.toString() 122 | userMap["username"] = accountSettings_username_profile.text.toString().toLowerCase() 123 | userMap["bio"] = accountSettings_bio_profile.text.toString() 124 | userMap["image"] = myUrl 125 | 126 | ref.child(firebaseUser.uid).updateChildren(userMap) 127 | Toast.makeText(this, "Account is updated", Toast.LENGTH_SHORT).show() 128 | 129 | val intent=Intent(this@AccountSettings,MainActivity::class.java) 130 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) 131 | startActivity(intent) 132 | finish() 133 | progressDialog.dismiss() 134 | 135 | } 136 | else { 137 | progressDialog.dismiss() 138 | } 139 | } ) 140 | } 141 | } 142 | } 143 | 144 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 145 | super.onActivityResult(requestCode, resultCode, data) 146 | if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE ) { 147 | if (resultCode == Activity.RESULT_OK) { 148 | val result = CropImage.getActivityResult(data) 149 | if (data != null){ 150 | imageUri= result.uri 151 | accountSettings_image_profile.setImageURI(imageUri) 152 | } 153 | // } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) { 154 | // val error = result.error 155 | } 156 | } 157 | } 158 | 159 | private fun updateUserInfoOnly() { 160 | 161 | when { 162 | TextUtils.isEmpty(accountSettings_fullname_profile.text.toString()) -> { 163 | Toast.makeText(this, "Full Name is required", Toast.LENGTH_SHORT).show() 164 | } 165 | TextUtils.isEmpty(accountSettings_username_profile.text.toString()) -> { 166 | Toast.makeText(this, "username is required", Toast.LENGTH_SHORT).show() 167 | } 168 | else -> { 169 | val userRef: DatabaseReference = FirebaseDatabase.getInstance().reference.child("Users") 170 | //using hashmap to store values 171 | val userMap = HashMap() 172 | userMap["fullname"] = accountSettings_fullname_profile.text.toString() 173 | userMap["username"] = accountSettings_username_profile.text.toString().toLowerCase() 174 | userMap["bio"] = accountSettings_bio_profile.text.toString() 175 | 176 | userRef.child(firebaseUser.uid).updateChildren(userMap) 177 | 178 | Toast.makeText(this, "Account is updated", Toast.LENGTH_SHORT).show() 179 | 180 | val intent=Intent(this@AccountSettings,MainActivity::class.java) 181 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) 182 | startActivity(intent) 183 | finish() 184 | } 185 | } 186 | } 187 | 188 | private fun getUserInfo() { 189 | val usersRef = FirebaseDatabase.getInstance().reference.child("Users").child(firebaseUser.uid) 190 | usersRef.addValueEventListener(object : ValueEventListener { 191 | override fun onCancelled(error: DatabaseError) { 192 | } 193 | override fun onDataChange(snapshot: DataSnapshot) { 194 | 195 | if (snapshot.exists()) { 196 | val user = snapshot.getValue(User::class.java) 197 | 198 | Picasso.get().load(user!!.getImage()).placeholder(R.drawable.profile).into(accountSettings_image_profile) 199 | accountSettings_fullname_profile?.setText(user.getFullname()) 200 | accountSettings_username_profile?.setText(user.getUsername()) 201 | accountSettings_bio_profile?.setText(user.getBio()) 202 | 203 | } 204 | } 205 | }) 206 | } 207 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Adapter/CommentAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Adapter 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.util.Log 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import android.widget.ImageView 10 | import android.widget.TextView 11 | import androidx.annotation.NonNull 12 | import androidx.recyclerview.widget.RecyclerView 13 | import com.example.instaapp.MainActivity 14 | import com.example.instaapp.Model.Comment 15 | import com.example.instaapp.Model.User 16 | import com.example.instaapp.R 17 | import com.google.firebase.auth.FirebaseAuth 18 | import com.google.firebase.auth.FirebaseUser 19 | import com.google.firebase.database.DataSnapshot 20 | import com.google.firebase.database.DatabaseError 21 | import com.google.firebase.database.FirebaseDatabase 22 | import com.google.firebase.database.ValueEventListener 23 | import com.squareup.picasso.Picasso 24 | import de.hdodenhof.circleimageview.CircleImageView 25 | 26 | class CommentAdapter(private var mContext: Context, 27 | private var mComment:List): RecyclerView.Adapter() { 28 | 29 | private var firebaseUser: FirebaseUser? = null 30 | 31 | inner class ViewHolder(@NonNull itemView: View) : RecyclerView.ViewHolder(itemView) { 32 | var profileImage: CircleImageView 33 | var publisher: TextView 34 | var publisher_comment: TextView 35 | 36 | 37 | init { 38 | profileImage = itemView.findViewById(R.id.publisher_image_profile) 39 | publisher = itemView.findViewById(R.id.publisher_username) 40 | publisher_comment = itemView.findViewById(R.id.publisher_caption) 41 | } 42 | 43 | } 44 | 45 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { 46 | val view = 47 | LayoutInflater.from(mContext).inflate(R.layout.comment_item_layout, parent, false) 48 | return ViewHolder(view) 49 | } 50 | 51 | override fun getItemCount(): Int { 52 | return mComment.size 53 | } 54 | 55 | override fun onBindViewHolder(holder: ViewHolder, position: Int) { 56 | 57 | firebaseUser = FirebaseAuth.getInstance().currentUser 58 | val comment = mComment[position] 59 | 60 | if(comment.getComment()!="") 61 | holder.publisher_comment.text=(comment.getComment()) 62 | 63 | publisherInfo(holder.profileImage, holder.publisher, comment.getPublisher()) 64 | 65 | holder.publisher.setOnClickListener { 66 | 67 | val intent = Intent(mContext, MainActivity::class.java).apply { 68 | putExtra("PUBLISHER_ID", comment.getPublisher()) 69 | } 70 | mContext.startActivity(intent) 71 | } 72 | 73 | holder.profileImage.setOnClickListener { 74 | 75 | val intent = Intent(mContext, MainActivity::class.java).apply { 76 | putExtra("PUBLISHER_ID", comment.getPublisher()) 77 | } 78 | mContext.startActivity(intent) 79 | } 80 | } 81 | 82 | private fun publisherInfo(profileImage: CircleImageView, username: TextView, publisherID: String) { 83 | 84 | val userRef= FirebaseDatabase.getInstance().reference.child("Users").child(publisherID) 85 | userRef.addValueEventListener(object : ValueEventListener 86 | { 87 | override fun onCancelled(error: DatabaseError) { 88 | 89 | } 90 | 91 | override fun onDataChange(snapshot: DataSnapshot) { 92 | if(snapshot.exists()) 93 | { 94 | val user = snapshot.getValue(User::class.java) 95 | 96 | Picasso.get().load(user!!.getImage()).placeholder(R.drawable.profile).into(profileImage) 97 | username.text =(user.getUsername()) 98 | } 99 | } 100 | 101 | }) 102 | } 103 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Adapter/MyPostAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Adapter 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.content.SharedPreferences 6 | import android.provider.Settings.Global.putString 7 | import android.view.LayoutInflater 8 | import android.view.View 9 | import android.view.ViewGroup 10 | import android.widget.ImageView 11 | import androidx.annotation.NonNull 12 | import androidx.fragment.app.FragmentActivity 13 | import androidx.recyclerview.widget.RecyclerView 14 | import com.example.instaapp.Fragments.PostDetailFragment 15 | import com.example.instaapp.Fragments.ProfileFragment 16 | import com.example.instaapp.MainActivity 17 | import com.example.instaapp.Model.Post 18 | import com.example.instaapp.R 19 | import com.squareup.picasso.Picasso 20 | import kotlinx.android.synthetic.main.mypost_layout.view.* 21 | 22 | class MyPostAdapter(private val mContext: Context, private val mPost:List): RecyclerView.Adapter() { 23 | 24 | inner class ViewHolder(@NonNull itemView: View) : RecyclerView.ViewHolder(itemView) 25 | { 26 | var postedImg: ImageView 27 | init 28 | { 29 | postedImg = itemView.findViewById(R.id.my_posted_picture) 30 | } 31 | } 32 | 33 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { 34 | val view= LayoutInflater.from(mContext).inflate(R.layout.mypost_layout,parent,false) 35 | return ViewHolder(view) 36 | } 37 | 38 | override fun getItemCount(): Int { 39 | return mPost.size 40 | } 41 | 42 | override fun onBindViewHolder(holder: ViewHolder, position: Int) { 43 | val post=mPost[position] 44 | 45 | Picasso.get().load(post.getPostImage()).into(holder.postedImg) 46 | holder.postedImg.setOnClickListener { 47 | 48 | val pref=mContext.getSharedPreferences("PREFS",Context.MODE_PRIVATE).edit() 49 | pref.putString("postid",post.getPostId()) 50 | pref.apply() 51 | 52 | (mContext as FragmentActivity).supportFragmentManager.beginTransaction() 53 | .replace(R.id.fragment_container, PostDetailFragment()).commit() 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Adapter/NotificationAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Adapter 2 | 3 | import android.content.Context 4 | import android.util.Log 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.ImageView 9 | import android.widget.TextView 10 | import androidx.annotation.NonNull 11 | import androidx.fragment.app.FragmentActivity 12 | import androidx.recyclerview.widget.RecyclerView 13 | import com.example.instaapp.Fragments.PostDetailFragment 14 | import com.example.instaapp.Fragments.ProfileFragment 15 | import com.example.instaapp.Model.Notification 16 | import com.example.instaapp.Model.Post 17 | import com.example.instaapp.Model.User 18 | import com.example.instaapp.R 19 | import com.google.firebase.database.DataSnapshot 20 | import com.google.firebase.database.DatabaseError 21 | import com.google.firebase.database.FirebaseDatabase 22 | import com.google.firebase.database.ValueEventListener 23 | import com.squareup.picasso.Picasso 24 | import de.hdodenhof.circleimageview.CircleImageView 25 | 26 | class NotificationAdapter( 27 | private var mContext: Context, 28 | private var mNotification:List) 29 | : RecyclerView.Adapter() { 30 | 31 | 32 | class ViewHolder(@NonNull itemView: View) : RecyclerView.ViewHolder(itemView) { 33 | 34 | var username: TextView = itemView.findViewById(R.id.notification_username) 35 | var notifyText: TextView = itemView.findViewById(R.id.notification_text) 36 | var profileimage: CircleImageView = itemView.findViewById(R.id.notification_image_profile) 37 | var postimg: ImageView = itemView.findViewById(R.id.posted_image) 38 | } 39 | 40 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { 41 | val view= LayoutInflater.from(mContext).inflate(R.layout.notification_item,parent,false) 42 | return ViewHolder(view) 43 | } 44 | 45 | override fun getItemCount(): Int { 46 | return mNotification.size 47 | } 48 | 49 | override fun onBindViewHolder(holder: ViewHolder, position: Int) { 50 | 51 | val notification = mNotification[position] 52 | holder.notifyText.text=notification.getText() 53 | 54 | publisherInfo(holder.profileimage,holder.username,notification.getUserId()) 55 | if(notification.getIsPost()) 56 | { 57 | holder.postimg.visibility=View.VISIBLE 58 | getPostedImg(holder.postimg,notification.getPostId()) 59 | } 60 | else 61 | { 62 | holder.postimg.visibility=View.GONE 63 | } 64 | 65 | holder.postimg.setOnClickListener { 66 | if(notification.getIsPost()) { 67 | val pref = mContext.getSharedPreferences("PREFS", Context.MODE_PRIVATE).edit() 68 | pref.putString("postid", notification.getPostId()) 69 | pref.apply() 70 | 71 | (mContext as FragmentActivity).supportFragmentManager.beginTransaction() 72 | .replace(R.id.fragment_container, PostDetailFragment()).commit() 73 | } 74 | else 75 | { 76 | 77 | val pref=mContext.getSharedPreferences("PREFS",Context.MODE_PRIVATE).edit() 78 | pref.putString("profileid",notification.getUserId()) 79 | pref.apply() 80 | 81 | (mContext as FragmentActivity).supportFragmentManager.beginTransaction() 82 | .replace(R.id.fragment_container, ProfileFragment()).commit() 83 | } 84 | } 85 | } 86 | 87 | private fun publisherInfo(imgView: CircleImageView, username: TextView, publisherid: String) { 88 | 89 | val userRef= FirebaseDatabase.getInstance().reference.child("Users").child(publisherid) 90 | userRef.addValueEventListener(object : ValueEventListener 91 | { 92 | override fun onCancelled(error: DatabaseError) { 93 | 94 | } 95 | 96 | override fun onDataChange(snapshot: DataSnapshot) { 97 | val user = snapshot.getValue(User::class.java) 98 | 99 | Picasso.get().load(user!!.getImage()).placeholder(R.drawable.profile).into(imgView) 100 | username.text =(user.getUsername()) 101 | } 102 | }) 103 | } 104 | 105 | private fun getPostedImg(postimg:ImageView, postid:String?) { 106 | 107 | val postRef= FirebaseDatabase.getInstance().reference.child("Posts").child(postid!!) 108 | 109 | postRef.addValueEventListener(object : ValueEventListener { 110 | override fun onCancelled(error: DatabaseError) { 111 | } 112 | override fun onDataChange(snapshot: DataSnapshot) 113 | { 114 | val post = snapshot.getValue(Post::class.java) 115 | Picasso.get().load(post!!.getPostImage()).into(postimg) 116 | } 117 | }) 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Adapter/UserAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Adapter 2 | 3 | import android.app.PendingIntent.getActivity 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.util.Log 7 | import android.view.LayoutInflater 8 | import android.view.ViewGroup 9 | import android.widget.* 10 | import androidx.annotation.NonNull 11 | import androidx.core.content.ContextCompat.startActivity 12 | import androidx.fragment.app.FragmentActivity 13 | import androidx.recyclerview.widget.RecyclerView 14 | import com.example.instaapp.Fragments.ProfileFragment 15 | import com.example.instaapp.Fragments.SearchFragment 16 | import com.example.instaapp.Model.User 17 | import com.example.instaapp.R 18 | import com.google.firebase.auth.FirebaseAuth 19 | import com.google.firebase.auth.FirebaseUser 20 | import com.google.firebase.database.DataSnapshot 21 | import com.google.firebase.database.DatabaseError 22 | import com.google.firebase.database.FirebaseDatabase 23 | import com.google.firebase.database.ValueEventListener 24 | import com.google.firebase.platforminfo.GlobalLibraryVersionRegistrar.getInstance 25 | import com.squareup.picasso.Picasso 26 | import de.hdodenhof.circleimageview.CircleImageView 27 | import android.view.View as AndroidViewView 28 | 29 | 30 | //import com.google.firebase.database.core.view.View 31 | 32 | class UserAdapter (private var mContext:Context, 33 | private var mUser:List, 34 | private var isFragment:Boolean=false):RecyclerView.Adapter(){ 35 | 36 | private val firebaseUser:FirebaseUser?= com.google.firebase.auth.FirebaseAuth.getInstance().currentUser 37 | 38 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserAdapter.ViewHolder { 39 | //to make user item available in search item 40 | val view=LayoutInflater.from(mContext).inflate(R.layout.user_item_layout,parent,false) 41 | 42 | return UserAdapter.ViewHolder(view) 43 | } 44 | 45 | override fun getItemCount(): Int { 46 | return mUser.size 47 | } 48 | 49 | override fun onBindViewHolder(holder: UserAdapter.ViewHolder, position: Int) { 50 | //to display the user data 51 | val user=mUser[position] 52 | holder.userNameTextView.text=user.getUsername() 53 | holder.userFullnameTextView.text=user.getFullname() 54 | Picasso.get().load(user.getImage()).placeholder(R.drawable.profile).into(holder.userProfileImage) //add picasso dependency for image caching and downloading 55 | 56 | checkFollowingStatus(user.getUid(),holder.followButton) 57 | 58 | //to go to searched user's profile 59 | 60 | holder.useritem.setOnClickListener(object : AndroidViewView.OnClickListener { 61 | override fun onClick(v: AndroidViewView?) { 62 | val pref=mContext.getSharedPreferences("PREFS",Context.MODE_PRIVATE).edit() 63 | pref.putString("profileid",user.getUid()) 64 | pref.apply() 65 | 66 | (mContext as FragmentActivity).supportFragmentManager.beginTransaction() 67 | .replace(R.id.fragment_container,ProfileFragment()).commit() 68 | } 69 | }) 70 | 71 | holder.followButton.setOnClickListener { 72 | if(holder.followButton.text.toString()=="Follow") { 73 | firebaseUser?.uid.let { it1 -> 74 | FirebaseDatabase.getInstance().reference 75 | .child("Follow").child(it1.toString()) 76 | .child("Following").child(user.getUid()) 77 | .setValue(true).addOnCompleteListener { task -> 78 | if (task.isSuccessful) { 79 | 80 | firebaseUser?.uid.let { it1 -> 81 | FirebaseDatabase.getInstance().reference 82 | .child("Follow").child(user.getUid()) 83 | .child("Followers").child(it1.toString()) 84 | .setValue(true).addOnCompleteListener { task -> 85 | if (task.isSuccessful) 86 | { 87 | pushNotification(user.getUid()) 88 | } 89 | } 90 | } 91 | } 92 | } 93 | } 94 | } 95 | else 96 | { 97 | if(holder.followButton.text.toString()=="Following") { 98 | firebaseUser?.uid.let { it1 -> 99 | FirebaseDatabase.getInstance().reference 100 | .child("Follow").child(it1.toString()) 101 | .child("Following").child(user.getUid()) 102 | .removeValue().addOnCompleteListener { task -> //reversing following action 103 | if (task.isSuccessful) { 104 | firebaseUser?.uid.let { it1 -> 105 | FirebaseDatabase.getInstance().reference 106 | .child("Follow").child(user.getUid()) 107 | .child("Followers").child(it1.toString()) 108 | .removeValue().addOnCompleteListener { task -> 109 | if (task.isSuccessful) { 110 | } 111 | } 112 | } 113 | } 114 | } 115 | } 116 | } 117 | } 118 | } 119 | } 120 | 121 | class ViewHolder(@NonNull itemView: AndroidViewView): RecyclerView.ViewHolder(itemView) 122 | { 123 | var userNameTextView:TextView=itemView.findViewById(R.id.user_item_search_username) 124 | var useritem:LinearLayout=itemView.findViewById(R.id.user_item) 125 | var userFullnameTextView:TextView=itemView.findViewById(R.id.user_item_search_fullname) 126 | var userProfileImage:CircleImageView=itemView.findViewById(R.id.user_item_image) 127 | var followButton: Button =itemView.findViewById(R.id.user_item_follow) 128 | } 129 | 130 | private fun pushNotification(userid:String) { 131 | 132 | val ref = FirebaseDatabase.getInstance().reference.child("Notification").child(userid) 133 | 134 | val notifyMap = HashMap() 135 | notifyMap["userid"] = FirebaseAuth.getInstance().currentUser!!.uid 136 | notifyMap["text"] = "started following you" 137 | notifyMap["postid"] = "" 138 | notifyMap["ispost"] = false 139 | 140 | ref.push().setValue(notifyMap) 141 | } 142 | 143 | private fun checkFollowingStatus(uid:String,followButton: Button) { 144 | val followingRef = firebaseUser?.uid.let { it1 -> 145 | FirebaseDatabase.getInstance().reference 146 | .child("Follow").child(it1.toString()) 147 | .child("Following") 148 | } 149 | 150 | followingRef.addValueEventListener(object : ValueEventListener { 151 | override fun onCancelled(error: DatabaseError) { 152 | 153 | } 154 | 155 | override fun onDataChange(datasnapshot: DataSnapshot) { 156 | if (datasnapshot.child(uid).exists()) { 157 | followButton.text = "Following" 158 | } 159 | else { 160 | followButton.text = "Follow" 161 | } 162 | } 163 | }) 164 | } 165 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/AddCommentActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import androidx.appcompat.app.AppCompatActivity 6 | import android.os.Bundle 7 | import android.util.Log 8 | import android.view.View 9 | import android.widget.* 10 | import androidx.recyclerview.widget.LinearLayoutManager 11 | import androidx.recyclerview.widget.RecyclerView 12 | import com.example.instaapp.Adapter.CommentAdapter 13 | import com.example.instaapp.Adapter.PostAdapter 14 | import com.example.instaapp.Model.Comment 15 | import com.example.instaapp.Model.Post 16 | import com.example.instaapp.Model.User 17 | import com.google.firebase.auth.FirebaseAuth 18 | import com.google.firebase.auth.FirebaseUser 19 | import com.google.firebase.database.* 20 | import com.squareup.picasso.Picasso 21 | import kotlinx.android.synthetic.main.activity_add_comment.* 22 | import kotlinx.android.synthetic.main.activity_add_post.* 23 | import kotlinx.android.synthetic.main.posts_layout.* 24 | 25 | class AddCommentActivity : AppCompatActivity() { 26 | 27 | private var firebaseUser: FirebaseUser?=null 28 | private var commentAdapter:CommentAdapter?=null 29 | private var commentList:MutableList?=null 30 | 31 | 32 | 33 | override fun onCreate(savedInstanceState: Bundle?) { 34 | super.onCreate(savedInstanceState) 35 | setContentView(R.layout.activity_add_comment) 36 | 37 | val toolbar=findViewById( R.id.comments_toolbar) 38 | setSupportActionBar(toolbar) 39 | supportActionBar!!.title = "Comments" 40 | supportActionBar!!.setDisplayHomeAsUpEnabled(true) 41 | toolbar.setNavigationOnClickListener(View.OnClickListener { 42 | finish() 43 | }) 44 | 45 | 46 | 47 | var recyclerView:RecyclerView?=null 48 | recyclerView=findViewById(R.id.recyclerview_comments) 49 | recyclerView.setHasFixedSize(true) 50 | val linearLayoutManager: LinearLayoutManager = LinearLayoutManager(this) 51 | recyclerView.layoutManager=linearLayoutManager 52 | 53 | commentList=ArrayList() 54 | commentAdapter= this.let { CommentAdapter(it,commentList as ArrayList) } 55 | recyclerView.adapter=commentAdapter 56 | 57 | 58 | firebaseUser= FirebaseAuth.getInstance().currentUser 59 | 60 | val add_comment=findViewById(R.id.add_comment) 61 | val post_comment=findViewById(R.id.post_comment) 62 | val postid = intent.getStringExtra("POST_ID") 63 | 64 | getImage() 65 | readComments(postid!!) 66 | getPostImage(postid!!) 67 | 68 | 69 | post_comment.setOnClickListener { 70 | if(add_comment.text.toString().equals("")) 71 | { 72 | Toast.makeText(this,"You can't send an empty comment",Toast.LENGTH_SHORT).show() 73 | } 74 | else 75 | { 76 | postComment(postid!!) 77 | } 78 | } 79 | 80 | } 81 | 82 | private fun postComment(postid:String) { 83 | 84 | val commentRef : DatabaseReference = FirebaseDatabase.getInstance().reference.child("Comment").child(postid) 85 | 86 | val commentMap = HashMap() 87 | commentMap["publisher"] = firebaseUser!!.uid 88 | commentMap["comment"] = add_comment.text.toString() 89 | 90 | commentRef.push().setValue(commentMap) 91 | pushNotification(postid) 92 | add_comment.setText("") 93 | Toast.makeText(this, "posted!!", Toast.LENGTH_LONG).show() 94 | } 95 | 96 | private fun getImage() { 97 | val ref : DatabaseReference = FirebaseDatabase.getInstance().reference.child("Users").child(firebaseUser!!.uid) 98 | 99 | ref.addValueEventListener(object:ValueEventListener{ 100 | override fun onCancelled(error: DatabaseError) { 101 | 102 | } 103 | 104 | override fun onDataChange(snapshot: DataSnapshot) { 105 | if(snapshot.exists()) 106 | { 107 | val user = snapshot.getValue(User::class.java) 108 | 109 | Picasso.get().load(user!!.getImage()).placeholder(R.drawable.profile).into(user_profile_image) 110 | } 111 | } 112 | }) 113 | } 114 | 115 | private fun pushNotification(postid: String) { 116 | 117 | val ref = FirebaseDatabase.getInstance().reference.child("Notification").child(firebaseUser!!.uid) 118 | 119 | val notifyMap = HashMap() 120 | notifyMap["userid"] = FirebaseAuth.getInstance().currentUser!!.uid 121 | notifyMap["text"] = "commented :"+add_comment.text.toString() 122 | notifyMap["postid"] = postid 123 | notifyMap["ispost"] = true 124 | 125 | ref.push().setValue(notifyMap) 126 | } 127 | 128 | private fun readComments(postid: String) { 129 | val ref: DatabaseReference = 130 | FirebaseDatabase.getInstance().reference.child("Comment").child(postid) 131 | 132 | ref.addValueEventListener(object : ValueEventListener { 133 | override fun onCancelled(error: DatabaseError) { 134 | } 135 | 136 | override fun onDataChange(p0: DataSnapshot) { 137 | 138 | commentList?.clear() 139 | for (snapshot in p0.children) { 140 | val cmnt: Comment? = snapshot.getValue(Comment::class.java) 141 | commentList!!.add(cmnt!!) 142 | } 143 | commentAdapter!!.notifyDataSetChanged() 144 | } 145 | }) 146 | } 147 | 148 | private fun getPostImage(postid: String){ 149 | val postRef = FirebaseDatabase.getInstance() 150 | .reference.child("Posts") 151 | .child(postid).child("postimage") 152 | 153 | postRef.addValueEventListener(object:ValueEventListener{ 154 | override fun onCancelled(error: DatabaseError) { 155 | 156 | } 157 | 158 | override fun onDataChange(p0: DataSnapshot) { 159 | if(p0.exists()) 160 | { 161 | val image = p0.value.toString() 162 | 163 | Picasso.get().load(image).placeholder(R.drawable.profile).into(post_image_comment) 164 | } 165 | } 166 | }) 167 | } 168 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/AddPostActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp 2 | 3 | import android.app.Activity 4 | import android.app.ProgressDialog 5 | import android.content.Intent 6 | import android.net.Uri 7 | import android.os.Bundle 8 | import android.text.TextUtils 9 | import android.widget.Toast 10 | import androidx.appcompat.app.AppCompatActivity 11 | import com.google.android.gms.tasks.Continuation 12 | import com.google.android.gms.tasks.OnCompleteListener 13 | import com.google.android.gms.tasks.Task 14 | import com.google.firebase.auth.FirebaseAuth 15 | import com.google.firebase.database.FirebaseDatabase 16 | import com.google.firebase.storage.FirebaseStorage 17 | import com.google.firebase.storage.StorageReference 18 | import com.google.firebase.storage.StorageTask 19 | import com.google.firebase.storage.UploadTask 20 | import com.theartofdev.edmodo.cropper.CropImage 21 | import com.theartofdev.edmodo.cropper.CropImageView 22 | import kotlinx.android.synthetic.main.activity_add_comment.* 23 | import kotlinx.android.synthetic.main.activity_add_post.* 24 | 25 | class AddPostActivity : AppCompatActivity() { 26 | 27 | private var myUrl="" 28 | private var imageUri: Uri?=null 29 | private var storagePostPictureRef: StorageReference?=null 30 | 31 | override fun onCreate(savedInstanceState: Bundle?) { 32 | super.onCreate(savedInstanceState) 33 | setContentView(R.layout.activity_add_post) 34 | 35 | storagePostPictureRef= FirebaseStorage.getInstance().reference.child("Post Picture") 36 | 37 | dont_post_picture.setOnClickListener { 38 | val intent=Intent(this@AddPostActivity,MainActivity::class.java) 39 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) 40 | startActivity(intent) 41 | finish() 42 | } 43 | 44 | post_picture.setOnClickListener { 45 | uploadPost() 46 | } 47 | 48 | picture_to_be_posted.setOnClickListener { 49 | CropImage.activity() 50 | .setGuidelines(CropImageView.Guidelines.ON) 51 | .setAspectRatio(1,1) 52 | .start(this@AddPostActivity) 53 | } 54 | 55 | CropImage.activity() 56 | .setGuidelines(CropImageView.Guidelines.ON) 57 | .setAspectRatio(1,1) 58 | .start(this@AddPostActivity) 59 | } 60 | 61 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 62 | super.onActivityResult(requestCode, resultCode, data) 63 | if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) { 64 | val result = CropImage.getActivityResult(data) 65 | if (resultCode == Activity.RESULT_OK) { 66 | imageUri= result.uri 67 | picture_to_be_posted.setImageURI(imageUri) 68 | } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) { 69 | val error = result.error 70 | } 71 | } 72 | } 73 | 74 | private fun uploadPost() { 75 | when 76 | { 77 | imageUri == null -> Toast.makeText(this, "Please select image first.", Toast.LENGTH_LONG).show() 78 | TextUtils.isEmpty(write_post.text.toString()) -> Toast.makeText(this, "Please write caption", Toast.LENGTH_LONG).show() 79 | 80 | else -> { 81 | val progressDialog = ProgressDialog(this) 82 | progressDialog.setTitle("Posting") 83 | progressDialog.setMessage("Please wait, we are posting..") 84 | progressDialog.show() 85 | 86 | val fileRef = storagePostPictureRef!!.child(System.currentTimeMillis().toString()+ ".jpg") 87 | 88 | var uploadTask: StorageTask<*> 89 | uploadTask = fileRef.putFile(imageUri!!) 90 | 91 | uploadTask.continueWithTask(Continuation >{ task -> 92 | if (!task.isSuccessful) 93 | { 94 | task.exception?.let { 95 | throw it 96 | progressDialog.dismiss() 97 | } 98 | } 99 | return@Continuation fileRef.downloadUrl 100 | }).addOnCompleteListener (OnCompleteListener { task -> 101 | if (task.isSuccessful) 102 | { 103 | val downloadUrl = task.result 104 | myUrl = downloadUrl.toString() 105 | 106 | 107 | 108 | val ref = FirebaseDatabase.getInstance().reference.child("Posts") 109 | val postid=ref.push().key 110 | 111 | val postMap = HashMap() 112 | 113 | postMap["postid"] = postid!! 114 | postMap["caption"] = write_post.text.toString() 115 | postMap["publisher"] = FirebaseAuth.getInstance().currentUser!!.uid 116 | postMap["postimage"] = myUrl 117 | 118 | ref.child(postid).updateChildren(postMap) 119 | 120 | 121 | val commentRef=FirebaseDatabase.getInstance().reference.child("Comment").child(postid) 122 | val commentMap = HashMap() 123 | commentMap["publisher"] = FirebaseAuth.getInstance().currentUser!!.uid 124 | commentMap["comment"] = write_post.text.toString() 125 | 126 | commentRef.push().setValue(commentMap) 127 | 128 | Toast.makeText(this, "Uploaded successfully", Toast.LENGTH_LONG).show() 129 | 130 | val intent = Intent(this@AddPostActivity, MainActivity::class.java) 131 | startActivity(intent) 132 | finish() 133 | progressDialog.dismiss() 134 | } 135 | else 136 | { 137 | progressDialog.dismiss() 138 | } 139 | }) 140 | } 141 | } 142 | } 143 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/AddStoryActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp 2 | 3 | import android.app.Activity 4 | import android.app.ProgressDialog 5 | import android.content.Intent 6 | import android.net.Uri 7 | import androidx.appcompat.app.AppCompatActivity 8 | import android.os.Bundle 9 | import android.text.TextUtils 10 | import android.widget.Toast 11 | import com.google.android.gms.tasks.Continuation 12 | import com.google.android.gms.tasks.OnCompleteListener 13 | import com.google.android.gms.tasks.Task 14 | import com.google.firebase.auth.FirebaseAuth 15 | import com.google.firebase.database.FirebaseDatabase 16 | import com.google.firebase.database.ServerValue 17 | import com.google.firebase.storage.FirebaseStorage 18 | import com.google.firebase.storage.StorageReference 19 | import com.google.firebase.storage.StorageTask 20 | import com.google.firebase.storage.UploadTask 21 | import com.theartofdev.edmodo.cropper.CropImage 22 | import com.theartofdev.edmodo.cropper.CropImageView 23 | import kotlinx.android.synthetic.main.activity_add_post.* 24 | 25 | class AddStoryActivity : AppCompatActivity() { 26 | 27 | private var myUrl = "" 28 | 29 | private var imageUri: Uri? = null 30 | 31 | private var storageStoryRef: StorageReference? = null 32 | 33 | override fun onCreate(savedInstanceState: Bundle?) { 34 | super.onCreate(savedInstanceState) 35 | setContentView(R.layout.activity_add_story) 36 | 37 | 38 | storageStoryRef = FirebaseStorage.getInstance().reference.child("Story Pictures") 39 | 40 | 41 | 42 | 43 | CropImage.activity() 44 | .setAspectRatio(9, 16) 45 | .start(this@AddStoryActivity) 46 | 47 | } 48 | 49 | 50 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { 51 | super.onActivityResult(requestCode, resultCode, data) 52 | if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) { 53 | 54 | val result = CropImage.getActivityResult(data) 55 | imageUri = result.uri 56 | 57 | 58 | uploadStory() 59 | 60 | } 61 | else 62 | { 63 | Toast.makeText(this,"Some Error Occured!! Try Again",Toast.LENGTH_SHORT).show() 64 | finish() 65 | } 66 | 67 | 68 | } 69 | 70 | private fun uploadStory() { 71 | when 72 | { 73 | imageUri==null ->{ 74 | Toast.makeText(this,"Please select Image", Toast.LENGTH_SHORT).show() 75 | } 76 | 77 | else-> 78 | { 79 | val progressDialog= ProgressDialog(this) 80 | progressDialog.setTitle("Adding Story") 81 | progressDialog.setMessage("Please wait while your story is added") 82 | progressDialog.show() 83 | 84 | 85 | val fileRef=storageStoryRef!!.child(System.currentTimeMillis().toString()+".jpg") 86 | 87 | val uploadTask: StorageTask<*> 88 | uploadTask=fileRef.putFile(imageUri!!) 89 | 90 | uploadTask.continueWithTask(Continuation> { task -> 91 | 92 | if (!task.isSuccessful){ 93 | task.exception?.let { 94 | throw it 95 | progressDialog.dismiss() 96 | } 97 | } 98 | 99 | return@Continuation fileRef.downloadUrl 100 | }) 101 | .addOnCompleteListener ( OnCompleteListener {task -> 102 | if (task.isSuccessful){ 103 | 104 | val downloadUrl=task.result 105 | myUrl=downloadUrl.toString() 106 | 107 | 108 | val ref= FirebaseDatabase.getInstance().reference 109 | .child("Story") 110 | .child(FirebaseAuth.getInstance().currentUser!!.uid) 111 | 112 | val storyId=(ref.push().key).toString() 113 | 114 | val timeEnd=System.currentTimeMillis()+ 86400000 //864000 is the millisec conversion for 24hrs//The timeSpan to expire the story 115 | 116 | val storymap = HashMap() 117 | 118 | storymap["userid"] = FirebaseAuth.getInstance().currentUser!!.uid 119 | storymap["timestart"] = ServerValue.TIMESTAMP 120 | storymap["timeend"] = timeEnd 121 | storymap["imageurl"] = myUrl 122 | storymap["storyid"] = storyId 123 | 124 | ref.child(storyId).updateChildren(storymap) 125 | 126 | Toast.makeText(this, "Story Added!!", Toast.LENGTH_SHORT) 127 | .show() 128 | 129 | finish() 130 | 131 | 132 | progressDialog.dismiss() 133 | 134 | } 135 | else 136 | { 137 | progressDialog.dismiss() 138 | } 139 | 140 | 141 | }) 142 | 143 | 144 | 145 | 146 | 147 | } 148 | } 149 | } 150 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Fragments/HomeFragment.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Fragments 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.fragment.app.Fragment 8 | import androidx.recyclerview.widget.LinearLayoutManager 9 | import androidx.recyclerview.widget.RecyclerView 10 | import com.example.instaapp.Adapter.PostAdapter 11 | import com.example.instaapp.Adapter.StoryAdapter 12 | import com.example.instaapp.Model.Post 13 | import com.example.instaapp.Model.Story 14 | import com.example.instaapp.R 15 | import com.google.firebase.auth.FirebaseAuth 16 | import com.google.firebase.database.DataSnapshot 17 | import com.google.firebase.database.DatabaseError 18 | import com.google.firebase.database.FirebaseDatabase 19 | import com.google.firebase.database.ValueEventListener 20 | 21 | class HomeFragment : Fragment() { 22 | 23 | private var postAdapter:PostAdapter?=null 24 | private var postList:MutableList?=null 25 | private var followingList:MutableList?=null 26 | 27 | private var storyAdapter: StoryAdapter? = null 28 | private var storyList: MutableList ?= null 29 | 30 | 31 | override fun onCreateView( 32 | inflater: LayoutInflater, container: ViewGroup?, 33 | savedInstanceState: Bundle? 34 | ): View? { 35 | // Inflate the layout for this fragment 36 | val view= inflater.inflate(R.layout.fragment_home, container, false) 37 | 38 | var recyclerView:RecyclerView?=null 39 | var recyclerViewStory:RecyclerView?=null 40 | 41 | recyclerView=view.findViewById(R.id.recycler_view_home) 42 | val linearlayoutManager=LinearLayoutManager(context) 43 | linearlayoutManager.reverseLayout=true 44 | //New posts at top 45 | linearlayoutManager.stackFromEnd=true 46 | recyclerView.layoutManager=linearlayoutManager 47 | //For Posts 48 | postList=ArrayList() 49 | postAdapter=context?.let { PostAdapter(it,postList as ArrayList) } 50 | recyclerView.adapter=postAdapter 51 | 52 | 53 | recyclerViewStory=view.findViewById(R.id.recycler_view_story) 54 | recyclerViewStory.setHasFixedSize(true) 55 | val linearlayoutManager2=LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false) 56 | recyclerViewStory.layoutManager=linearlayoutManager2 57 | ///For Stories 58 | storyList=ArrayList() 59 | storyAdapter=context?.let { StoryAdapter(it,storyList as ArrayList) } 60 | recyclerViewStory.adapter=storyAdapter 61 | 62 | //code for counting no of items in recycler view 63 | // if (postAdapter!!.itemCount == 0){ 64 | // welcome_text.text = "Welcome to Instagram" 65 | // } 66 | // else 67 | // { 68 | // welcome_text.visibility=View.INVISIBLE 69 | // } 70 | 71 | checkFollowings() 72 | 73 | return view 74 | } 75 | 76 | //to get the following List of logged-in user 77 | private fun checkFollowings() { 78 | followingList=ArrayList() 79 | 80 | val followingRef = FirebaseDatabase.getInstance().reference 81 | .child("Follow").child(FirebaseAuth.getInstance().currentUser!!.uid) 82 | .child("Following") 83 | 84 | followingRef.addValueEventListener(object :ValueEventListener 85 | { 86 | override fun onCancelled(error: DatabaseError) { 87 | 88 | } 89 | 90 | override fun onDataChange(p0: DataSnapshot) { 91 | if(p0.exists()) 92 | { 93 | (followingList as ArrayList).clear() //to get previous data 94 | for(snapshot in p0.children) 95 | { 96 | snapshot.key?.let { (followingList as ArrayList).add(it) } 97 | } 98 | retrievePosts() 99 | retrieveStories() 100 | } 101 | } 102 | }) 103 | } 104 | 105 | private fun retrievePosts() { 106 | val postRef=FirebaseDatabase.getInstance().reference.child("Posts") 107 | 108 | postRef.addValueEventListener(object : ValueEventListener 109 | { 110 | override fun onCancelled(error: DatabaseError) { 111 | 112 | } 113 | 114 | override fun onDataChange(p0: DataSnapshot) 115 | { 116 | if(p0.exists()) { 117 | postList?.clear() 118 | for (snapshot in p0.children) { 119 | val post = snapshot.getValue(Post::class.java) 120 | 121 | for (id in (followingList as ArrayList)) { 122 | if (post!!.getPublisher() == id) { 123 | postList!!.add(post) 124 | } 125 | postAdapter!!.notifyDataSetChanged() 126 | } 127 | } 128 | } 129 | } 130 | 131 | }) 132 | } 133 | 134 | private fun retrieveStories() 135 | { 136 | val storyRef= FirebaseDatabase.getInstance().reference.child("Story") 137 | 138 | storyRef.addValueEventListener(object :ValueEventListener{ 139 | override fun onDataChange(datasnapshot: DataSnapshot) { 140 | val timeCurrent=System.currentTimeMillis() 141 | 142 | (storyList as ArrayList).clear() 143 | 144 | (storyList as ArrayList).add(Story("",0,0,"",FirebaseAuth.getInstance().currentUser!!.uid)) 145 | 146 | for (id in followingList!!) 147 | { 148 | var countStory=0 149 | 150 | var story:Story?=null 151 | 152 | for (snapshot in datasnapshot.child(id).children) 153 | { 154 | story= snapshot.getValue(Story::class.java) 155 | 156 | if(timeCurrent>story!!.getTimeStart() && timeCurrent0){ 162 | (storyList as ArrayList).add(story!!) 163 | } 164 | } 165 | storyAdapter!!.notifyDataSetChanged() 166 | 167 | 168 | } 169 | 170 | override fun onCancelled(error: DatabaseError) { 171 | 172 | } 173 | }) 174 | 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Fragments/NotificationFragment.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Fragments 2 | 3 | import android.os.Bundle 4 | import androidx.fragment.app.Fragment 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import androidx.recyclerview.widget.LinearLayoutManager 9 | import androidx.recyclerview.widget.RecyclerView 10 | import com.example.instaapp.Adapter.NotificationAdapter 11 | import com.example.instaapp.Model.Notification 12 | import com.example.instaapp.R 13 | import com.google.firebase.auth.FirebaseAuth 14 | import com.google.firebase.auth.FirebaseUser 15 | import com.google.firebase.database.DataSnapshot 16 | import com.google.firebase.database.DatabaseError 17 | import com.google.firebase.database.FirebaseDatabase 18 | import com.google.firebase.database.ValueEventListener 19 | import java.util.* 20 | import kotlin.collections.ArrayList 21 | 22 | class NotificationFragment : Fragment() { 23 | 24 | private var notificationAdapter: NotificationAdapter?=null 25 | private var notificationList:MutableList?=null 26 | private var firebaseUser: FirebaseUser?=null 27 | 28 | override fun onCreateView( 29 | inflater: LayoutInflater, container: ViewGroup?, 30 | savedInstanceState: Bundle? 31 | ): View? { 32 | // Inflate the layout for this fragment 33 | val view= inflater.inflate(R.layout.fragment_notification, container, false) 34 | 35 | firebaseUser = FirebaseAuth.getInstance().currentUser!! 36 | var recyclerView: RecyclerView?=null 37 | recyclerView=view.findViewById(R.id.recyclerview_notification) 38 | recyclerView.setHasFixedSize(true) 39 | val linearLayoutManager: LinearLayoutManager = LinearLayoutManager(context) 40 | recyclerView.layoutManager=linearLayoutManager 41 | 42 | notificationList=ArrayList() 43 | notificationAdapter=context?.let { NotificationAdapter(it,notificationList as ArrayList) } 44 | recyclerView.adapter=notificationAdapter 45 | 46 | readNotification() 47 | return view 48 | } 49 | 50 | private fun readNotification() { 51 | 52 | val postRef= FirebaseDatabase.getInstance().reference.child("Notification").child(firebaseUser!!.uid) 53 | postRef.addValueEventListener(object : ValueEventListener 54 | { 55 | override fun onCancelled(error: DatabaseError) { 56 | 57 | } 58 | 59 | override fun onDataChange(p0: DataSnapshot) 60 | { 61 | notificationList?.clear() 62 | for (snapshot in p0.children) 63 | { 64 | val notification: Notification? = snapshot.getValue(Notification::class.java) 65 | notificationList!!.add(notification!!) 66 | } 67 | Collections.reverse(notificationList) 68 | notificationAdapter!!.notifyDataSetChanged() 69 | 70 | } 71 | }) 72 | } 73 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Fragments/PostDetailFragment.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Fragments 2 | 3 | import android.content.Context 4 | import android.os.Bundle 5 | import android.util.Log 6 | import androidx.fragment.app.Fragment 7 | import android.view.LayoutInflater 8 | import android.view.View 9 | import android.view.ViewGroup 10 | import androidx.recyclerview.widget.LinearLayoutManager 11 | import androidx.recyclerview.widget.RecyclerView 12 | import com.example.instaapp.Adapter.PostAdapter 13 | import com.example.instaapp.Model.Comment 14 | import com.example.instaapp.Model.Post 15 | import com.example.instaapp.R 16 | import com.google.firebase.database.DataSnapshot 17 | import com.google.firebase.database.DatabaseError 18 | import com.google.firebase.database.FirebaseDatabase 19 | import com.google.firebase.database.ValueEventListener 20 | 21 | class PostDetailFragment : Fragment() { 22 | 23 | private var postAdapter: PostAdapter?=null 24 | private var postList:MutableList?=null 25 | private var postid:String?="" 26 | 27 | override fun onCreateView( 28 | inflater: LayoutInflater, container: ViewGroup?, 29 | savedInstanceState: Bundle? 30 | ): View? { 31 | // Inflate the layout for this fragment 32 | val view= inflater.inflate(R.layout.fragment_post_detail, container, false) 33 | 34 | val pref = context?.getSharedPreferences("PREFS", Context.MODE_PRIVATE) 35 | postid=pref?.getString("postid","none") 36 | 37 | var recyclerView:RecyclerView?=null 38 | recyclerView=view.findViewById(R.id.recyclerview_postdetail) 39 | val linearLayoutManager: LinearLayoutManager = LinearLayoutManager(context) 40 | recyclerView.layoutManager=linearLayoutManager 41 | 42 | postList=ArrayList() 43 | postAdapter=context?.let { PostAdapter(it,postList as ArrayList) } 44 | recyclerView.adapter=postAdapter 45 | 46 | readPosts(postid) 47 | 48 | return view 49 | } 50 | 51 | private fun readPosts(postid: String?) { 52 | val postRef= FirebaseDatabase.getInstance().reference.child("Posts").child(postid!!) 53 | 54 | Log.d("Post id",postid) 55 | postRef.addValueEventListener(object : ValueEventListener 56 | { 57 | override fun onCancelled(error: DatabaseError) { 58 | 59 | } 60 | 61 | override fun onDataChange(p0: DataSnapshot) 62 | { 63 | postList?.clear() 64 | val post: Post? = p0.getValue(Post::class.java) 65 | postList!!.add(post!!) 66 | postAdapter!!.notifyDataSetChanged() 67 | } 68 | }) 69 | } 70 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Fragments/SearchFragment.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Fragments 2 | 3 | import android.os.Bundle 4 | import android.text.Editable 5 | import android.text.TextWatcher 6 | import androidx.fragment.app.Fragment 7 | import android.view.LayoutInflater 8 | import android.view.View 9 | import android.view.ViewGroup 10 | import android.widget.Toast 11 | import androidx.recyclerview.widget.LinearLayoutManager 12 | import androidx.recyclerview.widget.RecyclerView 13 | import com.example.instaapp.Adapter.UserAdapter 14 | import com.example.instaapp.Model.User 15 | import com.example.instaapp.R 16 | import com.google.firebase.database.DataSnapshot 17 | import com.google.firebase.database.DatabaseError 18 | import com.google.firebase.database.FirebaseDatabase 19 | import com.google.firebase.database.ValueEventListener 20 | import kotlinx.android.synthetic.main.fragment_search.* 21 | import kotlinx.android.synthetic.main.fragment_search.view.* 22 | 23 | class SearchFragment : Fragment() { 24 | 25 | private var recyclerView:RecyclerView?=null 26 | private var userAdapter:UserAdapter?=null 27 | private var mUser:MutableList?=null 28 | 29 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, 30 | savedInstanceState: Bundle?): View? { 31 | // Inflate the layout for this fragment 32 | val view = inflater.inflate(R.layout.fragment_search, container, false) 33 | recyclerView = view.findViewById(R.id.recyclerview_search) 34 | recyclerView?.setHasFixedSize(true) 35 | recyclerView?.layoutManager = LinearLayoutManager(context) 36 | 37 | mUser = ArrayList() 38 | //to show a user on search 39 | userAdapter = context?.let { UserAdapter(it, mUser as ArrayList, true)} 40 | recyclerView?.adapter = userAdapter 41 | 42 | view.searchitem.addTextChangedListener(object : TextWatcher { 43 | override fun afterTextChanged(p0: Editable?) { 44 | } 45 | 46 | override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { 47 | } 48 | 49 | override fun onTextChanged(s: CharSequence?, p1: Int, p2: Int, p3: Int) { 50 | if (searchitem.text.toString() == "") { 51 | } else { 52 | recyclerView?.visibility = View.VISIBLE 53 | retrieveUser() 54 | searchUser(s.toString().toLowerCase()) 55 | } 56 | } 57 | }) 58 | return view 59 | } 60 | 61 | private fun searchUser(input:String) { 62 | 63 | val query=FirebaseDatabase.getInstance().reference 64 | .child("Users") 65 | .orderByChild("username") 66 | .startAt(input) 67 | .endAt(input + "\uf8ff") 68 | 69 | query.addValueEventListener(object:ValueEventListener 70 | { 71 | override fun onCancelled(error: DatabaseError) { 72 | 73 | } 74 | override fun onDataChange(datasnapshot: DataSnapshot) { 75 | mUser?.clear() 76 | 77 | for(snapshot in datasnapshot.children) 78 | { 79 | //searching all users 80 | val user=snapshot.getValue(User::class.java) 81 | if(user!=null) 82 | { 83 | mUser?.add(user) 84 | } 85 | } 86 | userAdapter?.notifyDataSetChanged() 87 | } 88 | }) 89 | } 90 | 91 | private fun retrieveUser() 92 | { 93 | val usersSearchRef=FirebaseDatabase.getInstance().reference.child("Users")//table name:Users 94 | usersSearchRef.addValueEventListener(object:ValueEventListener 95 | { 96 | override fun onCancelled(error: DatabaseError) { 97 | Toast.makeText(context,"Could not read from Database",Toast.LENGTH_LONG).show() 98 | } 99 | 100 | override fun onDataChange(dataSnapshot: DataSnapshot) { 101 | if (view!!.searchitem.text.toString().equals("")) { 102 | mUser?.clear() 103 | for (snapShot in dataSnapshot.children) { 104 | val user = snapShot.getValue(User::class.java) 105 | if (user != null) { 106 | mUser?.add(user) 107 | } 108 | userAdapter?.notifyDataSetChanged() 109 | } 110 | } 111 | } 112 | }) 113 | } 114 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/LoginActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp 2 | 3 | import android.app.ProgressDialog 4 | import android.content.Intent 5 | import androidx.appcompat.app.AppCompatActivity 6 | import android.os.Bundle 7 | import android.text.TextUtils 8 | import android.widget.Toast 9 | import com.google.firebase.analytics.FirebaseAnalytics 10 | import com.google.firebase.auth.FirebaseAuth 11 | import kotlinx.android.synthetic.main.activity_login.* 12 | 13 | class LoginActivity : AppCompatActivity() { 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_login) 17 | 18 | signup_link.setOnClickListener { 19 | startActivity(Intent(this,SignUpActivity::class.java)) 20 | } 21 | login_btn.setOnClickListener { 22 | loginUser() 23 | } 24 | } 25 | 26 | private fun loginUser() { 27 | val email = login_email.text.toString() 28 | val password = login_password.text.toString() 29 | 30 | when { 31 | TextUtils.isEmpty(email) -> Toast.makeText( 32 | this, 33 | "Username is required", 34 | Toast.LENGTH_SHORT 35 | ).show() 36 | TextUtils.isEmpty(password) -> Toast.makeText( 37 | this, 38 | "Password is required", 39 | Toast.LENGTH_SHORT 40 | ).show() 41 | 42 | else -> { 43 | val progressDialog = ProgressDialog(this@LoginActivity) 44 | progressDialog.setTitle("Login") 45 | progressDialog.setMessage("Logging in...") 46 | progressDialog.setCanceledOnTouchOutside(false) 47 | progressDialog.show() 48 | 49 | val mAuth: FirebaseAuth = FirebaseAuth.getInstance() 50 | mAuth.signInWithEmailAndPassword(email, password) 51 | .addOnCompleteListener { task -> 52 | if (task.isSuccessful) { 53 | progressDialog.dismiss() 54 | val intent = Intent(this@LoginActivity, MainActivity::class.java) 55 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) 56 | startActivity(intent) 57 | finish() 58 | } else { 59 | val message = task.exception!!.toString() 60 | Toast.makeText(this, "Password or Email Invalid", Toast.LENGTH_LONG).show() 61 | mAuth.signOut() 62 | progressDialog.dismiss() 63 | } 64 | } 65 | } 66 | } 67 | 68 | } 69 | 70 | override fun onStart() { 71 | super.onStart() 72 | 73 | if(FirebaseAuth.getInstance().currentUser!=null) 74 | { 75 | //forwarding to home page 76 | val intent=Intent(this@LoginActivity,MainActivity::class.java) 77 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) 78 | startActivity(intent) 79 | finish() 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.content.SharedPreferences 6 | import android.os.Bundle 7 | import androidx.appcompat.app.AppCompatActivity 8 | import androidx.fragment.app.Fragment 9 | import androidx.fragment.app.FragmentManager 10 | import com.example.instaapp.Fragments.HomeFragment 11 | import com.example.instaapp.Fragments.NotificationFragment 12 | import com.example.instaapp.Fragments.ProfileFragment 13 | import com.example.instaapp.Fragments.SearchFragment 14 | import com.google.android.material.bottomnavigation.BottomNavigationView 15 | import kotlinx.android.synthetic.main.fragment_profile.view.* 16 | 17 | class MainActivity : AppCompatActivity() { 18 | 19 | internal var selectedFragment:Fragment?=null 20 | 21 | private val onNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> 22 | when (item.itemId) { 23 | R.id.nav_home -> { 24 | moveToFragment(HomeFragment()) 25 | return@OnNavigationItemSelectedListener true 26 | } 27 | R.id.nav_search -> { 28 | moveToFragment(SearchFragment()) 29 | return@OnNavigationItemSelectedListener true 30 | } 31 | R.id.nav_addpost -> { 32 | item.isChecked=false 33 | startActivity(Intent(this@MainActivity,AddPostActivity::class.java)) 34 | return@OnNavigationItemSelectedListener true 35 | } 36 | R.id.nav_notifications -> { 37 | moveToFragment(NotificationFragment()) 38 | return@OnNavigationItemSelectedListener true 39 | } 40 | R.id.nav_profile -> { 41 | moveToFragment(ProfileFragment()) 42 | return@OnNavigationItemSelectedListener true 43 | } 44 | } 45 | false 46 | } 47 | 48 | override fun onCreate(savedInstanceState: Bundle?) { 49 | super.onCreate(savedInstanceState) 50 | setContentView(R.layout.activity_main) 51 | setSupportActionBar(findViewById(R.id.home_toolbar)) 52 | 53 | val navView: BottomNavigationView = findViewById(R.id.nav_view) 54 | navView.setOnNavigationItemSelectedListener(onNavigationItemSelectedListener) 55 | 56 | val publisher = intent.getStringExtra("PUBLISHER_ID") 57 | if(publisher!=null) { 58 | val prefs: SharedPreferences.Editor? = 59 | getSharedPreferences("PREFS", Context.MODE_PRIVATE) 60 | .edit().apply { putString("profileId", publisher); apply() } 61 | 62 | moveToFragment(ProfileFragment()) 63 | } 64 | else 65 | //to call fragments 66 | moveToFragment(HomeFragment()) 67 | } 68 | 69 | private fun moveToFragment(fragment:Fragment) 70 | { 71 | val fragmentTrans=supportFragmentManager.beginTransaction() 72 | fragmentTrans.replace(R.id.fragment_container,fragment) 73 | fragmentTrans.commit() 74 | } 75 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Model/Comment.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Model 2 | 3 | class Comment { 4 | private var publisher:String="" 5 | private var comment:String="" 6 | 7 | constructor() 8 | 9 | constructor(publisher: String, comment: String) { 10 | this.publisher = publisher 11 | this.comment = comment 12 | } 13 | 14 | fun getPublisher():String{ 15 | return publisher 16 | } 17 | fun getComment():String{ 18 | return comment 19 | } 20 | 21 | fun setPublisher(publisher: String) 22 | { 23 | this.publisher=publisher 24 | } 25 | 26 | fun setComment(comment: String) 27 | { 28 | this.comment=comment 29 | } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Model/Notification.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Model 2 | 3 | class Notification { 4 | private var userid:String="" 5 | private var text:String="" 6 | private var postid:String="" 7 | private var ispost:Boolean=false 8 | 9 | 10 | constructor() 11 | 12 | constructor(userid: String,text: String,postid:String,ispost:Boolean) { 13 | this.userid=userid 14 | this.text=text 15 | this.postid=postid 16 | this.ispost= ispost 17 | } 18 | 19 | fun getPostId():String{ 20 | return postid 21 | } 22 | 23 | fun getUserId():String{ 24 | return userid 25 | } 26 | fun getText():String{ 27 | return text 28 | } 29 | fun getIsPost():Boolean{ 30 | return ispost 31 | } 32 | 33 | fun setPostId(postid: String){ 34 | this.postid= postid 35 | } 36 | 37 | fun setUserId(userid: String){ 38 | this.userid= userid 39 | } 40 | 41 | fun setText(text: String){ 42 | this.text= text 43 | } 44 | 45 | fun setIsPost(ispost: Boolean){ 46 | this.ispost= ispost 47 | } 48 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Model/Post.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Model 2 | 3 | class Post { 4 | private var postid:String="" 5 | private var postimage:String="" 6 | private var publisher:String="" 7 | private var caption:String="" 8 | 9 | constructor() 10 | 11 | constructor(postid: String, postimage: String, publisher: String, caption: String) { 12 | this.postid = postid 13 | this.postimage = postimage 14 | this.publisher = publisher 15 | this.caption = caption 16 | } 17 | 18 | //getters 19 | fun getPostId():String{ 20 | return postid 21 | } 22 | 23 | fun getPostImage():String{ 24 | return postimage 25 | } 26 | fun getPublisher():String{ 27 | return publisher 28 | } 29 | fun getCaption():String{ 30 | return caption 31 | } 32 | 33 | //setters 34 | fun setPostId(postid: String) 35 | { 36 | this.postid=postid 37 | } 38 | 39 | fun setPostImage(postimage: String) 40 | { 41 | this.postimage=postimage 42 | } 43 | 44 | fun setPublisher(publisher: String) 45 | { 46 | this.publisher=publisher 47 | } 48 | 49 | fun setCaption(caption: String) 50 | { 51 | this.caption=caption 52 | } 53 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Model/Story.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Model 2 | 3 | class Story 4 | { 5 | 6 | private var imageurl:String="" 7 | private var timestart:Long=0 8 | private var timeend:Long=0 9 | private var storyid:String="" 10 | private var userid:String="" 11 | 12 | constructor() 13 | constructor(imageurl: String, timestart: Long, timeend: Long, storyid: String, userid: String) { 14 | this.imageurl = imageurl 15 | this.timestart = timestart 16 | this.timeend = timeend 17 | this.storyid = storyid 18 | this.userid = userid 19 | } 20 | 21 | //Getter and setters 22 | 23 | fun getImageUrl():String 24 | { 25 | return imageurl 26 | } 27 | fun getTimeStart():Long 28 | { 29 | return timestart 30 | } 31 | fun getTimeEnd():Long 32 | { 33 | return timeend 34 | } 35 | fun getStoryId():String 36 | { 37 | return storyid 38 | } 39 | fun getUserId():String 40 | { 41 | return userid 42 | } 43 | 44 | 45 | 46 | fun setImageUrl(imageurl: String) 47 | { 48 | this.imageurl=imageurl 49 | } 50 | fun setTimeStart(timestart: Long) 51 | { 52 | this.timestart=timestart 53 | } 54 | fun setTimeEnd(timeend: Long) 55 | { 56 | this.timeend=timeend 57 | 58 | } 59 | fun setStoryId(storyid: String) 60 | { 61 | this.storyid=storyid 62 | } 63 | fun setUserId(userid: String) 64 | { 65 | this.userid=userid 66 | } 67 | 68 | 69 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/Model/User.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp.Model 2 | 3 | class User { 4 | private var username:String="" 5 | private var uid:String="" 6 | private var bio:String="" 7 | private var fullname:String="" 8 | private var image:String="" 9 | 10 | constructor() 11 | 12 | constructor(username:String,fullname:String,bio:String,uid:String,image:String) 13 | { 14 | this.username=username 15 | this.uid=uid 16 | this.fullname=fullname 17 | this.bio=bio 18 | this.image=image 19 | } 20 | 21 | //getters and Setters 22 | fun getUsername():String{ 23 | return username 24 | } 25 | fun setUsername(username:String){ 26 | this.username= username 27 | } 28 | 29 | fun getUid():String{ 30 | return uid 31 | } 32 | fun setUid(uid:String){ 33 | this.uid= uid 34 | } 35 | 36 | fun getFullname():String{ 37 | return fullname 38 | } 39 | fun setFullname(fullname:String){ 40 | this.fullname=fullname 41 | } 42 | 43 | fun getBio():String{ 44 | return bio 45 | } 46 | fun setBio(bio:String){ 47 | this.bio= bio 48 | } 49 | 50 | fun getImage():String{ 51 | return image 52 | } 53 | fun setImage(image:String){ 54 | this.image= image 55 | } 56 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/ShowUsersActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | import android.widget.Toast 6 | import androidx.appcompat.widget.Toolbar 7 | import androidx.recyclerview.widget.LinearLayoutManager 8 | import androidx.recyclerview.widget.RecyclerView 9 | import com.example.instaapp.Adapter.UserAdapter 10 | import com.example.instaapp.Model.User 11 | import com.google.firebase.database.DataSnapshot 12 | import com.google.firebase.database.DatabaseError 13 | import com.google.firebase.database.FirebaseDatabase 14 | import com.google.firebase.database.ValueEventListener 15 | import kotlinx.android.synthetic.main.fragment_search.view.* 16 | 17 | class ShowUsersActivity : AppCompatActivity() { 18 | 19 | var id: String = "" 20 | var title: String = "" 21 | 22 | var userAdapter: UserAdapter?= null 23 | var userList: List? = null 24 | var idList: List? = null 25 | 26 | override fun onCreate(savedInstanceState: Bundle?) { 27 | super.onCreate(savedInstanceState) 28 | setContentView(R.layout.activity_show_users) 29 | 30 | val intent = intent 31 | id = intent.getStringExtra("id").toString() 32 | title = intent.getStringExtra("title").toString() 33 | 34 | val toolbar: Toolbar = findViewById(R.id.toolbar) 35 | setSupportActionBar(toolbar) 36 | supportActionBar!!.title = title 37 | supportActionBar!!.setDisplayHomeAsUpEnabled(true) 38 | toolbar.setNavigationOnClickListener{ 39 | finish() 40 | } 41 | 42 | var recyclerView: RecyclerView 43 | recyclerView = findViewById(R.id.recycle_view) 44 | recyclerView.setHasFixedSize(true) 45 | recyclerView.layoutManager = LinearLayoutManager(this) 46 | userList = ArrayList() 47 | userAdapter = UserAdapter(this, userList as ArrayList, false) 48 | recyclerView.adapter = userAdapter 49 | 50 | idList = ArrayList() 51 | 52 | when(title){ 53 | "likes" -> getLikes() 54 | "following" -> getFollowing() 55 | "followers" -> getFollowers() 56 | "views" -> getViews() 57 | } 58 | } 59 | 60 | private fun getViews() { 61 | 62 | val ref= FirebaseDatabase.getInstance().reference 63 | .child("Story").child(id!!) 64 | .child(intent.getStringExtra("storyid").toString()) 65 | .child("views") 66 | 67 | 68 | ref.addValueEventListener(object :ValueEventListener{ 69 | override fun onDataChange(snapshot: DataSnapshot) { 70 | (idList as ArrayList).clear() 71 | 72 | for(datasnapshot in snapshot.children) 73 | { 74 | (idList as ArrayList).add(datasnapshot.key!!) 75 | } 76 | 77 | showUsers() 78 | 79 | 80 | } 81 | 82 | override fun onCancelled(error: DatabaseError) { 83 | 84 | } 85 | }) 86 | } 87 | 88 | private fun getFollowers() { 89 | val followersRef = FirebaseDatabase.getInstance().reference 90 | .child("Follow").child(id!!) 91 | .child("Followers") 92 | 93 | followersRef.addValueEventListener(object : ValueEventListener { 94 | override fun onCancelled(p0: DatabaseError) { 95 | } 96 | 97 | override fun onDataChange(p0: DataSnapshot) { 98 | (idList as ArrayList).clear() 99 | for(snapshot in p0.children){ 100 | (idList as ArrayList).add(snapshot.key!!) 101 | } 102 | showUsers() 103 | } 104 | }) 105 | } 106 | 107 | private fun getFollowing() { 108 | val followersRef = FirebaseDatabase.getInstance().reference 109 | .child("Follow").child(id!!) 110 | .child("Following") 111 | 112 | followersRef.addValueEventListener(object : ValueEventListener { 113 | override fun onCancelled(p0: DatabaseError) { 114 | } 115 | override fun onDataChange(p0: DataSnapshot) { 116 | (idList as ArrayList).clear() 117 | for(snapshot in p0.children){ 118 | (idList as ArrayList).add(snapshot.key!!) 119 | } 120 | showUsers() 121 | } 122 | }) 123 | } 124 | 125 | private fun getLikes() { 126 | val LikesRef = FirebaseDatabase.getInstance().reference 127 | .child("Likes").child(id!!) 128 | LikesRef.addValueEventListener(object : ValueEventListener { 129 | override fun onCancelled(p0: DatabaseError) { 130 | } 131 | override fun onDataChange(p0: DataSnapshot) { 132 | if (p0.exists()){ 133 | (idList as ArrayList).clear() 134 | for(snapshot in p0.children){ 135 | (idList as ArrayList).add(snapshot.key!!) 136 | } 137 | showUsers() 138 | } 139 | } 140 | }) 141 | } 142 | 143 | private fun showUsers(){ 144 | val usersRef=FirebaseDatabase.getInstance().reference.child("Users")//table name:Users 145 | usersRef.addValueEventListener(object:ValueEventListener 146 | { 147 | override fun onCancelled(error: DatabaseError) { 148 | } 149 | override fun onDataChange(dataSnapshot: DataSnapshot) { 150 | (userList as ArrayList).clear() 151 | for (snapShot in dataSnapshot.children) { 152 | val user = snapShot.getValue(User::class.java) 153 | 154 | for (id in idList!!){ 155 | if (user!!.getUid() == id) { 156 | (userList as ArrayList).add(user!!) 157 | } 158 | } 159 | } 160 | userAdapter?.notifyDataSetChanged() 161 | } 162 | }) 163 | } 164 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/SignUpActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp 2 | 3 | import android.app.ProgressDialog 4 | import android.content.Intent 5 | import androidx.appcompat.app.AppCompatActivity 6 | import android.os.Bundle 7 | import android.text.TextUtils 8 | import android.widget.Toast 9 | import com.google.firebase.auth.FirebaseAuth 10 | import com.google.firebase.database.DatabaseReference 11 | import com.google.firebase.database.FirebaseDatabase 12 | import kotlinx.android.synthetic.main.activity_sign_up.* 13 | 14 | class SignUpActivity : AppCompatActivity() { 15 | override fun onCreate(savedInstanceState: Bundle?) { 16 | super.onCreate(savedInstanceState) 17 | setContentView(R.layout.activity_sign_up) 18 | 19 | login_link.setOnClickListener { 20 | startActivity(Intent(this,LoginActivity::class.java)) 21 | } 22 | signup_btn.setOnClickListener { 23 | createAccount() 24 | } 25 | 26 | } 27 | 28 | private fun createAccount() { 29 | val fullName=signup_fullname.text.toString() 30 | val userName=signup_username.text.toString() 31 | val email=signup_email.text.toString() 32 | val password=signup_password.text.toString() 33 | 34 | 35 | when{ 36 | TextUtils.isEmpty(fullName)-> Toast.makeText(this, "Name is required", Toast.LENGTH_SHORT).show() 37 | TextUtils.isEmpty(userName)-> Toast.makeText(this, "Username is required", Toast.LENGTH_SHORT).show() 38 | TextUtils.isEmpty(email)-> Toast.makeText(this, "Email is required", Toast.LENGTH_SHORT).show() 39 | TextUtils.isEmpty(password)-> Toast.makeText(this, "Password is required", Toast.LENGTH_SHORT).show() 40 | 41 | else-> 42 | { 43 | val progressDialog= ProgressDialog(this@SignUpActivity) 44 | progressDialog.setTitle("SignUp") 45 | progressDialog.setMessage("Please wait...") 46 | progressDialog.setCanceledOnTouchOutside(false) 47 | progressDialog.show() 48 | 49 | val mAuth: FirebaseAuth = FirebaseAuth.getInstance() 50 | mAuth.createUserWithEmailAndPassword(email,password) 51 | .addOnCompleteListener { task -> 52 | if(task.isSuccessful) 53 | { 54 | saveUserInfo(fullName,userName,email,progressDialog) 55 | } 56 | else 57 | { 58 | val message=task.exception!!.toString() 59 | Toast.makeText(this,"Error : $message", Toast.LENGTH_LONG).show() 60 | mAuth.signOut() 61 | progressDialog.dismiss() 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | private fun saveUserInfo(fullName: String, userName: String, email: String,progressDialog:ProgressDialog) { 69 | val currentUserId=FirebaseAuth.getInstance().currentUser!!.uid 70 | val userRef : DatabaseReference=FirebaseDatabase.getInstance().reference.child("Users") 71 | 72 | val userMap=HashMap() 73 | userMap["uid"]=currentUserId 74 | userMap["fullname"]=fullName 75 | userMap["username"]=userName.toLowerCase() 76 | userMap["email"]=email 77 | userMap["bio"]="Hey! I am using InstaApp" 78 | userMap["image"]="gs://instagram-clone-app-205f9.appspot.com/Default images/profile.png" 79 | 80 | 81 | userRef.child(currentUserId).setValue(userMap) 82 | .addOnCompleteListener {task -> 83 | if(task.isSuccessful) 84 | { 85 | Toast.makeText(this,"Account has been created",Toast.LENGTH_SHORT).show() 86 | 87 | 88 | FirebaseDatabase.getInstance().reference 89 | .child("Follow").child(currentUserId) 90 | .child("Following").child(currentUserId) 91 | .setValue(true) 92 | 93 | 94 | val intent=Intent(this@SignUpActivity,MainActivity::class.java) 95 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) 96 | startActivity(intent) 97 | finish() 98 | } 99 | else 100 | { 101 | val message=task.exception!!.toString() 102 | Toast.makeText(this,"Error : $message", Toast.LENGTH_LONG).show() 103 | FirebaseAuth.getInstance().signOut() 104 | progressDialog.dismiss() 105 | } 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/SplashScreenActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp 2 | 3 | import android.content.Intent 4 | import androidx.appcompat.app.AppCompatActivity 5 | import android.os.Bundle 6 | import android.text.TextPaint 7 | import kotlinx.android.synthetic.main.activity_splash_screen.* 8 | 9 | class SplashScreenActivity : AppCompatActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContentView(R.layout.activity_splash_screen) 13 | 14 | splashscreen.alpha = 0f 15 | splashscreen.animate().setDuration(2200).alpha(1f).withEndAction{ 16 | val i = Intent(this,LoginActivity::class.java) 17 | startActivity(i) 18 | overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out) 19 | finish() 20 | } 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/instaapp/StoryActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.instaapp 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Intent 5 | import androidx.appcompat.app.AppCompatActivity 6 | import android.os.Bundle 7 | import android.view.MotionEvent 8 | import android.view.View 9 | import android.widget.Toast 10 | import com.example.instaapp.Adapter.StoryAdapter 11 | import com.example.instaapp.Model.Story 12 | import com.example.instaapp.Model.User 13 | import com.google.firebase.auth.FirebaseAuth 14 | import com.google.firebase.database.DataSnapshot 15 | import com.google.firebase.database.DatabaseError 16 | import com.google.firebase.database.FirebaseDatabase 17 | import com.google.firebase.database.ValueEventListener 18 | import com.squareup.picasso.Picasso 19 | import jp.shts.android.storiesprogressview.StoriesProgressView 20 | import kotlinx.android.synthetic.main.activity_story.* 21 | 22 | class StoryActivity : AppCompatActivity(), StoriesProgressView.StoriesListener { 23 | 24 | var currentUserId:String="" 25 | var userId:String="" 26 | var counter=0 27 | var pressTime=0L 28 | var limit=500L 29 | 30 | var imagesList:List?=null 31 | var storyIdsList:List?=null 32 | 33 | private val onTouchListener=View.OnTouchListener { view, motionevent -> 34 | when(motionevent.action) 35 | { 36 | MotionEvent.ACTION_DOWN->{ 37 | 38 | pressTime=System.currentTimeMillis() 39 | storiesProgressView!!.pause() 40 | return@OnTouchListener false 41 | 42 | } 43 | MotionEvent.ACTION_UP->{ 44 | 45 | val now=System.currentTimeMillis() 46 | storiesProgressView!!.resume() 47 | return@OnTouchListener limit 106 | 107 | if (task.isSuccessful) 108 | { 109 | Toast.makeText(this,"Deleted Sucessfully",Toast.LENGTH_SHORT).show() 110 | } 111 | } 112 | 113 | } 114 | 115 | } 116 | 117 | private fun addViewToStory(storyId:String) 118 | { 119 | val ref=FirebaseDatabase.getInstance().reference.child("Story").child(userId!!).child(storyId).child("views").child(currentUserId) 120 | .setValue(true) 121 | 122 | } 123 | 124 | private fun getStories(useId: String) 125 | { 126 | 127 | imagesList=ArrayList() 128 | storyIdsList=ArrayList() 129 | 130 | val ref=FirebaseDatabase.getInstance().reference.child("Story").child(userId!!) 131 | 132 | ref.addListenerForSingleValueEvent(object :ValueEventListener{ 133 | override fun onDataChange(datasnapshot: DataSnapshot) { 134 | 135 | (imagesList as ArrayList).clear() 136 | (storyIdsList as ArrayList).clear() 137 | 138 | for(snapshot in datasnapshot.children) 139 | { 140 | val story:Story?=snapshot.getValue(Story::class.java) 141 | val timeCurrent=System.currentTimeMillis() 142 | 143 | if(timeCurrent>story!!.getTimeStart() && timeCurrent).add(story.getImageUrl()) 146 | (storyIdsList as ArrayList).add(story.getStoryId()) 147 | 148 | 149 | } 150 | 151 | } 152 | storiesProgressView!!.setStoriesCount((imagesList as ArrayList).size) 153 | storiesProgressView!!.setStoryDuration(7000L) 154 | storiesProgressView!!.setStoriesListener(this@StoryActivity) 155 | storiesProgressView!!.startStories(counter) 156 | Picasso.get().load(imagesList!!.get(counter)).placeholder(R.drawable.profile).into(image_story) 157 | 158 | addViewToStory(storyIdsList!!.get(counter)) 159 | seenNumber(storyIdsList!!.get(counter)) 160 | 161 | 162 | } 163 | 164 | override fun onCancelled(error: DatabaseError) { 165 | 166 | } 167 | }) 168 | 169 | 170 | } 171 | 172 | 173 | private fun seenNumber(storyId:String) 174 | { 175 | val ref=FirebaseDatabase.getInstance().reference.child("Story").child(userId!!).child(storyId).child("views") 176 | 177 | ref.addListenerForSingleValueEvent(object :ValueEventListener{ 178 | override fun onDataChange(snapshot: DataSnapshot) { 179 | 180 | seen_number.text=" "+snapshot.childrenCount 181 | 182 | } 183 | 184 | override fun onCancelled(error: DatabaseError) { 185 | } 186 | }) 187 | } 188 | 189 | 190 | private fun userInfo(userid:String) 191 | { 192 | val userRef= FirebaseDatabase.getInstance().getReference().child("Users").child(userid) 193 | 194 | userRef.addValueEventListener(object : ValueEventListener { 195 | override fun onDataChange(snapshot: DataSnapshot) { 196 | 197 | 198 | if(snapshot.exists()) 199 | { 200 | val user=snapshot.getValue(User::class.java) 201 | 202 | Picasso.get().load(user!!.getImage()).placeholder(R.drawable.profile).into(story_profile_image) 203 | 204 | story_username!!.text=user.getUsername() 205 | } 206 | 207 | 208 | } 209 | 210 | override fun onCancelled(error: DatabaseError) { 211 | 212 | } 213 | }) 214 | } 215 | 216 | override fun onComplete() { 217 | finish() 218 | } 219 | 220 | override fun onPrev() { 221 | 222 | if (counter-1<0) return 223 | 224 | Picasso.get().load(imagesList!![--counter]).placeholder(R.drawable.profile).into(image_story) 225 | seenNumber(storyIdsList!![counter]) 226 | } 227 | 228 | override fun onNext() { 229 | 230 | Picasso.get().load(imagesList!![++counter]).placeholder(R.drawable.profile).into(image_story) 231 | addViewToStory(storyIdsList!![counter]) 232 | seenNumber(storyIdsList!![counter]) 233 | 234 | 235 | } 236 | 237 | 238 | override fun onDestroy() { 239 | super.onDestroy() 240 | storiesProgressView!!.destroy() 241 | } 242 | 243 | override fun onResume() { 244 | super.onResume() 245 | storiesProgressView!!.resume() 246 | } 247 | 248 | override fun onPause() { 249 | super.onPause() 250 | storiesProgressView!!.pause() 251 | } 252 | 253 | 254 | } 255 | 256 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/add.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/add_image_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/add_image_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/app_ic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/app_ic.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/back_ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/back_ui.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_black_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/buttons_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/camera.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/close.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/comment.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/download.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/grid.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/heart.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/heart_clicked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/heart_clicked.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/heart_not_clicked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/heart_not_clicked.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/home.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_addstory_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | 36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 | 68 | 70 | 72 | 74 | 75 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_addstory_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dashboard_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_home_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_notifications_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/inputs_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/instagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/instagram.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/instagramlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/instagramlogo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/itv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/itv.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/itv2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/itv2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/itv24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/itv24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/itv64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/itv64.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/metalogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/metalogo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/options.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/profile.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/profile_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/profile_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/round_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/save_edited_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/save_edited_info.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/save_large_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/save_large_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/save_post_unfilled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/save_post_unfilled.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/save_unfilled_large_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/save_unfilled_large_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/saved_post_filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/saved_post_filled.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/search.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/send_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/send_icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/tagged.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/tagged.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/taggedpost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/taggedpost.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/vertical_view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/drawable/vertical_view.png -------------------------------------------------------------------------------- /app/src/main/res/font/arimo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FOG-ntp/insta-app-kotlin/a1a32f54d0e871171d12dcb2b729e9e20cd885a1/app/src/main/res/font/arimo.ttf -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_account_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 23 | 24 | 27 | 28 | 36 | 37 | 49 | 50 | 60 | 61 | 62 | 63 | 64 | 70 | 71 | 79 | 87 | 88 | 89 | 99 | 100 | 110 | 111 | 121 | 122 | 132 | 133 | 134 |