init commit
This commit is contained in:
39
README.md
39
README.md
@@ -0,0 +1,39 @@
|
||||
# Ponila (پونیلا)
|
||||
|
||||
Android app for content discovery and recommendation. Ponila helps users find, save, and share interesting content based on their interests.
|
||||
|
||||
## Features
|
||||
|
||||
- **Content Recommendations**: Personalized content suggestions based on user interests
|
||||
- **Collections**: Organize and manage content collections ("دفتر")
|
||||
- **Social Features**: Follow users, like posts, comment, and share
|
||||
- **Search**: Search across posts, collections, and members
|
||||
- **Offline Support**: Browse cached content offline
|
||||
- **Push Notifications**: Real-time notifications for activities
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Language**: Java
|
||||
- **Database**: DBFlow (SQLite)
|
||||
- **Networking**: Retrofit + OkHttp
|
||||
- **Image Loading**: Picasso
|
||||
- **Notifications**: OneSignal
|
||||
- **Analytics**: Google Analytics, Crashlytics
|
||||
- **Build**: Gradle
|
||||
|
||||
## Setup
|
||||
|
||||
1. Clone the repository
|
||||
2. Open in Android Studio
|
||||
3. Configure `google-services.json` and `fabric.properties`
|
||||
4. Set up signing configuration for release builds
|
||||
5. Build and run
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
src/main/java/com/shaya/poinila/
|
||||
├── android/presentation/ # UI layer (Activities, Fragments, ViewHolders)
|
||||
├── data/ # Data layer (Models, Network, Database)
|
||||
└── manager/ # Business logic (DataRepository, DBFacade)
|
||||
```
|
||||
|
||||
136
build.gradle
Executable file
136
build.gradle
Executable file
@@ -0,0 +1,136 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url 'https://maven.fabric.io/public' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'io.fabric.tools:gradle:1.+'
|
||||
}
|
||||
}
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'io.fabric'
|
||||
|
||||
repositories {
|
||||
maven { url 'https://maven.fabric.io/public' }
|
||||
}
|
||||
|
||||
apply plugin: 'com.neenbedankt.android-apt'
|
||||
|
||||
android {
|
||||
compileSdkVersion project.ext.global_compileSdkVersion
|
||||
buildToolsVersion project.ext.global_buildToolsVersion
|
||||
defaultConfig {
|
||||
applicationId "com.shaya.poinila"
|
||||
minSdkVersion project.ext.global_minSdkVersion
|
||||
targetSdkVersion project.ext.global_targetSdkVersion
|
||||
// maxSdkVersion project.ext.global_maxSdkVersion
|
||||
versionCode project.ext.global_versionCode
|
||||
versionName project.ext.global_versionName
|
||||
setProperty("archivesBaseName", "Ponila-$versionName".replace("-release", ""))
|
||||
|
||||
manifestPlaceholders = [manifestApplicationId: "${applicationId}",
|
||||
onesignal_app_id: "ec125f7c-f3d9-48c9-ba01-79699f7e7118",
|
||||
onesignal_google_project_number: "167856249045"]
|
||||
}
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file("myreleasekey.keystore")
|
||||
storePassword System.getenv("KEYSTOREPWD")
|
||||
keyAlias "MyReleaseKey"
|
||||
keyPassword System.getenv("KEYPWD")
|
||||
}
|
||||
|
||||
debug {
|
||||
storeFile file('/home/hossein/android/keystores/poinila.jks')
|
||||
storePassword '2d858dce8c0b9a6bb9f411d0a891fb8dc7718ea6'
|
||||
keyAlias 'PoinilaReleaseKey'
|
||||
keyPassword '36f4f28b92e39ff719e1e261f67fe75825c552f6'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
zipAlignEnabled true
|
||||
debuggable false
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
encoding "UTF-8"
|
||||
}
|
||||
// debug {
|
||||
// versionNameSuffix "-DEBUG"
|
||||
// applicationIdSuffix ".debug"
|
||||
// }
|
||||
}
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
disable "ResourceType"
|
||||
}
|
||||
productFlavors {
|
||||
}
|
||||
|
||||
aaptOptions{
|
||||
cruncherEnabled = false
|
||||
}
|
||||
|
||||
// butterknife and parceler conflict
|
||||
packagingOptions {
|
||||
exclude 'META-INF/services/javax.annotation.processing.Processor' // butterknife
|
||||
}
|
||||
}
|
||||
|
||||
def dbflow_version = "3.1.1"
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
||||
compile project(':util')
|
||||
// compile project(':downloadmanager')
|
||||
compile 'com.jakewharton:butterknife:7.0.1'
|
||||
compile 'de.hdodenhof:circleimageview:1.3.0'
|
||||
compile 'org.apmem.tools:layouts:1.10@aar'
|
||||
compile 'com.squareup.picasso:picasso:2.5.2'
|
||||
compile 'com.android.support:cardview-v7:' + project.ext.supportLibVersion
|
||||
compile 'com.android.support:recyclerview-v7:' + project.ext.supportLibVersion
|
||||
compile 'com.android.support:design:' + project.ext.supportLibVersion
|
||||
//compile 'com.android.support:percent:' + project.ext.supportLibVersion
|
||||
compile 'com.mobsandgeeks:android-saripaar:2.0.3'
|
||||
compile 'com.getbase:floatingactionbutton:1.10.1'
|
||||
//debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
|
||||
//releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
|
||||
compile 'com.yqritc:recyclerview-flexibledivider:1.2.8'
|
||||
compile 'com.isseiaoki:simplecropview:1.0.16'
|
||||
compile 'com.makeramen:roundedimageview:2.2.1'
|
||||
compile 'me.relex:circleindicator:1.1.8@aar'
|
||||
compile 'uk.co.chrisjenx:calligraphy:2.1.0'
|
||||
compile 'ru.noties:debug:2.0.1'
|
||||
compile 'com.squareup.retrofit:retrofit:1.9.0'
|
||||
compile 'com.squareup.okhttp:okhttp:2.4.0'
|
||||
//debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
|
||||
//releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
|
||||
compile "org.parceler:parceler-api:1.1.5"
|
||||
apt "org.parceler:parceler:1.1.5"
|
||||
|
||||
apt "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}"
|
||||
// use kapt for kotlin apt
|
||||
compile "com.github.Raizlabs.DBFlow:dbflow-core:${dbflow_version}"
|
||||
compile "com.github.Raizlabs.DBFlow:dbflow:${dbflow_version}"
|
||||
|
||||
|
||||
compile 'com.onesignal:OneSignal:2.+@aar'
|
||||
compile 'com.google.android.gms:play-services-gcm:9.0.2'
|
||||
compile 'com.google.android.gms:play-services-analytics:9.0.2'
|
||||
compile "com.google.android.gms:play-services-location:9.0.2"
|
||||
compile 'com.google.android.gms:play-services-auth:9.0.2'
|
||||
compile 'com.google.android.gms:play-services-ads:9.0.2'
|
||||
|
||||
compile 'com.android.support:customtabs:23.3.0'
|
||||
compile('com.crashlytics.sdk.android:crashlytics:2.5.7@aar') {
|
||||
transitive = true;
|
||||
}
|
||||
compile "com.tapstream.sdk:tapstream-android:3.1.0"
|
||||
}
|
||||
|
||||
3
fabric.properties
Executable file
3
fabric.properties
Executable file
@@ -0,0 +1,3 @@
|
||||
#Contains API Secret used to validate your application. Commit to internal source control; avoid making secret public.
|
||||
#Sat Jul 02 09:01:21 IRDT 2016
|
||||
apiSecret=7a1d121a5dfbd03c3068c40fcb308e1ae13bffa2a3e1a172b4e9e92bd90b52d6
|
||||
48
google-services.json
Executable file
48
google-services.json
Executable file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "167856249045",
|
||||
"project_id": "ponila-official"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:167856249045:android:55a0071f579cd514",
|
||||
"android_client_info": {
|
||||
"package_name": "com.shaya.poinila"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "167856249045-k57ge2m42jpeds4bmsrf97ncr44aoj0u.apps.googleusercontent.com",
|
||||
"client_type": 1,
|
||||
"android_info": {
|
||||
"package_name": "com.shaya.poinila",
|
||||
"certificate_hash": "EE4EA336D24FE4723DB34BF0CA9BF152A559AF5A"
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_id": "167856249045-bt5tjuk0io8tgq64m5d1uprdh6vb563t.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyAKNoFedZSzmvVSXbMba07n4e_Z4wszEpc"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"analytics_service": {
|
||||
"status": 1
|
||||
},
|
||||
"appinvite_service": {
|
||||
"status": 1,
|
||||
"other_platform_oauth_client": []
|
||||
},
|
||||
"ads_service": {
|
||||
"status": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
55
proguard-rules.pro
vendored
Executable file
55
proguard-rules.pro
vendored
Executable file
@@ -0,0 +1,55 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in D:\Android\android-sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Picasso
|
||||
-dontwarn com.squareup.okhttp.**
|
||||
|
||||
# Butter knife library
|
||||
-keep class butterknife.** { *; }
|
||||
-dontwarn butterknife.internal.**
|
||||
-keep class **$$ViewBinder { *; }
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
@butterknife.* <fields>;
|
||||
}
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
@butterknife.* <methods>;
|
||||
}
|
||||
|
||||
# Saripaar Form Validation
|
||||
-keep class com.mobsandgeeks.saripaar.** {*;}
|
||||
-keep class commons.validator.routines.** {*;}
|
||||
-keep @com.mobsandgeeks.saripaar.annotation.ValidateUsing class * {*;}
|
||||
|
||||
# LeakCanary
|
||||
-keep class org.eclipse.mat.** { *; }
|
||||
-keep class com.squareup.leakcanary.** { *; }
|
||||
|
||||
# parcelable error (Unmarshalling unknown type code)
|
||||
-keepclassmembers class * implements android.os.Parcelable {
|
||||
static ** CREATOR;
|
||||
}
|
||||
|
||||
# Fabric
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keep public class * extends java.lang.Exception
|
||||
|
||||
# Tap Stream
|
||||
-keep class com.google.android.gms.ads.identifier.** { *; }
|
||||
BIN
src/.DS_Store
vendored
Normal file
BIN
src/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,13 @@
|
||||
package com.shaya.poinila.android.presentation;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
||||
BIN
src/main/.DS_Store
vendored
Normal file
BIN
src/main/.DS_Store
vendored
Normal file
Binary file not shown.
273
src/main/AndroidManifest.xml
Executable file
273
src/main/AndroidManifest.xml
Executable file
@@ -0,0 +1,273 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.shaya.poinila.android.presentation">
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.camera"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_SMS" /> <!--Dangerous Permission-->
|
||||
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!--Dangerous Permission-->
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
|
||||
<!--<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />-->
|
||||
<application
|
||||
android:name=".PoinilaApplication"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".view.activity.MainActivity"
|
||||
android:clearTaskOnLaunch="true"
|
||||
android:label="@string/title_activity_main"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:host="www.ponila.com" />
|
||||
<data android:host="ponila.com" />
|
||||
<data android:host="192.168.1.103" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.SignUpLoginActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:label="@string/title_activity_sign_up_login"
|
||||
android:windowSoftInputMode="adjustPan">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.CommentsListActivity"
|
||||
android:label="@string/title_activity_comments_list"
|
||||
android:parentActivityName=".view.activity.MainActivity"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.MainActivity" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".view.activity.SettingActivity"
|
||||
android:label="@string/title_activity_setting"
|
||||
android:parentActivityName=".view.activity.MainActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.EditInterestsActivity"
|
||||
android:label="@string/title_activity_edit_interests"
|
||||
android:parentActivityName=".view.activity.MainActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.SelectInterestActivity"
|
||||
android:label="@string/title_activity_select_interests_actvity"/>
|
||||
<activity
|
||||
android:name=".view.activity.CirclesManagementActivity"
|
||||
android:label="@string/title_activity_circles_management"
|
||||
android:parentActivityName=".view.activity.SettingActivity">
|
||||
<meta-member
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.SettingActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.NotificationSwitchActivity"
|
||||
android:label="@string/title_activity_application_notification"
|
||||
android:parentActivityName=".view.activity.SettingActivity">
|
||||
<meta-member
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.SettingActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.ProfileSettingActivity"
|
||||
android:label="@string/title_activity_profile_setting"
|
||||
android:parentActivityName=".view.activity.SettingActivity">
|
||||
<meta-member
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.SettingActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.FramesManagementActivity"
|
||||
android:label="@string/title_activity_frames_management"
|
||||
android:parentActivityName=".view.activity.SettingActivity">
|
||||
<meta-member
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.SettingActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.MemberListActivity"
|
||||
android:label="@string/title_activity_member_followers"
|
||||
android:parentActivityName=".view.activity.MainActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.MainActivity" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".view.activity.PostListActivity"
|
||||
android:label="@string/title_activity_post"
|
||||
android:parentActivityName=".view.activity.MainActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.NewPostActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:label="@string/new_post"
|
||||
android:windowSoftInputMode="adjustPan">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".view.activity.OthersProfileActivity"
|
||||
android:label="@string/title_activity_others_profile"
|
||||
android:parentActivityName=".view.activity.MainActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.MainActivity" />
|
||||
<!--<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:host="www.ponila.com" />
|
||||
<data android:host="ponila.com" />
|
||||
<data android:host="192.168.1.103" />
|
||||
</intent-filter>-->
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".view.activity.CollectionListActivity"
|
||||
android:label="@string/title_activity_collection_list"
|
||||
android:parentActivityName=".view.activity.MainActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.SplashActivity"
|
||||
android:label="@string/app_name"
|
||||
android:noHistory="true"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
|
||||
|
||||
<!-- android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen" -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.FullImageActivity"
|
||||
android:theme="@style/full_image_activity"/>
|
||||
<activity
|
||||
android:name=".view.activity.CropImageActivity"
|
||||
android:theme="@style/full_image_activity"/>
|
||||
<activity
|
||||
android:name=".view.activity.ChangePasswordActivity"
|
||||
android:label="@string/title_activity_change_password"
|
||||
android:parentActivityName=".view.activity.SettingActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.SettingActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.InvitationNotifListActivity"
|
||||
android:label="@string/title_activity_invitation_notif_list"
|
||||
android:parentActivityName=".view.activity.MainActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.HelpActivity"
|
||||
android:label="@string/title_activity_help"/>
|
||||
<activity
|
||||
android:name=".view.activity.AppSettingActivity"
|
||||
android:label="@string/app_settings"
|
||||
android:parentActivityName=".view.activity.SettingActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".view.activity.SettingActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".view.activity.WebviewActivity"
|
||||
android:label="@string/title_activity_webview"
|
||||
android:hardwareAccelerated="true">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".view.activity.ChromeActivity"
|
||||
android:label="srdsfsdfsdfdsf">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".view.activity.NotificationOpenedActivity"
|
||||
android:label=""/>
|
||||
|
||||
|
||||
<service android:name="com.shaya.poinila.android.authentication.AuthenticationService" >
|
||||
<intent-filter>
|
||||
<action android:name="android.accounts.AccountAuthenticator" >
|
||||
</action>
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.accounts.AccountAuthenticator"
|
||||
android:resource="@layout/authenticator" >
|
||||
</meta-data>
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name="com.shaya.poinila.android.NotificationService"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.onesignal.NotificationExtender" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<meta-data android:name="com.onesignal.NotificationOpened.DEFAULT" android:value="DISABLE" />
|
||||
|
||||
<receiver android:name=".SmsReceiver" android:exported="true" >
|
||||
<intent-filter android:priority="1000">
|
||||
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name="com.tapstream.sdk.ReferrerReceiver" android:exported="true" >
|
||||
<intent-filter>
|
||||
<action android:name="com.android.vending.INSTALL_REFERRER" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!--<receiver-->
|
||||
<!--android:name="com.shaya.poinila.android.presentation.OneSignalReceiver"-->
|
||||
<!--android:exported="false">-->
|
||||
<!--<intent-filter>-->
|
||||
<!--<action android:name="com.onesignal.BackgroundBroadcast.RECEIVE" />-->
|
||||
<!--</intent-filter>-->
|
||||
<!--</receiver>-->
|
||||
|
||||
<meta-data
|
||||
android:name="io.fabric.ApiKey"
|
||||
android:value="be690570e63d95c30727708af7a2c38bcc72fe80" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
BIN
src/main/assets/.DS_Store
vendored
Normal file
BIN
src/main/assets/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/main/assets/fonts/iransans.ttf
Executable file
BIN
src/main/assets/fonts/iransans.ttf
Executable file
Binary file not shown.
BIN
src/main/ic_launcher-web.png
Executable file
BIN
src/main/ic_launcher-web.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
BIN
src/main/java/.DS_Store
vendored
Normal file
BIN
src/main/java/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/main/java/android/.DS_Store
vendored
Normal file
BIN
src/main/java/android/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/main/java/android/support/.DS_Store
vendored
Normal file
BIN
src/main/java/android/support/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/main/java/android/support/design/.DS_Store
vendored
Normal file
BIN
src/main/java/android/support/design/.DS_Store
vendored
Normal file
Binary file not shown.
768
src/main/java/android/support/design/widget/PoinilaTextInputLayout.java
Executable file
768
src/main/java/android/support/design/widget/PoinilaTextInputLayout.java
Executable file
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.support.design.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StyleRes;
|
||||
import android.support.v4.view.AccessibilityDelegateCompat;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
|
||||
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
|
||||
import android.support.v4.widget.Space;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import android.support.design.R;
|
||||
|
||||
import com.shaya.poinila.android.util.ResourceUtils;
|
||||
|
||||
import uk.co.chrisjenx.calligraphy.CalligraphyConfig;
|
||||
import uk.co.chrisjenx.calligraphy.CalligraphyUtils;
|
||||
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
|
||||
/**
|
||||
* This class is a copy of Android support design library intending to use for rtl languages.
|
||||
* @author Alireza Farahani. contact me at ar.d.farahani@gmail.com
|
||||
*
|
||||
* Layout which wraps an {@link android.widget.EditText} (or descendant) to show a floating label
|
||||
* when the hint is hidden due to the user inputting text.
|
||||
* <p/>
|
||||
* Also supports showing an error via {@link #setErrorEnabled(boolean)} and
|
||||
* {@link #setError(CharSequence)}.
|
||||
*/
|
||||
public class PoinilaTextInputLayout extends LinearLayout {
|
||||
|
||||
private static final int ANIMATION_DURATION = 200;
|
||||
private static final int INVALID_MAX_LENGTH = -1;
|
||||
|
||||
private EditText mEditText;
|
||||
private CharSequence mHint;
|
||||
|
||||
private Paint mTmpPaint;
|
||||
|
||||
private LinearLayout mIndicatorArea;
|
||||
|
||||
private boolean mErrorEnabled;
|
||||
private TextView mErrorView;
|
||||
private int mErrorTextAppearance;
|
||||
private boolean mErrorShown;
|
||||
|
||||
private boolean mCounterEnabled;
|
||||
private TextView mCounterView;
|
||||
private int mCounterMaxLength;
|
||||
private int mCounterTextAppearance;
|
||||
private int mCounterOverflowTextAppearance;
|
||||
private boolean mCounterOverflowed;
|
||||
// alireza farahani
|
||||
private boolean mHasSimpleBackground = false; // temporary solution for handling edittext color change when having error
|
||||
|
||||
private ColorStateList mDefaultTextColor;
|
||||
private ColorStateList mFocusedTextColor;
|
||||
|
||||
private final CollapsingTextHelper mCollapsingTextHelper = new CollapsingTextHelper(this);
|
||||
|
||||
private boolean mHintAnimationEnabled;
|
||||
private ValueAnimatorCompat mAnimator;
|
||||
|
||||
public PoinilaTextInputLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public PoinilaTextInputLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public PoinilaTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
// Can't call through to super(Context, AttributeSet, int) since it doesn't exist on API 10
|
||||
super(context, attrs);
|
||||
|
||||
ThemeUtils.checkAppCompatTheme(context);
|
||||
|
||||
setOrientation(VERTICAL);
|
||||
setWillNotDraw(false);
|
||||
setAddStatesFromChildren(true);
|
||||
|
||||
mCollapsingTextHelper.setTextSizeInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR);
|
||||
mCollapsingTextHelper.setPositionInterpolator(new AccelerateInterpolator());
|
||||
mCollapsingTextHelper.setCollapsedTextGravity(Gravity.TOP | Gravity.RIGHT); // alireza farahani
|
||||
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.TextInputLayout, defStyleAttr, R.style.Widget_Design_TextInputLayout);
|
||||
setHint(a.getText(R.styleable.TextInputLayout_android_hint));
|
||||
mHintAnimationEnabled = a.getBoolean(
|
||||
R.styleable.TextInputLayout_hintAnimationEnabled, true);
|
||||
|
||||
if (a.hasValue(R.styleable.TextInputLayout_android_textColorHint)) {
|
||||
mDefaultTextColor = mFocusedTextColor =
|
||||
a.getColorStateList(R.styleable.TextInputLayout_android_textColorHint);
|
||||
}
|
||||
|
||||
final int hintAppearance = a.getResourceId(
|
||||
R.styleable.TextInputLayout_hintTextAppearance, -1);
|
||||
if (hintAppearance != -1) {
|
||||
setHintTextAppearance(
|
||||
a.getResourceId(R.styleable.TextInputLayout_hintTextAppearance, 0));
|
||||
}
|
||||
|
||||
mErrorTextAppearance = a.getResourceId(R.styleable.TextInputLayout_errorTextAppearance, 0);
|
||||
final boolean errorEnabled = a.getBoolean(R.styleable.TextInputLayout_errorEnabled, false);
|
||||
|
||||
final boolean counterEnabled = a.getBoolean(
|
||||
R.styleable.TextInputLayout_counterEnabled, false);
|
||||
setCounterMaxLength(
|
||||
a.getInt(R.styleable.TextInputLayout_counterMaxLength, INVALID_MAX_LENGTH));
|
||||
mCounterTextAppearance = a.getResourceId(
|
||||
R.styleable.TextInputLayout_counterTextAppearance, 0);
|
||||
mCounterOverflowTextAppearance = a.getResourceId(
|
||||
R.styleable.TextInputLayout_counterOverflowTextAppearance, 0);
|
||||
|
||||
// alireza farahani
|
||||
final TypedArray poinila_a = context.obtainStyledAttributes(attrs, com.shaya.poinila.android.presentation.R.styleable.PoinilaTextInputLayout);
|
||||
mHasSimpleBackground = poinila_a.getBoolean(com.shaya.poinila.android.presentation.R.styleable.PoinilaTextInputLayout_hasSimpleBackground, false);
|
||||
poinila_a.recycle();
|
||||
|
||||
a.recycle();
|
||||
|
||||
setErrorEnabled(errorEnabled);
|
||||
setCounterEnabled(counterEnabled);
|
||||
|
||||
if (ViewCompat.getImportantForAccessibility(this)
|
||||
== ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
|
||||
// Make sure we're important for accessibility if we haven't been explicitly not
|
||||
ViewCompat.setImportantForAccessibility(this,
|
||||
ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
|
||||
}
|
||||
|
||||
ViewCompat.setAccessibilityDelegate(this, new TextInputAccessibilityDelegate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child, int index, ViewGroup.LayoutParams params) {
|
||||
if (child instanceof EditText) {
|
||||
setEditText((EditText) child);
|
||||
super.addView(child, 0, updateEditTextMargin(params));
|
||||
} else {
|
||||
// Carry on adding the View...
|
||||
super.addView(child, index, params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the typeface to use for both the expanded and floating hint.
|
||||
*
|
||||
* @param typeface typeface to use, or {@code null} to use the default.
|
||||
*/
|
||||
public void setTypeface(@Nullable Typeface typeface) {
|
||||
mCollapsingTextHelper.setTypefaces(typeface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the typeface used for both the expanded and floating hint.
|
||||
*/
|
||||
@NonNull
|
||||
public Typeface getTypeface() {
|
||||
// This could be either the collapsed or expanded
|
||||
return mCollapsingTextHelper.getCollapsedTypeface();
|
||||
}
|
||||
|
||||
private void setEditText(EditText editText) {
|
||||
// If we already have an EditText, throw an exception
|
||||
if (mEditText != null) {
|
||||
throw new IllegalArgumentException("We already have an EditText, can only have one");
|
||||
}
|
||||
mEditText = editText;
|
||||
|
||||
// Use the EditText's typeface, and it's text size for our expanded text
|
||||
mCollapsingTextHelper.setTypefaces(mEditText.getTypeface());
|
||||
mCollapsingTextHelper.setExpandedTextSize(mEditText.getTextSize());
|
||||
mCollapsingTextHelper.setExpandedTextGravity(mEditText.getGravity());
|
||||
|
||||
// Add a TextWatcher so that we know when the text input has changed
|
||||
mEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
updateLabelVisibility(true);
|
||||
if (mCounterEnabled) {
|
||||
updateCounter(s.length());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
});
|
||||
|
||||
// Use the EditText's hint colors if we don't have one set
|
||||
if (mDefaultTextColor == null) {
|
||||
mDefaultTextColor = mEditText.getHintTextColors();
|
||||
}
|
||||
|
||||
// If we do not have a valid hint, try and retrieve it from the EditText
|
||||
if (TextUtils.isEmpty(mHint)) {
|
||||
setHint(mEditText.getHint());
|
||||
// Clear the EditText's hint as we will display it ourselves
|
||||
mEditText.setHint(null);
|
||||
}
|
||||
|
||||
if (mCounterView != null) {
|
||||
updateCounter(mEditText.getText().length());
|
||||
}
|
||||
|
||||
if (mIndicatorArea != null) {
|
||||
adjustIndicatorPadding();
|
||||
}
|
||||
|
||||
// Update the label visibility with no animation
|
||||
updateLabelVisibility(false);
|
||||
}
|
||||
|
||||
private LayoutParams updateEditTextMargin(ViewGroup.LayoutParams lp) {
|
||||
// Create/update the LayoutParams so that we can add enough top margin
|
||||
// to the EditText so make room for the label
|
||||
LayoutParams llp = lp instanceof LayoutParams ? (LayoutParams) lp : new LayoutParams(lp);
|
||||
|
||||
if (mTmpPaint == null) {
|
||||
mTmpPaint = new Paint();
|
||||
}
|
||||
mTmpPaint.setTypeface(mCollapsingTextHelper.getCollapsedTypeface());
|
||||
mTmpPaint.setTextSize(mCollapsingTextHelper.getCollapsedTextSize());
|
||||
llp.topMargin = (int) -mTmpPaint.ascent();
|
||||
|
||||
return llp;
|
||||
}
|
||||
|
||||
private void updateLabelVisibility(boolean animate) {
|
||||
final boolean hasText = mEditText != null && !TextUtils.isEmpty(mEditText.getText());
|
||||
final boolean isFocused = arrayContains(getDrawableState(), android.R.attr.state_focused);
|
||||
final boolean isErrorShowing = !TextUtils.isEmpty(getError());
|
||||
|
||||
if (mDefaultTextColor != null) {
|
||||
mCollapsingTextHelper.setExpandedTextColor(mDefaultTextColor.getDefaultColor());
|
||||
}
|
||||
|
||||
if (mCounterOverflowed && mCounterView != null) {
|
||||
mCollapsingTextHelper.setCollapsedTextColor(mCounterView.getCurrentTextColor());
|
||||
} else if (isErrorShowing && mErrorView != null) {
|
||||
mCollapsingTextHelper.setCollapsedTextColor(mErrorView.getCurrentTextColor());
|
||||
} else if (isFocused && mFocusedTextColor != null) {
|
||||
mCollapsingTextHelper.setCollapsedTextColor(mFocusedTextColor.getDefaultColor());
|
||||
} else if (mDefaultTextColor != null) {
|
||||
mCollapsingTextHelper.setCollapsedTextColor(mDefaultTextColor.getDefaultColor());
|
||||
}
|
||||
|
||||
if (hasText || isFocused || isErrorShowing) {
|
||||
// We should be showing the label so do so if it isn't already
|
||||
collapseHint(animate);
|
||||
} else {
|
||||
// We should not be showing the label so hide it
|
||||
expandHint(animate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link android.widget.EditText} used for text input.
|
||||
*/
|
||||
@Nullable
|
||||
public EditText getEditText() {
|
||||
return mEditText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the hint to be displayed in the floating label
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#TextInputLayout_android_hint
|
||||
*/
|
||||
public void setHint(@Nullable CharSequence hint) {
|
||||
mHint = hint;
|
||||
mCollapsingTextHelper.setText(hint);
|
||||
|
||||
sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hint which is displayed in the floating label.
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#TextInputLayout_android_hint
|
||||
*/
|
||||
@Nullable
|
||||
public CharSequence getHint() {
|
||||
return mHint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hint text color, size, style from the specified TextAppearance resource.
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#TextInputLayout_hintTextAppearance
|
||||
*/
|
||||
public void setHintTextAppearance(@StyleRes int resId) {
|
||||
mCollapsingTextHelper.setCollapsedTextAppearance(resId);
|
||||
mFocusedTextColor = ColorStateList.valueOf(mCollapsingTextHelper.getCollapsedTextColor());
|
||||
|
||||
if (mEditText != null) {
|
||||
updateLabelVisibility(false);
|
||||
|
||||
// Text size might have changed so update the top margin
|
||||
LayoutParams lp = updateEditTextMargin(mEditText.getLayoutParams());
|
||||
mEditText.setLayoutParams(lp);
|
||||
mEditText.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addIndicator(TextView indicator, int index) {
|
||||
if (mIndicatorArea == null) {
|
||||
mIndicatorArea = new LinearLayout(getContext());
|
||||
/*RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
|
||||
RelativeLayout.LayoutParams.WRAP_CONTENT);
|
||||
mIndicatorArea.setGravity(Gravity.RIGHT);*/
|
||||
mIndicatorArea.setOrientation(LinearLayout.HORIZONTAL);
|
||||
/* alireza farahani */
|
||||
mIndicatorArea.setGravity(Gravity.RIGHT);
|
||||
addView(mIndicatorArea, LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
WRAP_CONTENT);
|
||||
/* alireza farahani */
|
||||
|
||||
// Add a flexible spacer in the middle so that the left/right views stay pinned
|
||||
final Space spacer = new Space(getContext());
|
||||
|
||||
/* alireza farahani */
|
||||
final LinearLayout.LayoutParams spacerLp = new LinearLayout.LayoutParams(0,
|
||||
((int) ResourceUtils.getDimen(com.shaya.poinila.android.presentation.R.dimen.margin_lvl2)));//0, 1f);
|
||||
|
||||
mIndicatorArea.addView(spacer, spacerLp);
|
||||
|
||||
if (mEditText != null) {
|
||||
adjustIndicatorPadding();
|
||||
}
|
||||
}
|
||||
/* alireza farahani */
|
||||
mIndicatorArea.setVisibility(View.VISIBLE);
|
||||
if (index == Integer.MAX_VALUE) { // adding error to right of layout
|
||||
index = mIndicatorArea.getChildCount();
|
||||
mIndicatorArea.addView(indicator, index);
|
||||
} else { // adding counter
|
||||
mIndicatorArea.addView(indicator, new LinearLayout.LayoutParams(0, WRAP_CONTENT, 1f));
|
||||
}
|
||||
/* alireza farahani */
|
||||
}
|
||||
|
||||
private void adjustIndicatorPadding() {
|
||||
// Add padding to the error and character counter so that they match the EditText
|
||||
ViewCompat.setPaddingRelative(mIndicatorArea, ViewCompat.getPaddingStart(mEditText),
|
||||
0, ViewCompat.getPaddingEnd(mEditText), mEditText.getPaddingBottom());
|
||||
}
|
||||
|
||||
private void removeIndicator(TextView indicator) {
|
||||
if (mIndicatorArea != null) {
|
||||
mIndicatorArea.removeView(indicator);
|
||||
if (mIndicatorArea.getChildCount() == 0) {
|
||||
mIndicatorArea.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the error functionality is enabled or not in this layout. Enabling this
|
||||
* functionality before setting an error message via {@link #setError(CharSequence)}, will mean
|
||||
* that this layout will not change size when an error is displayed.
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#TextInputLayout_errorEnabled
|
||||
*/
|
||||
public void setErrorEnabled(boolean enabled) {
|
||||
if (mErrorEnabled != enabled) {
|
||||
if (mErrorView != null) {
|
||||
ViewCompat.animate(mErrorView).cancel();
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
mErrorView = new TextView(getContext());
|
||||
mErrorView.setTextAppearance(getContext(), mErrorTextAppearance);
|
||||
|
||||
//alireza farahani
|
||||
CalligraphyUtils.applyFontToTextView(mErrorView.getContext(), mErrorView, CalligraphyConfig.get().getFontPath());
|
||||
|
||||
mErrorView.setVisibility(INVISIBLE);
|
||||
ViewCompat.setAccessibilityLiveRegion(mErrorView,
|
||||
ViewCompat.ACCESSIBILITY_LIVE_REGION_POLITE);
|
||||
addIndicator(mErrorView, Integer.MAX_VALUE);
|
||||
} else {
|
||||
mErrorShown = false;
|
||||
updateEditTextBackground();
|
||||
removeIndicator(mErrorView);
|
||||
mErrorView = null;
|
||||
}
|
||||
mErrorEnabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the error functionality is enabled or not in this layout.
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#TextInputLayout_errorEnabled
|
||||
* @see #setErrorEnabled(boolean)
|
||||
*/
|
||||
public boolean isErrorEnabled() {
|
||||
return mErrorEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an error message that will be displayed below our {@link EditText}. If the
|
||||
* {@code error} is {@code null}, the error message will be cleared.
|
||||
* <p/>
|
||||
* If the error functionality has not been enabled via {@link #setErrorEnabled(boolean)}, then
|
||||
* it will be automatically enabled if {@code error} is not empty.
|
||||
*
|
||||
* @param error Error message to display, or null to clear
|
||||
* @see #getError()
|
||||
*/
|
||||
public void setError(@Nullable CharSequence error) {
|
||||
if (!mErrorEnabled) {
|
||||
if (TextUtils.isEmpty(error)) {
|
||||
// If error isn't enabled, and the error is empty, just return
|
||||
return;
|
||||
}
|
||||
// Else, we'll assume that they want to enable the error functionality
|
||||
setErrorEnabled(true);
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(error)) {
|
||||
ViewCompat.setAlpha(mErrorView, 0f);
|
||||
mErrorView.setText(error);
|
||||
ViewCompat.animate(mErrorView)
|
||||
.alpha(1f)
|
||||
.setDuration(ANIMATION_DURATION)
|
||||
.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR)
|
||||
.setListener(new ViewPropertyAnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(View view) {
|
||||
view.setVisibility(VISIBLE);
|
||||
}
|
||||
})
|
||||
.start();
|
||||
|
||||
// Set the EditText's background tint to the error color
|
||||
mErrorShown = true;
|
||||
updateEditTextBackground();
|
||||
updateLabelVisibility(true);
|
||||
} else {
|
||||
if (mErrorView.getVisibility() == VISIBLE) {
|
||||
ViewCompat.animate(mErrorView)
|
||||
.alpha(0f)
|
||||
.setDuration(ANIMATION_DURATION)
|
||||
.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR)
|
||||
.setListener(new ViewPropertyAnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(View view) {
|
||||
view.setVisibility(INVISIBLE);
|
||||
|
||||
updateLabelVisibility(true);
|
||||
}
|
||||
}).start();
|
||||
|
||||
// Restore the 'original' tint, using colorControlNormal and colorControlActivated
|
||||
mErrorShown = false;
|
||||
updateEditTextBackground();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the character counter functionality is enabled or not in this layout.
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#TextInputLayout_counterEnabled
|
||||
*/
|
||||
public void setCounterEnabled(boolean enabled) {
|
||||
if (mCounterEnabled != enabled) {
|
||||
if (enabled) {
|
||||
mCounterView = new TextView(getContext());
|
||||
mCounterView.setGravity(Gravity.LEFT);
|
||||
mCounterView.setMaxLines(1);
|
||||
mCounterView.setTextAppearance(getContext(), mCounterTextAppearance);
|
||||
ViewCompat.setAccessibilityLiveRegion(mCounterView,
|
||||
ViewCompat.ACCESSIBILITY_LIVE_REGION_POLITE);
|
||||
|
||||
// alireza farahani
|
||||
addIndicator(mCounterView, 0);
|
||||
CalligraphyUtils.applyFontToTextView(mCounterView.getContext(), mCounterView, CalligraphyConfig.get().getFontPath());
|
||||
|
||||
if (mEditText == null) {
|
||||
updateCounter(0);
|
||||
} else {
|
||||
updateCounter(mEditText.getText().length());
|
||||
}
|
||||
} else {
|
||||
removeIndicator(mCounterView);
|
||||
mCounterView = null;
|
||||
}
|
||||
mCounterEnabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the max length to display at the character counter.
|
||||
*
|
||||
* @param maxLength maxLength to display. Any value less than or equal to 0 will not be shown.
|
||||
*/
|
||||
public void setCounterMaxLength(int maxLength) {
|
||||
if (mCounterMaxLength != maxLength) {
|
||||
if (maxLength > 0) {
|
||||
mCounterMaxLength = maxLength;
|
||||
} else {
|
||||
mCounterMaxLength = INVALID_MAX_LENGTH;
|
||||
}
|
||||
if (mCounterEnabled) {
|
||||
updateCounter(mEditText == null ? 0 : mEditText.getText().length());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the max length shown at the character counter.
|
||||
*/
|
||||
public int getCounterMaxLength() {
|
||||
return mCounterMaxLength;
|
||||
}
|
||||
|
||||
private void updateCounter(int length) {
|
||||
boolean wasCounterOverflowed = mCounterOverflowed;
|
||||
if (mCounterMaxLength == INVALID_MAX_LENGTH) {
|
||||
mCounterView.setText(String.valueOf(length));
|
||||
mCounterOverflowed = false;
|
||||
} else {
|
||||
mCounterOverflowed = length > mCounterMaxLength;
|
||||
if (wasCounterOverflowed != mCounterOverflowed) {
|
||||
mCounterView.setTextAppearance(getContext(), mCounterOverflowed ?
|
||||
mCounterOverflowTextAppearance : mCounterTextAppearance);
|
||||
// alireza farahani
|
||||
CalligraphyUtils.applyFontToTextView(mCounterView.getContext(), mCounterView, CalligraphyConfig.get().getFontPath());
|
||||
}
|
||||
mCounterView.setText(getContext().getString(R.string.character_counter_pattern,
|
||||
length, mCounterMaxLength));
|
||||
}
|
||||
if (mEditText != null && wasCounterOverflowed != mCounterOverflowed) {
|
||||
updateLabelVisibility(false);
|
||||
updateEditTextBackground();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEditTextBackground() { // alireza farahani. handling cases in which edittext has custom background
|
||||
if (mErrorShown && mErrorView != null && mHasSimpleBackground) {
|
||||
// Set the EditText's background tint to the error color
|
||||
ViewCompat.setBackgroundTintList(mEditText,
|
||||
ColorStateList.valueOf(mErrorView.getCurrentTextColor()));
|
||||
} else if (mCounterOverflowed && mCounterView != null && mHasSimpleBackground) {
|
||||
ViewCompat.setBackgroundTintList(mEditText,
|
||||
ColorStateList.valueOf(mCounterView.getCurrentTextColor()));
|
||||
} else if (mHasSimpleBackground) {
|
||||
// final TintManager tintManager = TintManager.get(getContext());
|
||||
// ViewCompat.setBackgroundTintList(mEditText,
|
||||
// tintManager.getTintList(R.drawable.abc_edit_text_material));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error message that was set to be displayed with
|
||||
* {@link #setError(CharSequence)}, or <code>null</code> if no error was set
|
||||
* or if error displaying is not enabled.
|
||||
*
|
||||
* @see #setError(CharSequence)
|
||||
*/
|
||||
@Nullable
|
||||
public CharSequence getError() {
|
||||
if (mErrorEnabled && mErrorView != null && mErrorView.getVisibility() == VISIBLE) {
|
||||
return mErrorView.getText();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether any hint state changes, due to being focused or non-empty text, are
|
||||
* animated.
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#TextInputLayout_hintAnimationEnabled
|
||||
* @see #setHintAnimationEnabled(boolean)
|
||||
*/
|
||||
public boolean isHintAnimationEnabled() {
|
||||
return mHintAnimationEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether any hint state changes, due to being focused or non-empty text, are
|
||||
* animated.
|
||||
*
|
||||
* @attr ref android.support.design.R.styleable#TextInputLayout_hintAnimationEnabled
|
||||
* @see #isHintAnimationEnabled()
|
||||
*/
|
||||
public void setHintAnimationEnabled(boolean enabled) {
|
||||
mHintAnimationEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
super.draw(canvas);
|
||||
mCollapsingTextHelper.draw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
|
||||
if (mEditText != null) {
|
||||
final int l = mEditText.getLeft() + mEditText.getCompoundPaddingLeft();
|
||||
final int r = mEditText.getRight() - mEditText.getCompoundPaddingRight();
|
||||
|
||||
mCollapsingTextHelper.setExpandedBounds(l,
|
||||
mEditText.getTop() + mEditText.getCompoundPaddingTop(),
|
||||
r, mEditText.getBottom() - mEditText.getCompoundPaddingBottom());
|
||||
|
||||
// Set the collapsed bounds to be the the full height (minus padding) to match the
|
||||
// EditText's editable area
|
||||
mCollapsingTextHelper.setCollapsedBounds(l, getPaddingTop(),
|
||||
r, bottom - top - getPaddingBottom());
|
||||
|
||||
mCollapsingTextHelper.recalculate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshDrawableState() {
|
||||
super.refreshDrawableState();
|
||||
// Drawable state has changed so see if we need to update the label
|
||||
updateLabelVisibility(ViewCompat.isLaidOut(this));
|
||||
}
|
||||
|
||||
private void collapseHint(boolean animate) {
|
||||
if (mAnimator != null && mAnimator.isRunning()) {
|
||||
mAnimator.cancel();
|
||||
}
|
||||
if (animate && mHintAnimationEnabled) {
|
||||
animateToExpansionFraction(1f);
|
||||
} else {
|
||||
mCollapsingTextHelper.setExpansionFraction(1f);
|
||||
}
|
||||
}
|
||||
|
||||
private void expandHint(boolean animate) {
|
||||
if (mAnimator != null && mAnimator.isRunning()) {
|
||||
mAnimator.cancel();
|
||||
}
|
||||
if (animate && mHintAnimationEnabled) {
|
||||
animateToExpansionFraction(0f);
|
||||
} else {
|
||||
mCollapsingTextHelper.setExpansionFraction(0f);
|
||||
}
|
||||
}
|
||||
|
||||
private void animateToExpansionFraction(final float target) {
|
||||
if (mCollapsingTextHelper.getExpansionFraction() == target) {
|
||||
return;
|
||||
}
|
||||
if (mAnimator == null) {
|
||||
mAnimator = ViewUtils.createAnimator();
|
||||
mAnimator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR);
|
||||
mAnimator.setDuration(ANIMATION_DURATION);
|
||||
mAnimator.setUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimatorCompat animator) {
|
||||
mCollapsingTextHelper.setExpansionFraction(animator.getAnimatedFloatValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
mAnimator.setFloatValues(mCollapsingTextHelper.getExpansionFraction(), target);
|
||||
mAnimator.start();
|
||||
}
|
||||
|
||||
private int getThemeAttrColor(int attr) {
|
||||
TypedValue tv = new TypedValue();
|
||||
if (getContext().getTheme().resolveAttribute(attr, tv, true)) {
|
||||
return tv.data;
|
||||
} else {
|
||||
return Color.MAGENTA;
|
||||
}
|
||||
}
|
||||
|
||||
private class TextInputAccessibilityDelegate extends AccessibilityDelegateCompat {
|
||||
@Override
|
||||
public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
|
||||
super.onInitializeAccessibilityEvent(host, event);
|
||||
event.setClassName(TextInputLayout.class.getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
|
||||
super.onPopulateAccessibilityEvent(host, event);
|
||||
|
||||
final CharSequence text = mCollapsingTextHelper.getText();
|
||||
if (!TextUtils.isEmpty(text)) {
|
||||
event.getText().add(text);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
|
||||
super.onInitializeAccessibilityNodeInfo(host, info);
|
||||
info.setClassName(TextInputLayout.class.getSimpleName());
|
||||
|
||||
final CharSequence text = mCollapsingTextHelper.getText();
|
||||
if (!TextUtils.isEmpty(text)) {
|
||||
info.setText(text);
|
||||
}
|
||||
if (mEditText != null) {
|
||||
info.setLabelFor(mEditText);
|
||||
}
|
||||
final CharSequence error = mErrorView != null ? mErrorView.getText() : null;
|
||||
if (!TextUtils.isEmpty(error)) {
|
||||
info.setContentInvalid(true);
|
||||
info.setError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean arrayContains(int[] array, int value) {
|
||||
for (int v : array) {
|
||||
if (v == value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
93
src/main/java/com/shaya/poinila/android/NotificationService.java
Executable file
93
src/main/java/com/shaya/poinila/android/NotificationService.java
Executable file
@@ -0,0 +1,93 @@
|
||||
package com.shaya.poinila.android;
|
||||
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.onesignal.NotificationExtenderService;
|
||||
import com.onesignal.OSNotificationPayload;
|
||||
import com.shaya.poinila.android.util.Logger;
|
||||
import com.shaya.poinila.android.utils.NotificationQueue;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import data.model.Member;
|
||||
import data.model.Post;
|
||||
import manager.DBFacade;
|
||||
|
||||
import static com.shaya.poinila.android.utils.PushNotificationUtils.*;
|
||||
|
||||
/**
|
||||
* Created by iran on 6/7/2016.
|
||||
*/
|
||||
public class NotificationService extends NotificationExtenderService {
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean onNotificationProcessing(final OSNotificationPayload notification) {
|
||||
|
||||
Log.i(getClass().getName(), "additionalData : " + notification.additionalData);
|
||||
|
||||
OverrideSettings overrideSettings = new OverrideSettings();
|
||||
overrideSettings.extender = new NotificationCompat.Extender() {
|
||||
@Override
|
||||
public NotificationCompat.Builder extend(NotificationCompat.Builder builder) {
|
||||
|
||||
// String message = createNotificationMessage(notification.additionalData);
|
||||
|
||||
// builder.setStyle(new NotificationCompat.BigTextStyle().bigText(message));
|
||||
// builder.setContentText(message);
|
||||
// builder.setTicker(message);
|
||||
|
||||
NOTIFICATION_TYPE group = getNotificationType(notification.additionalData);
|
||||
JSONArray data = NotificationQueue.getInstance().get(group.toString().toLowerCase());
|
||||
|
||||
if(!group.equals(NOTIFICATION_TYPE.FRIENDSHIP_REQUEST)
|
||||
&& !group.equals(NOTIFICATION_TYPE.FRIENDSHIP_ANSWER)
|
||||
&& !group.equals(NOTIFICATION_TYPE.POST_SUGGESTION)){
|
||||
JSONObject jsonModel = notification.additionalData.optJSONObject("object");
|
||||
|
||||
Logger.log("push data additionalData = " + notification.additionalData, Logger.LEVEL_INFO);
|
||||
|
||||
|
||||
if(data == null)
|
||||
data = new JSONArray();
|
||||
try {
|
||||
JSONObject ownerJs = new JSONObject(new Gson().toJson(DBFacade.getCachedMyInfo(), Member.class));
|
||||
switch (group){
|
||||
case FOLLOW:
|
||||
JSONObject collectionJs = jsonModel.optJSONObject("collection");
|
||||
collectionJs.put("owner", ownerJs);
|
||||
data.put(collectionJs);
|
||||
break;
|
||||
default:
|
||||
JSONObject postJs = jsonModel.optJSONObject("post");
|
||||
postJs.put("poster", ownerJs);
|
||||
JSONObject collJs = jsonModel.optJSONObject("post_collection");
|
||||
postJs.put("collection", collJs);
|
||||
data.put(postJs);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
NotificationQueue.getInstance().put(group.toString().toLowerCase(), data);
|
||||
}
|
||||
|
||||
return builder;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
displayNotification(overrideSettings);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.shaya.poinila.android.authentication;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Created by iran on 5/30/2016.
|
||||
*/
|
||||
public class AuthenticationService extends Service {
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return new Authenticator(this).getIBinder();
|
||||
}
|
||||
}
|
||||
119
src/main/java/com/shaya/poinila/android/authentication/Authenticator.java
Executable file
119
src/main/java/com/shaya/poinila/android/authentication/Authenticator.java
Executable file
@@ -0,0 +1,119 @@
|
||||
package com.shaya.poinila.android.authentication;
|
||||
|
||||
import android.accounts.AbstractAccountAuthenticator;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountAuthenticatorResponse;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.NetworkErrorException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.shaya.poinila.android.presentation.view.activity.SignUpLoginActivity;
|
||||
|
||||
/**
|
||||
* Created by iran on 5/30/2016.
|
||||
*/
|
||||
public class Authenticator extends AbstractAccountAuthenticator {
|
||||
|
||||
Context mContext;
|
||||
|
||||
String TAG = this.getClass().getSimpleName();
|
||||
|
||||
public Authenticator(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle addAccount(AccountAuthenticatorResponse response,
|
||||
String accountType, String authTokenType,
|
||||
String[] requiredFeatures, Bundle options)
|
||||
throws NetworkErrorException {
|
||||
|
||||
final Intent intent = new Intent(mContext, SignUpLoginActivity.class);
|
||||
// intent.putExtra(AuthenticationActivity.ARG_ACCOUNT_TYPE, accountType);
|
||||
// intent.putExtra(AuthenticationActivity.ARG_AUTH_TYPE, authTokenType);
|
||||
// intent.putExtra(AuthenticationActivity.ARG_IS_ADDING_NEW_ACCOUNT, true);
|
||||
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
|
||||
|
||||
final Bundle bundle = new Bundle();
|
||||
|
||||
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Bundle getAuthToken(AccountAuthenticatorResponse response,
|
||||
Account account, String authTokenType, Bundle options)
|
||||
throws NetworkErrorException {
|
||||
|
||||
// Extract the username and password from the Account Manager
|
||||
final AccountManager am = AccountManager.get(mContext);
|
||||
String authToken = am.peekAuthToken(account, authTokenType);
|
||||
|
||||
// Let's give another try to authenticate the user
|
||||
if (TextUtils.isEmpty(authToken)) {
|
||||
final String password = am.getPassword(account);
|
||||
|
||||
if (password != null) {
|
||||
// authToken = ServerConnector.SignIn(account.name, password);
|
||||
}
|
||||
}
|
||||
else{
|
||||
final Bundle result = new Bundle();
|
||||
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
|
||||
result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
|
||||
result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
|
||||
return result;
|
||||
}
|
||||
|
||||
// If we get here, then we couldn't access the user's password - so we
|
||||
// need to re-prompt them for their credentials. We do that by creating
|
||||
// an intent to display our AuthenticatorActivity.
|
||||
final Intent intent = new Intent(mContext, SignUpLoginActivity.class);
|
||||
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
|
||||
// intent.putExtra(AuthenticationActivity.ARG_ACCOUNT_TYPE, account.type);
|
||||
// intent.putExtra(AuthenticationActivity.ARG_AUTH_TYPE, authTokenType);
|
||||
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthTokenLabel(String authTokenType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle hasFeatures(AccountAuthenticatorResponse response,
|
||||
Account account, String[] features) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle updateCredentials(AccountAuthenticatorResponse response,
|
||||
Account account, String authTokenType, Bundle options)
|
||||
throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Bundle confirmCredentials(AccountAuthenticatorResponse response,
|
||||
Account account, Bundle options) throws NetworkErrorException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle editProperties(AccountAuthenticatorResponse response,
|
||||
String accountType) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
1118
src/main/java/com/shaya/poinila/android/presentation/AndroidUtilities.java
Executable file
1118
src/main/java/com/shaya/poinila/android/presentation/AndroidUtilities.java
Executable file
File diff suppressed because it is too large
Load Diff
17
src/main/java/com/shaya/poinila/android/presentation/OneSignalReceiver.java
Executable file
17
src/main/java/com/shaya/poinila/android/presentation/OneSignalReceiver.java
Executable file
@@ -0,0 +1,17 @@
|
||||
package com.shaya.poinila.android.presentation;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* Created by iran on 6/11/2016.
|
||||
*/
|
||||
public class OneSignalReceiver extends BroadcastReceiver{
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// Log.i(getClass().getName(), "OneSignalReceiver");
|
||||
}
|
||||
}
|
||||
254
src/main/java/com/shaya/poinila/android/presentation/PageChanger.java
Executable file
254
src/main/java/com/shaya/poinila/android/presentation/PageChanger.java
Executable file
@@ -0,0 +1,254 @@
|
||||
package com.shaya.poinila.android.presentation;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.raizlabs.android.dbflow.annotation.NotNull;
|
||||
import com.shaya.poinila.android.presentation.view.activity.ChromeActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.CollectionListActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.CommentsListActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.FullImageActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.HelpActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.MainActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.MemberListActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.NewPostActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.NotificationOpenedActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.OthersProfileActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.PostListActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.SelectInterestActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.SignUpLoginActivity;
|
||||
import com.shaya.poinila.android.presentation.view.activity.WebviewActivity;
|
||||
import com.shaya.poinila.android.presentation.view.dialog.NewPostDialog;
|
||||
import com.shaya.poinila.android.util.ConstantsUtils;
|
||||
import com.shaya.poinila.android.util.Logger;
|
||||
import com.shaya.poinila.android.util.NavigationUtils;
|
||||
import com.shaya.poinila.android.utils.PushNotificationUtils;
|
||||
import com.shaya.poinila.android.utils.Utils;
|
||||
|
||||
import data.model.Collection;
|
||||
import data.model.Member;
|
||||
import data.model.Post;
|
||||
import data.model.SuggestedWebPagePost;
|
||||
import manager.DataRepository;
|
||||
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.KEY_CONTENT_URI;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.KEY_ENTITY;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.KEY_FIRST_LOGIN;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.KEY_ITEM_COUNT;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.KEY_MEMBER_ID;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.KEY_PAGE_TITLE_PARAMETER;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.KEY_POST_ID;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.KEY_REQUEST_ID;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.KEY_SECOND_ENTITY_ID;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.KEY_STARTED_FROM_SETTING;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.KEY_WEBSITE_URL;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.REQUEST_COLLECTION_POSTS;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.REQUEST_EXPLORE;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.REQUEST_MEMBER_POSTS;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.REQUEST_POST_LIKERS;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.REQUEST_POST_RELATED_POSTS;
|
||||
import static com.shaya.poinila.android.util.ConstantsUtils.REQUEST_POST_REPOSTING_COLLECTIONS;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-09-27.
|
||||
*/
|
||||
public class PageChanger {
|
||||
public static void goToProfile(Activity activity, Member member) {
|
||||
DataRepository.getInstance().putTempModel(member);
|
||||
NavigationUtils.goToActivity(OthersProfileActivity.class,
|
||||
activity, KEY_MEMBER_ID, member.getId());
|
||||
}
|
||||
|
||||
public static void goToProfile(Activity activity, String memberID) {
|
||||
DataRepository.getInstance().putTempModel(null);
|
||||
NavigationUtils.goToActivity(OthersProfileActivity.class,
|
||||
activity, KEY_MEMBER_ID, memberID);
|
||||
}
|
||||
|
||||
public static void goToCollection(Activity activity, Collection collection) {
|
||||
DataRepository.getInstance().putTempModel(collection);
|
||||
goToCollection(activity, collection.getId(), collection.name, null);
|
||||
}
|
||||
|
||||
public static void goToCollection(Activity activity, @Nullable String collectionId,
|
||||
@NotNull String collectionName, @Nullable String userName){
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_ENTITY, collectionId != null ? collectionId : collectionName);
|
||||
bundle.putInt(KEY_REQUEST_ID, REQUEST_COLLECTION_POSTS);
|
||||
bundle.putString(KEY_SECOND_ENTITY_ID, userName != null ? userName : collectionName);
|
||||
NavigationUtils.goToActivity(PostListActivity.class, activity, bundle);
|
||||
}
|
||||
|
||||
/*public static void goToCollectionByName(Activity activity, String collectionName, String userName){
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_Entity, collectionName);
|
||||
bundle.putInt(KEY_REQUEST_ID, REQUEST_COLLECTION_POSTS);
|
||||
bundle.putString(KEY_PAGE_TITLE_PARAMETER, collectionName);
|
||||
bundle.putString(KEY_SECOND_ENTITY_ID, userName);
|
||||
NavigationUtils.goToActivity(PostListActivity.class, activity, bundle);
|
||||
}*/
|
||||
|
||||
public static void goToPost(Activity activity, Post post) {
|
||||
DataRepository.getInstance().putTempModel(post);
|
||||
goToPost(activity, post.getId());
|
||||
}
|
||||
|
||||
public static void goToPost(Activity activity, String postID) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_ENTITY, postID);
|
||||
bundle.putInt(KEY_REQUEST_ID, REQUEST_POST_RELATED_POSTS);
|
||||
NavigationUtils.goToActivity(PostListActivity.class, activity, bundle);
|
||||
|
||||
/* BaseFragment fragment = PostListFragment.newInstance(postID, REQUEST_POST_RELATED_POSTS);
|
||||
if (activity instanceof FragmentHostActivity)
|
||||
((FragmentHostActivity) activity).addFragment(fragment, true);
|
||||
else {
|
||||
NavigationUtils.goToActivity(FragmentHostActivity.class, activity);
|
||||
DataRepository.getInstance().putTempModel(fragment);
|
||||
}*/
|
||||
}
|
||||
|
||||
public static void goToExplore(Activity activity, String tagText) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_ENTITY, tagText);
|
||||
bundle.putInt(KEY_REQUEST_ID, REQUEST_EXPLORE);
|
||||
NavigationUtils.goToActivity(PostListActivity.class, activity, bundle);
|
||||
}
|
||||
|
||||
public static void goToLikersList(Activity activity, int faveCount, String postID) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_ENTITY, postID);
|
||||
bundle.putInt(KEY_REQUEST_ID, REQUEST_POST_LIKERS);
|
||||
bundle.putInt(KEY_ITEM_COUNT, faveCount);
|
||||
NavigationUtils.goToActivity(MemberListActivity.class, activity, bundle);
|
||||
}
|
||||
|
||||
public static void goToCommentList(Activity activity, int commentCount, String postID) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_POST_ID, postID);
|
||||
bundle.putInt(KEY_ITEM_COUNT, commentCount);
|
||||
NavigationUtils.goToActivity(CommentsListActivity.class, activity, bundle);
|
||||
}
|
||||
|
||||
public static void goToRepostList(Activity activity, int repostCount, String postID) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_ENTITY, postID);
|
||||
bundle.putInt(KEY_REQUEST_ID, REQUEST_POST_REPOSTING_COLLECTIONS);
|
||||
bundle.putInt(KEY_ITEM_COUNT, repostCount);
|
||||
NavigationUtils.goToActivity(CollectionListActivity.class, activity, bundle);
|
||||
}
|
||||
|
||||
public static void gotToNotificationActivity(PushNotificationUtils.NOTIFICATION_TYPE type, String data) {
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
bundle.putString("type", type.toString());
|
||||
if(!TextUtils.isEmpty(data))
|
||||
bundle.putString("data", data);
|
||||
|
||||
Logger.log("push data = " + data, Logger.LEVEL_INFO);
|
||||
|
||||
NavigationUtils.goToActivity(NotificationOpenedActivity.class, PoinilaApplication.getAppContext(), bundle, Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
|
||||
public static void goToMemberPosts(Activity activity, String memberID, String memberName) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(KEY_ENTITY, memberID);
|
||||
bundle.putInt(KEY_REQUEST_ID, REQUEST_MEMBER_POSTS);
|
||||
bundle.putString(KEY_SECOND_ENTITY_ID, memberName);
|
||||
NavigationUtils.goToActivity(PostListActivity.class, activity, bundle);
|
||||
}
|
||||
|
||||
public static void goToHelpActivity(Activity activity, boolean startedFromSetting) {
|
||||
Intent intent = NavigationUtils.makeNavigationIntent(HelpActivity.class, activity);
|
||||
intent.putExtra(KEY_STARTED_FROM_SETTING, startedFromSetting);
|
||||
if (!startedFromSetting)
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
|
||||
public static void goToLoginActivity(Activity activity) {
|
||||
goToLoginActivity(activity, null);
|
||||
}
|
||||
|
||||
public static void goToLoginActivity(Activity activity, Uri shareUri) {
|
||||
Intent intent = NavigationUtils.makeNavigationIntent(SignUpLoginActivity.class, activity);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
if (shareUri != null)
|
||||
intent.setData(shareUri);
|
||||
activity.finish();
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
|
||||
public static void goToInlineBrowser(Activity activity, String url, @NotNull String postId, String pageTitle) {
|
||||
Bundle bundle = new Bundle();
|
||||
if (!TextUtils.isEmpty(pageTitle))
|
||||
bundle.putString(KEY_PAGE_TITLE_PARAMETER, pageTitle);
|
||||
|
||||
if(!TextUtils.isEmpty(postId))
|
||||
bundle.putString(KEY_ENTITY, postId);
|
||||
|
||||
bundle.putString(KEY_WEBSITE_URL, url);
|
||||
if(Utils.getBrowserAvailablePackageName() == null){
|
||||
NavigationUtils.goToActivity(WebviewActivity.class, activity, bundle);
|
||||
}else {
|
||||
if(!TextUtils.isEmpty(postId))
|
||||
bundle.putString("referrer", getPostUrl(postId));
|
||||
NavigationUtils.goToActivity(ChromeActivity.class, activity, bundle);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getPostUrl(String postId){
|
||||
return ConstantsUtils.POINILA_SERVER_ADDRESS.concat("post/" + postId + "/");
|
||||
}
|
||||
|
||||
//TODO problem in showing full screen dialogs
|
||||
public static void goToNewPost(android.support.v4.app.FragmentManager fragmentManager, SuggestedWebPagePost webpagePost) {
|
||||
/*Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(ConstantsUtils.KEY_WEBPAGE_POST, webpagePost == null ? null : Parcels.wrap(webpagePost));
|
||||
NavigationUtils.goToActivity(NewPostActivity.class, activity, bundle);*/
|
||||
NewPostDialog.newInstance(webpagePost).show(fragmentManager, null);
|
||||
}
|
||||
|
||||
//TODO problem in showing full screen dialogs
|
||||
public static void goToNewWebSitePost(Context context, SuggestedWebPagePost webpagePost) {
|
||||
Bundle bundle = new Bundle();
|
||||
NavigationUtils.goToActivity(NewPostActivity.class, context, bundle);
|
||||
}
|
||||
|
||||
public static void goToSelectInterest(Activity activity, boolean firstLogin) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(KEY_FIRST_LOGIN, firstLogin);
|
||||
NavigationUtils.goToActivity(SelectInterestActivity.class, activity, bundle);
|
||||
}
|
||||
|
||||
public static void goToSelectInterest(Context context, boolean firstLogin) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(KEY_FIRST_LOGIN, firstLogin);
|
||||
NavigationUtils.goToActivity(SelectInterestActivity.class, context, bundle);
|
||||
}
|
||||
|
||||
public static void goToDashboard(Activity activity) {
|
||||
Intent intent = NavigationUtils.makeNavigationIntent(MainActivity.class, activity);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
activity.startActivity(intent);
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
public static void goToDashboard(Context context) {
|
||||
Intent intent = NavigationUtils.makeNavigationIntent(MainActivity.class, context);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public static void goToFullImage(Activity activity, String imageAddress) {
|
||||
Intent intent = NavigationUtils.makeNavigationIntent(FullImageActivity.class, activity);
|
||||
intent.putExtra(KEY_CONTENT_URI, imageAddress);
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
|
||||
}
|
||||
158
src/main/java/com/shaya/poinila/android/presentation/PoinilaApplication.java
Executable file
158
src/main/java/com/shaya/poinila/android/presentation/PoinilaApplication.java
Executable file
@@ -0,0 +1,158 @@
|
||||
package com.shaya.poinila.android.presentation;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.google.android.gms.analytics.GoogleAnalytics;
|
||||
import com.google.android.gms.analytics.Tracker;
|
||||
import com.onesignal.OneSignal;
|
||||
import com.raizlabs.android.dbflow.config.FlowConfig;
|
||||
import com.raizlabs.android.dbflow.config.FlowManager;
|
||||
import com.shaya.poinila.android.util.ConstantsUtils;
|
||||
import com.shaya.poinila.android.util.ContextHolder;
|
||||
import com.shaya.poinila.android.util.DeviceInfoUtils;
|
||||
import com.shaya.poinila.android.presentation.notification.OneSignalNotificationOpenedHelper;
|
||||
|
||||
import io.fabric.sdk.android.Fabric;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import data.PoinilaNetService;
|
||||
import data.model.Member;
|
||||
import manager.DBFacade;
|
||||
import manager.DataRepository;
|
||||
import uk.co.chrisjenx.calligraphy.CalligraphyConfig;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-06-03.
|
||||
*
|
||||
* @author Alireza Farahani
|
||||
*/
|
||||
public class PoinilaApplication extends Application {
|
||||
|
||||
//private RefWatcher refWatcher;
|
||||
|
||||
private static Context mContext;
|
||||
|
||||
private static String authToken;
|
||||
|
||||
private Tracker mTracker;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
final Fabric fabric = new Fabric.Builder(this)
|
||||
.kits(new Crashlytics())
|
||||
.debuggable(true)
|
||||
.build();
|
||||
Fabric.with(fabric);
|
||||
ContextHolder.setContext(getApplicationContext());
|
||||
FlowManager.init(new FlowConfig.Builder(this).build()); //refWatcher = LeakCanary.install(this);
|
||||
setLocale();
|
||||
//TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/BYekan.ttf");
|
||||
//TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/iransans.ttf");
|
||||
//TypefaceUtil.overrideFont(getApplicationContext(), "SERIF-LIGHT", "fonts/IRANSansLight.ttf");
|
||||
//TypefaceUtil.overrideFont(getApplicationContext(), "SERIF-BOLD", "fonts/IRANSansBold.ttf");
|
||||
CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
|
||||
.setDefaultFontPath(getString(R.string.default_font_path))
|
||||
.setFontAttrId(R.attr.fontPath)
|
||||
.build());
|
||||
//OneSignal.startInit(this).init();
|
||||
//setupCrashReport();
|
||||
|
||||
mContext = this;
|
||||
|
||||
OneSignal
|
||||
.startInit(this)
|
||||
.setNotificationOpenedHandler(new OneSignalNotificationOpenedHelper(this))
|
||||
// .setAutoPromptLocation(true)
|
||||
|
||||
.init();
|
||||
|
||||
OneSignal.enableInAppAlertNotification(false);
|
||||
|
||||
|
||||
OneSignal.getTags(new OneSignal.GetTagsHandler() {
|
||||
@Override
|
||||
public void tagsAvailable(JSONObject tags) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void logUser() {
|
||||
// You can call any combination of these three methods
|
||||
Member user = DBFacade.getCachedMyInfo();
|
||||
if(user != null){
|
||||
Crashlytics.setUserIdentifier(user.getId());
|
||||
// if(!TextUtils.isEmpty(user.email)) Crashlytics.setUserEmail(user.email);
|
||||
Crashlytics.setUserName(user.uniqueName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default {@link Tracker} for this {@link Application}.
|
||||
* @return tracker
|
||||
*/
|
||||
synchronized public Tracker getDefaultTracker() {
|
||||
if (mTracker == null) {
|
||||
GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
|
||||
mTracker = analytics.newTracker(ConstantsUtils.GOOGLE_ANALYTICS_TRACKING_ID);
|
||||
mTracker.enableAutoActivityTracking(true);
|
||||
mTracker.setAppVersion(DeviceInfoUtils.CLIENT_VERSION_NAME);
|
||||
}
|
||||
return mTracker;
|
||||
}
|
||||
|
||||
|
||||
public static Context getAppContext(){
|
||||
return mContext;
|
||||
}
|
||||
|
||||
public static String getAuthToken(){
|
||||
return authToken;
|
||||
}
|
||||
|
||||
private void setupCrashReport() {
|
||||
// Setup handler for uncaught exceptions.
|
||||
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||
@Override
|
||||
public void uncaughtException(Thread thread, Throwable e) {
|
||||
handleUncaughtException(thread, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handleUncaughtException(Thread thread, Throwable e) {
|
||||
PoinilaNetService.sendReport(ConstantsUtils.REPORT_TYPE_BUG, e.getClass().getSimpleName(), Log.getStackTraceString(e));
|
||||
throw new RuntimeException("");
|
||||
/*android.os.Process.killProcess(android.os.Process.myPid());
|
||||
System.exit(1); // crash with "unfortunately stopped blah blah*/
|
||||
|
||||
}
|
||||
|
||||
/* public static RefWatcher getRefWatcher(Context context) {
|
||||
PoinilaApplication application = (PoinilaApplication) context.getApplicationContext();
|
||||
return application.refWatcher;
|
||||
}*/
|
||||
public void setLocale() {
|
||||
Locale myLocale = new Locale("fa");
|
||||
Resources res = getResources();
|
||||
DisplayMetrics dm = res.getDisplayMetrics();
|
||||
Configuration conf = res.getConfiguration();
|
||||
conf.locale = myLocale;
|
||||
res.updateConfiguration(conf, dm);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
77
src/main/java/com/shaya/poinila/android/presentation/SmsReceiver.java
Executable file
77
src/main/java/com/shaya/poinila/android/presentation/SmsReceiver.java
Executable file
@@ -0,0 +1,77 @@
|
||||
package com.shaya.poinila.android.presentation;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.telephony.SmsManager;
|
||||
import android.telephony.SmsMessage;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.shaya.poinila.android.presentation.uievent.SmsReceivedEvent;
|
||||
import com.shaya.poinila.android.util.BusProvider;
|
||||
import com.shaya.poinila.android.util.Logger;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import manager.DataRepository;
|
||||
|
||||
/**
|
||||
* Created by iran on 12/8/2015.
|
||||
*/
|
||||
public class SmsReceiver extends BroadcastReceiver {
|
||||
final SmsManager sms = SmsManager.getDefault();
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Logger.toast("Sms Received");
|
||||
}
|
||||
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
|
||||
|
||||
Bundle bundle = intent.getExtras();
|
||||
SmsMessage[] msgs;
|
||||
if (bundle != null) {
|
||||
try {
|
||||
Object[] pdus = (Object[]) bundle.get("pdus");
|
||||
msgs = new SmsMessage[pdus.length];
|
||||
String wholeString = "";
|
||||
for (int i = 0; i < msgs.length; i++) {
|
||||
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
|
||||
if(isPonilaNumber(msgs[i].getOriginatingAddress())){
|
||||
wholeString += msgs[i].getMessageBody();
|
||||
}
|
||||
}
|
||||
|
||||
if(!TextUtils.isEmpty(wholeString)){
|
||||
// Log.i(getClass().getName(), "wholeString = " + wholeString);
|
||||
Pattern pattern = Pattern.compile("[0-9]+");
|
||||
final Matcher matcher = pattern.matcher(wholeString);
|
||||
if (matcher.find()) {
|
||||
// Log.i(getClass().getName(), "matcher.group(0) = " + matcher.group(0));
|
||||
String str = matcher.group(0);
|
||||
if (str.length() >= 3) {
|
||||
BusProvider.getBus().post(new SmsReceivedEvent(str));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPonilaNumber(String address){
|
||||
List<String> numbers = DataRepository.getSMSProviderNumbers();
|
||||
for(String number : numbers){
|
||||
if(number.contains(address))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
36
src/main/java/com/shaya/poinila/android/presentation/SortUtils.java
Executable file
36
src/main/java/com/shaya/poinila/android/presentation/SortUtils.java
Executable file
@@ -0,0 +1,36 @@
|
||||
package com.shaya.poinila.android.presentation;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import data.model.Timed;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-07.
|
||||
*/
|
||||
public class SortUtils {
|
||||
private static Comparator timeComparator = new Comparator() {
|
||||
@Override
|
||||
public int compare(Object left, Object right) {
|
||||
if (!(left instanceof Timed) || !(right instanceof Timed))
|
||||
throw new RuntimeException("objects must implement Timed interface");
|
||||
Timed lhs = (Timed) left;
|
||||
Timed rhs = (Timed) right;
|
||||
if (lhs == rhs)
|
||||
return 0;
|
||||
// newer item in less index
|
||||
if (lhs.getCreationTime() > rhs.getCreationTime())
|
||||
return -1;
|
||||
// older item in greate index
|
||||
if (lhs.getCreationTime() < rhs.getCreationTime())
|
||||
return 1;
|
||||
// same time
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
public static void sortByTime(List list){
|
||||
Collections.sort(list, timeComparator);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.shaya.poinila.android.presentation.notification;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.onesignal.OneSignal;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import data.PoinilaNetService;
|
||||
import data.model.FriendRequestAnswer;
|
||||
|
||||
import static com.shaya.poinila.android.utils.PushNotificationUtils.*;
|
||||
|
||||
/**
|
||||
* Created by iran on 6/8/2016.
|
||||
*/
|
||||
public class OneSignalNotificationOpenedHelper implements OneSignal.NotificationOpenedHandler {
|
||||
|
||||
|
||||
Context context;
|
||||
|
||||
public OneSignalNotificationOpenedHelper(Context context){
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notificationOpened(String message, JSONObject additionalData, boolean isActive) {
|
||||
|
||||
Log.i(getClass().getName(), "additionalData = " + additionalData);
|
||||
Log.i(getClass().getName(), "message = " + message);
|
||||
Log.i(getClass().getName(), "isActive = " + isActive);
|
||||
|
||||
JSONArray notifArray = additionalData.optJSONArray("stacked_notifications");
|
||||
JSONObject objJS = null;
|
||||
if(notifArray != null){
|
||||
try {
|
||||
objJS = notifArray.length()> 0 ? notifArray.getJSONObject(0) : null;
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
fireNotificationAction(objJS == null ? additionalData: objJS);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.shaya.poinila.android.presentation.presenter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import com.shaya.poinila.android.presentation.R;
|
||||
import com.shaya.poinila.android.presentation.viewholder.BaseViewHolder;
|
||||
import com.shaya.poinila.android.presentation.viewholder.CollectionNotifViewHolder;
|
||||
import com.shaya.poinila.android.presentation.viewholder.MemberNotifViewHolder;
|
||||
import com.shaya.poinila.android.presentation.viewholder.PostNotifViewHolder;
|
||||
|
||||
import data.model.ImageUrls;
|
||||
import data.model.Notification;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-15.
|
||||
*/
|
||||
public class NotificationAdapter extends RecyclerViewAdapter<Notification, BaseViewHolder<Notification>>{
|
||||
|
||||
//public static final int DATE_HEADER = 0;
|
||||
public static final int INVITE_NOTIF = 1;
|
||||
public static final int FRIENDSHIP_ACCEPTED_NOTIF = 2;
|
||||
public static final int COMMENT_AFTER_YOUR_COMMENT = 3;
|
||||
public static final int COMMENT_MY_POST = 4;
|
||||
public static final int FRIENDS_CREATED_COLLECTIONS = 5;
|
||||
public static final int FRIENDS_FOLLOWED_COLLECTIONS = 6;
|
||||
public static final int FRIENDS_LIKED_POSTS = 7;
|
||||
public static final int MY_COLLECTION_FOLLOWED = 8;
|
||||
public static final int MY_POST_REPOSTED = 9;
|
||||
public static final int MY_POST_LIKED = 10;
|
||||
|
||||
public NotificationAdapter(Context context){
|
||||
super(context, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseViewHolder<Notification> onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
switch (viewType){
|
||||
/*case DATE_HEADER:
|
||||
return new DateHeaderViewHolder(mLayoutInflater.inflate(R.layout.title_date_separator, parent, false));*/
|
||||
case MY_POST_LIKED:
|
||||
case COMMENT_AFTER_YOUR_COMMENT:
|
||||
case COMMENT_MY_POST:
|
||||
case MY_POST_REPOSTED:
|
||||
return new PostNotifViewHolder(mLayoutInflater.inflate(R.layout.notif_post, parent, false));
|
||||
case MY_COLLECTION_FOLLOWED:
|
||||
return new CollectionNotifViewHolder(mLayoutInflater.inflate(R.layout.notif_collection, parent, false));
|
||||
case FRIENDS_LIKED_POSTS:
|
||||
return new MemberNotifViewHolder(mLayoutInflater.inflate(R.layout.notif_member, parent, false), ImageUrls.ImageType.POST);
|
||||
case FRIENDS_CREATED_COLLECTIONS:
|
||||
case FRIENDS_FOLLOWED_COLLECTIONS:
|
||||
return new MemberNotifViewHolder(mLayoutInflater.inflate(R.layout.notif_member, parent, false), ImageUrls.ImageType.COLLECTION);
|
||||
case FRIENDSHIP_ACCEPTED_NOTIF:
|
||||
return new MemberNotifViewHolder(mLayoutInflater.inflate(R.layout.notif_member, parent, false), ImageUrls.ImageType.MEMBER);
|
||||
case VIEW_TYPE_LOAD_PROGRESS:
|
||||
return new BaseViewHolder.EmptyViewHolder(mLayoutInflater.inflate(R.layout.progress, parent, false));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BaseViewHolder<Notification> getProperViewHolder(View v, int viewType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
/* else if (items.get(position) instanceof AcceptNotif){
|
||||
return FRIENDSHIP_ACCEPTED_NOTIF;
|
||||
}*/
|
||||
/* else if (items.get(position) instanceof DateHeader) {
|
||||
return DATE_HEADER;
|
||||
}*/
|
||||
|
||||
int type = super.getItemViewType(position);
|
||||
if(type == VIEW_TYPE_LOAD_PROGRESS){
|
||||
return super.getItemViewType(position);
|
||||
}
|
||||
|
||||
switch (getItem(position).type){
|
||||
case MY_POST_LIKED:
|
||||
return MY_POST_LIKED;
|
||||
case COMMENT_AFTER_YOUR_COMMENT:
|
||||
return COMMENT_AFTER_YOUR_COMMENT;
|
||||
case COMMENT_MY_POST:
|
||||
return COMMENT_MY_POST;
|
||||
case FRIENDS_CREATED_COLLECTIONS:
|
||||
return FRIENDS_CREATED_COLLECTIONS;
|
||||
case FRIENDS_FOLLOWED_COLLECTIONS:
|
||||
return FRIENDS_FOLLOWED_COLLECTIONS;
|
||||
case FRIENDS_LIKED_POSTS:
|
||||
return FRIENDS_LIKED_POSTS;
|
||||
case MY_COLLECTION_FOLLOWED:
|
||||
return MY_COLLECTION_FOLLOWED;
|
||||
case MY_POST_REPOSTED:
|
||||
return MY_POST_REPOSTED;
|
||||
case FRIENDSHIP_ACCEPTED:
|
||||
return FRIENDSHIP_ACCEPTED_NOTIF;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
package com.shaya.poinila.android.presentation.presenter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.StaggeredGridLayoutManager;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import com.shaya.poinila.android.presentation.R;
|
||||
import com.shaya.poinila.android.presentation.viewholder.BaseViewHolder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import data.database.PoinilaDataBase;
|
||||
import data.model.Identifiable;
|
||||
import data.model.Loading;
|
||||
import data.model.Post;
|
||||
|
||||
public abstract class RecyclerViewAdapter<T, VH extends BaseViewHolder<T>> extends RecyclerView.Adapter<VH> {
|
||||
|
||||
public static final int VIEW_TYPE_LOAD_PROGRESS = -1;
|
||||
protected static final int VIEW_TYPE_DATA_ROW = 100;
|
||||
//private final Class<VH> mViewHolderClazz;loading
|
||||
protected LayoutInflater mLayoutInflater;
|
||||
private List<T> items;
|
||||
private int mItemLayoutID = -1;
|
||||
|
||||
// Provide a reference to the views for each items item
|
||||
// Complex items items may need more than one view per item, and
|
||||
// you provide access to all the views for a items item in a view holder
|
||||
//public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
// each items item is just a string in this case
|
||||
|
||||
// Provide a suitable constructor (depends on the kind of dataset)
|
||||
|
||||
public RecyclerViewAdapter(Context context, @LayoutRes int itemLayoutID) {
|
||||
super();
|
||||
Log.i(getClass().getName(), "context = " + context);
|
||||
mLayoutInflater = LayoutInflater.from(context);
|
||||
items = new ArrayList<>();
|
||||
mItemLayoutID = itemLayoutID;
|
||||
}
|
||||
|
||||
|
||||
// Create new views (invoked by the layout manager)
|
||||
@Override
|
||||
public VH onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
|
||||
|
||||
if(viewType == VIEW_TYPE_LOAD_PROGRESS){
|
||||
View v = mLayoutInflater.inflate(R.layout.progress, parent, false);
|
||||
return getProperViewHolder(v, viewType);
|
||||
}
|
||||
|
||||
View v = mLayoutInflater.inflate(mItemLayoutID, parent, false);
|
||||
return getProperViewHolder(v, viewType);
|
||||
}
|
||||
|
||||
protected abstract VH getProperViewHolder(View v, int viewType);
|
||||
|
||||
protected boolean isStaggeredGridLayoutManager(){
|
||||
return false;
|
||||
}
|
||||
|
||||
// Replace the contents of a view (invoked by the layout manager)
|
||||
@Override
|
||||
public void onBindViewHolder(VH holder, int position) {
|
||||
|
||||
if (!(getItemViewType(position) == VIEW_TYPE_LOAD_PROGRESS)) {
|
||||
holder.fill(getItem(position));
|
||||
}
|
||||
|
||||
if(isStaggeredGridLayoutManager() && getItemViewType(position) == VIEW_TYPE_LOAD_PROGRESS){
|
||||
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
|
||||
layoutParams.setFullSpan(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Return the size of your dataset (invoked by the layout manager)
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
//if (getItem(position) instanceof Identifiable)
|
||||
if (hasStableIds())
|
||||
return Integer.parseInt(((Identifiable) getItem(position)).getId());
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
public T getItem(int position){
|
||||
return items.get(position);
|
||||
}
|
||||
|
||||
public void addItem(T item, int position){
|
||||
if (item == null)
|
||||
return;
|
||||
items.add(position, item);
|
||||
notifyItemInserted(position);
|
||||
}
|
||||
|
||||
public void addItem(T item){
|
||||
if (item == null)
|
||||
return;
|
||||
items.add(item);
|
||||
|
||||
notifyItemInserted(items.size() - 1);
|
||||
}
|
||||
|
||||
public void setLoading(T item){
|
||||
if (item == null)
|
||||
return;
|
||||
items.add(item);
|
||||
notifyItemInserted(items.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
public void removeLoading(){
|
||||
int position = items.size() - 1;
|
||||
removeItem(position);
|
||||
notifyItemRemoved(position);
|
||||
}
|
||||
|
||||
public void addItems(List data){
|
||||
int oldSize = items.size();
|
||||
items.addAll(oldSize > 0 ? oldSize - 1 : oldSize, data);
|
||||
// items.addAll(data);
|
||||
notifyItemRangeInserted(oldSize, data.size());
|
||||
// TODO: moshkele inconsistency az ine guya
|
||||
//notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void addItemsToListHead(List<T> data){
|
||||
items.addAll(0, data);
|
||||
notifyItemRangeInserted(0, data.size());
|
||||
}
|
||||
|
||||
public void setItem(T item, int position){
|
||||
items.set(position, item);
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void resetData(List data) {
|
||||
// don't use this.items = data snippet. it produces bug in saving suggestions came from server
|
||||
this.items.clear();
|
||||
this.items.addAll(data);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void removeItem(int position){
|
||||
items.remove(position);
|
||||
notifyItemRemoved(position);
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
this.items.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (items.get(position) instanceof Loading)
|
||||
return VIEW_TYPE_LOAD_PROGRESS;
|
||||
return VIEW_TYPE_DATA_ROW;
|
||||
}
|
||||
|
||||
public List getItems(){
|
||||
return items;
|
||||
}
|
||||
|
||||
// Don't use it except you have no other choice! I assumed that lists have a single type entity in my design
|
||||
// But in Dashboard page there's times we want to show a "please rate us" item which is not a post.
|
||||
// 1- I could just add a fake post but it was not clean and triggered unwanted click events and blah blah
|
||||
// 2- Replacing current mechanism with new one. It messed the code and produced lots of cast to Post
|
||||
// 3- Ignoring generics and use the old api but in adding items to adapter I face the generic problem so I decided to just write a function without generic so be able to add anything other than post.
|
||||
// sorry for long comment, here's your potato :))
|
||||
public List getUngenericedItems(){
|
||||
return items;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return items.isEmpty() || (items.size() > 0 && items.get(0) instanceof Loading);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.shaya.poinila.android.presentation.presenter;
|
||||
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.StaggeredGridLayoutManager;
|
||||
|
||||
import com.shaya.poinila.android.presentation.view.LoaderList;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-06-23.
|
||||
* @author Alireza Farahani
|
||||
*/
|
||||
public class RecyclerViewProvider {
|
||||
private RecyclerView.LayoutManager mLayoutManager;
|
||||
private RecyclerView mRecyclerView;
|
||||
private RecyclerViewAdapter mAdapter;
|
||||
|
||||
public RecyclerViewProvider(RecyclerView recyclerView){
|
||||
mRecyclerView = recyclerView;
|
||||
}
|
||||
|
||||
/*public RecyclerViewProvider setRecyclerView(RecyclerView recyclerView){
|
||||
mRecyclerView = recyclerView;
|
||||
return this;
|
||||
}*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param direction use constans from {@link StaggeredGridLayoutManager}
|
||||
* @param columnCount get value from xml resources
|
||||
*/
|
||||
public RecyclerViewProvider setStaggeredLayoutManager(int direction, int columnCount){
|
||||
mLayoutManager = new StaggeredGridLayoutManager(columnCount, direction);
|
||||
//((StaggeredGridLayoutManager) mLayoutManager).setGapStrategy(GAP_HANDLING_NONE);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param direction use constans from {@link GridLayoutManager}
|
||||
* @param columnCount get value from xml resources
|
||||
* @return
|
||||
*/
|
||||
public RecyclerViewProvider setGridLayoutManager(int direction, int columnCount) {
|
||||
mLayoutManager = new GridLayoutManager(null, columnCount, direction, false);
|
||||
// mRecyclerView.setHasFixedSize(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerViewProvider setGridLayoutManager(
|
||||
int direction, int columnCount, GridLayoutManager.SpanSizeLookup spanSizeLookup) {
|
||||
((GridLayoutManager)setGridLayoutManager(direction, columnCount).mLayoutManager)
|
||||
.setSpanSizeLookup(spanSizeLookup);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param direction use constants from (@link LinearLayoutManager}
|
||||
* @return
|
||||
*/
|
||||
public RecyclerViewProvider setLinearLayoutManager(int direction){
|
||||
return setLinearLayoutManager(direction, false);
|
||||
}
|
||||
|
||||
public RecyclerViewProvider setLinearLayoutManager(int direction, boolean reverse) {
|
||||
mLayoutManager = new LinearLayoutManager(null, direction, reverse);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerViewProvider setAdapter(RecyclerViewAdapter adapter){
|
||||
mAdapter = adapter;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets layoutmanager and adapter for already given recyclerview and then returns it
|
||||
* @return
|
||||
*/
|
||||
public RecyclerView bindViewToAdapter() {
|
||||
if (mRecyclerView != null) {
|
||||
mRecyclerView.setLayoutManager(mLayoutManager);
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
return mRecyclerView;
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
|
||||
public static RecyclerView.OnScrollListener linearListEndDetectorListener(final RecyclerView.Adapter adapter, final LoaderList list) {
|
||||
return new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
boolean endOfList = ((LinearLayoutManager)recyclerView.getLayoutManager()).findLastVisibleItemPosition() ==
|
||||
adapter.getItemCount() - 1;
|
||||
if (endOfList && dy != 0){
|
||||
list.onLoadMore();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static RecyclerView.OnScrollListener staggeredListEndDetectorListener(final RecyclerView.Adapter adapter, final LoaderList list){
|
||||
return new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
int[] lastVisibleItems = ((StaggeredGridLayoutManager)recyclerView.getLayoutManager()).
|
||||
findLastVisibleItemPositions(null);
|
||||
int itemCount = adapter.getItemCount() - 1;
|
||||
if ((lastVisibleItems[0] == itemCount ||
|
||||
lastVisibleItems[1] == itemCount) && dy != 0){
|
||||
list.onLoadMore();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static RecyclerView.OnScrollListener gridListEndDetectionListener(final RecyclerView.Adapter adapter, final LoaderList list){
|
||||
return new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
boolean endOfList = ((GridLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition() ==
|
||||
adapter.getItemCount() - 1;
|
||||
if (endOfList && dy != 0) {
|
||||
list.onLoadMore();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
package com.shaya.poinila.android.presentation.svgandroid;
|
||||
|
||||
/*
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
/**
|
||||
* Parses numbers from SVG text. Based on the Batik Number Parser (Apache 2 License).
|
||||
*
|
||||
* @author Apache Software Foundation, Larva Labs LLC
|
||||
*/
|
||||
public class ParserHelper {
|
||||
|
||||
private char current;
|
||||
private CharSequence s;
|
||||
public int pos;
|
||||
private int n;
|
||||
|
||||
public ParserHelper(CharSequence s, int pos) {
|
||||
this.s = s;
|
||||
this.pos = pos;
|
||||
n = s.length();
|
||||
current = s.charAt(pos);
|
||||
}
|
||||
|
||||
private char read() {
|
||||
if (pos < n) {
|
||||
pos++;
|
||||
}
|
||||
if (pos == n) {
|
||||
return '\0';
|
||||
} else {
|
||||
return s.charAt(pos);
|
||||
}
|
||||
}
|
||||
|
||||
public void skipWhitespace() {
|
||||
while (pos < n) {
|
||||
if (Character.isWhitespace(s.charAt(pos))) {
|
||||
advance();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void skipNumberSeparator() {
|
||||
while (pos < n) {
|
||||
char c = s.charAt(pos);
|
||||
switch (c) {
|
||||
case ' ':
|
||||
case ',':
|
||||
case '\n':
|
||||
case '\t':
|
||||
advance();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void advance() {
|
||||
current = read();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the content of the buffer and converts it to a float.
|
||||
*/
|
||||
public float parseFloat() {
|
||||
int mant = 0;
|
||||
int mantDig = 0;
|
||||
boolean mantPos = true;
|
||||
boolean mantRead = false;
|
||||
|
||||
int exp = 0;
|
||||
int expDig = 0;
|
||||
int expAdj = 0;
|
||||
boolean expPos = true;
|
||||
|
||||
switch (current) {
|
||||
case '-':
|
||||
mantPos = false;
|
||||
// fallthrough
|
||||
case '+':
|
||||
current = read();
|
||||
}
|
||||
|
||||
m1: switch (current) {
|
||||
default:
|
||||
return Float.NaN;
|
||||
|
||||
case '.':
|
||||
break;
|
||||
|
||||
case '0':
|
||||
mantRead = true;
|
||||
l: for (;;) {
|
||||
current = read();
|
||||
switch (current) {
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
break l;
|
||||
case '.': case 'e': case 'E':
|
||||
break m1;
|
||||
default:
|
||||
return 0.0f;
|
||||
case '0':
|
||||
}
|
||||
}
|
||||
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
mantRead = true;
|
||||
l: for (;;) {
|
||||
if (mantDig < 9) {
|
||||
mantDig++;
|
||||
mant = mant * 10 + (current - '0');
|
||||
} else {
|
||||
expAdj++;
|
||||
}
|
||||
current = read();
|
||||
switch (current) {
|
||||
default:
|
||||
break l;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (current == '.') {
|
||||
current = read();
|
||||
m2: switch (current) {
|
||||
default:
|
||||
case 'e': case 'E':
|
||||
if (!mantRead) {
|
||||
reportUnexpectedCharacterError( current );
|
||||
return 0.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case '0':
|
||||
if (mantDig == 0) {
|
||||
l: for (;;) {
|
||||
current = read();
|
||||
expAdj--;
|
||||
switch (current) {
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
break l;
|
||||
default:
|
||||
if (!mantRead) {
|
||||
return 0.0f;
|
||||
}
|
||||
break m2;
|
||||
case '0':
|
||||
}
|
||||
}
|
||||
}
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
l: for (;;) {
|
||||
if (mantDig < 9) {
|
||||
mantDig++;
|
||||
mant = mant * 10 + (current - '0');
|
||||
expAdj--;
|
||||
}
|
||||
current = read();
|
||||
switch (current) {
|
||||
default:
|
||||
break l;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (current) {
|
||||
case 'e': case 'E':
|
||||
current = read();
|
||||
switch (current) {
|
||||
default:
|
||||
reportUnexpectedCharacterError( current );
|
||||
return 0f;
|
||||
case '-':
|
||||
expPos = false;
|
||||
case '+':
|
||||
current = read();
|
||||
switch (current) {
|
||||
default:
|
||||
reportUnexpectedCharacterError( current );
|
||||
return 0f;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
}
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
}
|
||||
|
||||
en: switch (current) {
|
||||
case '0':
|
||||
l: for (;;) {
|
||||
current = read();
|
||||
switch (current) {
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
break l;
|
||||
default:
|
||||
break en;
|
||||
case '0':
|
||||
}
|
||||
}
|
||||
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
l: for (;;) {
|
||||
if (expDig < 3) {
|
||||
expDig++;
|
||||
exp = exp * 10 + (current - '0');
|
||||
}
|
||||
current = read();
|
||||
switch (current) {
|
||||
default:
|
||||
break l;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
}
|
||||
|
||||
if (!expPos) {
|
||||
exp = -exp;
|
||||
}
|
||||
exp += expAdj;
|
||||
if (!mantPos) {
|
||||
mant = -mant;
|
||||
}
|
||||
|
||||
return buildFloat(mant, exp);
|
||||
}
|
||||
|
||||
private void reportUnexpectedCharacterError(char c) {
|
||||
throw new RuntimeException("Unexpected char '" + c + "'.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a float from mantissa and exponent.
|
||||
*/
|
||||
public static float buildFloat(int mant, int exp) {
|
||||
if (exp < -125 || mant == 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (exp >= 128) {
|
||||
return (mant > 0)
|
||||
? Float.POSITIVE_INFINITY
|
||||
: Float.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
if (exp == 0) {
|
||||
return mant;
|
||||
}
|
||||
|
||||
if (mant >= (1 << 26)) {
|
||||
mant++; // round up trailing bits if they will be dropped.
|
||||
}
|
||||
|
||||
return (float) ((exp > 0) ? mant * pow10[exp] : mant / pow10[-exp]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array of powers of ten. Using double instead of float gives a tiny bit more precision.
|
||||
*/
|
||||
private static final double[] pow10 = new double[128];
|
||||
|
||||
static {
|
||||
for (int i = 0; i < pow10.length; i++) {
|
||||
pow10[i] = Math.pow(10, i);
|
||||
}
|
||||
}
|
||||
|
||||
public float nextFloat() {
|
||||
skipWhitespace();
|
||||
float f = parseFloat();
|
||||
skipNumberSeparator();
|
||||
return f;
|
||||
}
|
||||
}
|
||||
121
src/main/java/com/shaya/poinila/android/presentation/svgandroid/SVG.java
Executable file
121
src/main/java/com/shaya/poinila/android/presentation/svgandroid/SVG.java
Executable file
@@ -0,0 +1,121 @@
|
||||
package com.shaya.poinila.android.presentation.svgandroid;
|
||||
|
||||
import android.graphics.Picture;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.PictureDrawable;
|
||||
|
||||
/*
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Describes a vector Picture object, and optionally its bounds.
|
||||
*
|
||||
* @author Larva Labs, LLC
|
||||
*/
|
||||
public class SVG {
|
||||
|
||||
/**
|
||||
* The parsed Picture object.
|
||||
*/
|
||||
private Picture picture;
|
||||
|
||||
/**
|
||||
* These are the bounds for the SVG specified as a hidden "bounds" layer in the SVG.
|
||||
*/
|
||||
private RectF bounds;
|
||||
|
||||
/**
|
||||
* These are the estimated bounds of the SVG computed from the SVG elements while parsing.
|
||||
* Note that this could be null if there was a failure to compute limits (ie. an empty SVG).
|
||||
*/
|
||||
private RectF limits = null;
|
||||
|
||||
/**
|
||||
* Construct a new SVG.
|
||||
* @param picture the parsed picture object.
|
||||
* @param bounds the bounds computed from the "bounds" layer in the SVG.
|
||||
*/
|
||||
SVG(Picture picture, RectF bounds) {
|
||||
this.picture = picture;
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the limits of the SVG, which are the estimated bounds computed by the parser.
|
||||
* @param limits the bounds computed while parsing the SVG, may not be entirely accurate.
|
||||
*/
|
||||
void setLimits(RectF limits) {
|
||||
this.limits = limits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a picture drawable from the SVG.
|
||||
* @return the PictureDrawable.
|
||||
*/
|
||||
public PictureDrawable createPictureDrawable() {
|
||||
return new PictureDrawable(picture);
|
||||
// return new PictureDrawable(picture) {
|
||||
// @Override
|
||||
// public int getIntrinsicWidth() {
|
||||
// if (bounds != null) {
|
||||
// return (int) bounds.width();
|
||||
// } else if (limits != null) {
|
||||
// return (int) limits.width();
|
||||
// } else {
|
||||
// return -1;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getIntrinsicHeight() {
|
||||
// if (bounds != null) {
|
||||
// return (int) bounds.height();
|
||||
// } else if (limits != null) {
|
||||
// return (int) limits.height();
|
||||
// } else {
|
||||
// return -1;
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parsed SVG picture data.
|
||||
* @return the picture.
|
||||
*/
|
||||
public Picture getPicture() {
|
||||
return picture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bounding rectangle for the SVG, if one was specified.
|
||||
* @return rectangle representing the bounds.
|
||||
*/
|
||||
public RectF getBounds() {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bounding rectangle for the SVG that was computed upon parsing. It may not be entirely accurate for certain curves or transformations, but is often better than nothing.
|
||||
* @return rectangle representing the computed bounds.
|
||||
*/
|
||||
public RectF getLimits() {
|
||||
return limits;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.shaya.poinila.android.presentation.svgandroid;
|
||||
|
||||
/**
|
||||
* Runtime exception thrown when there is a problem parsing an SVG.
|
||||
*
|
||||
* @author Larva Labs, LLC
|
||||
*/
|
||||
public class SVGParseException extends RuntimeException {
|
||||
|
||||
public SVGParseException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public SVGParseException(String s, Throwable throwable) {
|
||||
super(s, throwable);
|
||||
}
|
||||
|
||||
public SVGParseException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
}
|
||||
1316
src/main/java/com/shaya/poinila/android/presentation/svgandroid/SVGParser.java
Executable file
1316
src/main/java/com/shaya/poinila/android/presentation/svgandroid/SVGParser.java
Executable file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-11-08.
|
||||
*/
|
||||
public abstract class AdapterPositionedEvent {
|
||||
public AdapterPositionedEvent(int adapterPosition) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
|
||||
public int adapterPosition;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-26.
|
||||
*/
|
||||
public class AddItemUIEvent {
|
||||
public AddItemUIEvent(int adapterPosition) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
|
||||
public int adapterPosition;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import data.event.BaseEvent;
|
||||
|
||||
/**
|
||||
* Created by hossein on 9/7/16.
|
||||
*/
|
||||
public class AfterVerifyResponse extends BaseEvent {
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import data.model.FriendRequestAnswer;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-15.
|
||||
*/
|
||||
public class AnswerFriendshipUIEvent {
|
||||
public int adapterPosition;
|
||||
public FriendRequestAnswer accept;
|
||||
|
||||
public AnswerFriendshipUIEvent(int adapterPosition, FriendRequestAnswer answer) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
this.accept = answer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Created by AlirezaF on 7/17/2015.
|
||||
*/
|
||||
public class CapturePhotoEvent {
|
||||
public final int requestCode;
|
||||
public final Intent intent;
|
||||
|
||||
public CapturePhotoEvent(Intent takePictureIntent, int requestTakePhoto) {
|
||||
intent = takePictureIntent;
|
||||
requestCode = requestTakePhoto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-01.
|
||||
*/
|
||||
public class ChangePasswordUIEvent {
|
||||
public final String oldPass;
|
||||
public final String newPass;
|
||||
|
||||
public ChangePasswordUIEvent(String oldPass, String newPass) {
|
||||
this.oldPass = oldPass;
|
||||
this.newPass = newPass;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-19.
|
||||
*/
|
||||
public class CheckBoxClickUIEvent {
|
||||
public boolean checked;
|
||||
public int adapterPosition;
|
||||
|
||||
public CheckBoxClickUIEvent(boolean checked, int adapterPosition) {
|
||||
this.checked = checked;
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-29.
|
||||
*/
|
||||
public class CirclesSelectedUIEvent {
|
||||
public final boolean[] selectedCircles;
|
||||
//public final int actorID;
|
||||
|
||||
public CirclesSelectedUIEvent(boolean[] selectedCircles, int actorID) {
|
||||
|
||||
this.selectedCircles = selectedCircles;
|
||||
//this.actorID = actorID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import data.event.BaseEvent;
|
||||
import data.event.IdentifiableEvent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-06.
|
||||
*/
|
||||
public class CollectionClickedUIEvent extends IdentifiableEvent {
|
||||
public int adapterPosition;
|
||||
|
||||
public CollectionClickedUIEvent(int adapterPosition, BaseEvent.ReceiverName receiverTag) {
|
||||
super(receiverTag);
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-11-08.
|
||||
*/
|
||||
public class CollectionFrameToggledEvent extends AdapterPositionedEvent{
|
||||
public CollectionFrameToggledEvent(int adapterPosition) {
|
||||
super(adapterPosition);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-09-22.
|
||||
*/
|
||||
public class CollectionListActivityImageSelectedUIEvent extends ImageSelectedUIEvent {
|
||||
public CollectionListActivityImageSelectedUIEvent(ImageSelectedUIEvent event) {
|
||||
super(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-09-20.
|
||||
*/
|
||||
public class CommentLongClickUIEvent {
|
||||
public int adapterPosition;
|
||||
|
||||
public CommentLongClickUIEvent(int adapterPosition) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-28.
|
||||
*/
|
||||
public class DeleteCircleUIEvent {
|
||||
public int adapterPosition;
|
||||
|
||||
public DeleteCircleUIEvent(int adapterPosition) {
|
||||
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-28.
|
||||
*/
|
||||
public class DeleteFrameUIEvent {
|
||||
|
||||
|
||||
public int adapterPosition;
|
||||
|
||||
public DeleteFrameUIEvent(int adapterPosition) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-28.
|
||||
*/
|
||||
public class EditCircleNameUIEvent {
|
||||
public int adapterPosition;
|
||||
|
||||
public EditCircleNameUIEvent(int adapterPosition) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-28.
|
||||
*/
|
||||
public class EditFrameNameUIEvent {
|
||||
public int adapterPosition;
|
||||
|
||||
public EditFrameNameUIEvent(int adapterPosition) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-17.
|
||||
*/
|
||||
public class EditItemUIEvent {
|
||||
public int adapterPosition;
|
||||
|
||||
public EditItemUIEvent(int adapterPosition) {
|
||||
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 12/26/2015.
|
||||
*/
|
||||
public class ExploreTagEvent {
|
||||
public String text;
|
||||
|
||||
public ExploreTagEvent(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
|
||||
import data.event.IdentifiableEvent;
|
||||
|
||||
/**
|
||||
* Created by iran on 11/22/2015.
|
||||
*/
|
||||
public class FABMenuCollapseUIEvent extends IdentifiableEvent {
|
||||
public FABMenuCollapseUIEvent(ReceiverName receiverName) {
|
||||
super(receiverName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
|
||||
import data.event.BaseEvent;
|
||||
import data.event.IdentifiableEvent;
|
||||
|
||||
/**
|
||||
* Created by iran on 11/22/2015.
|
||||
*/
|
||||
public class FABMenuExpandUIEvent extends IdentifiableEvent {
|
||||
public FABMenuExpandUIEvent(BaseEvent.ReceiverName receiverName) {
|
||||
super(receiverName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import data.model.Frame;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-01.
|
||||
*/
|
||||
public class FramesUpdatedUIEvent {
|
||||
public List<Frame> frames;
|
||||
|
||||
public FramesUpdatedUIEvent(List<Frame> frames) {
|
||||
this.frames = frames;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import data.model.Member;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-10-11.
|
||||
*/
|
||||
public class FriendCirclesUpdated {
|
||||
public final List<Integer> selectedCirclesIDs;
|
||||
public final Member member;
|
||||
|
||||
public FriendCirclesUpdated(List<Integer> selectedCirclesIDs, Member member) {
|
||||
this.selectedCirclesIDs = selectedCirclesIDs;
|
||||
this.member = member;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by AlirezaF on 7/16/2015.
|
||||
*/
|
||||
public class FriendshipClickEvent {
|
||||
public final int adapterPosition;
|
||||
|
||||
public FriendshipClickEvent(int adapterPosition) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 12/6/2015.
|
||||
*/
|
||||
public class GoNextPhaseUIEvent {
|
||||
public GoNextPhaseUIEvent(String phase) {
|
||||
this.phase = phase;
|
||||
}
|
||||
|
||||
public String phase;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 12/6/2015.
|
||||
*/
|
||||
public class GoPreviousPhaseUIEvent {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import data.event.LoginSucceedEvent;
|
||||
|
||||
/**
|
||||
* Created by iran on 6/26/2016.
|
||||
*/
|
||||
public class GoogleLoginSucceedEvent extends LoginSucceedEvent {
|
||||
public boolean firstLoginDoneByGoogle = false;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import data.event.BaseEvent;
|
||||
|
||||
/**
|
||||
* Created by iran on 5/28/2016.
|
||||
*/
|
||||
public class HelpDashboardFragment extends BaseEvent {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import data.event.BaseEvent;
|
||||
|
||||
/**
|
||||
* Created by iran on 5/28/2016.
|
||||
*/
|
||||
public class HelpMyFollowedCollectionListFragment extends BaseEvent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
|
||||
import data.event.BaseEvent;
|
||||
|
||||
/**
|
||||
* Created by iran on 5/28/2016.
|
||||
*/
|
||||
public class HelpMyProfileFragment extends BaseEvent {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by AlirezaF on 7/16/2015.
|
||||
*/
|
||||
public class ImageClickedUIEvent {
|
||||
public final int adapterPosition;
|
||||
|
||||
public ImageClickedUIEvent(int adapterPosition) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
/**
|
||||
* Created by AlirezaF on 7/17/2015.
|
||||
*/
|
||||
public class ImageSelectedUIEvent {
|
||||
public String absolutePath;
|
||||
public Uri mediaPath;
|
||||
|
||||
public ImageSelectedUIEvent(String absolutePath, Uri mediaPath) {
|
||||
this.absolutePath = absolutePath;
|
||||
this.mediaPath = mediaPath;
|
||||
}
|
||||
|
||||
public ImageSelectedUIEvent(ImageSelectedUIEvent event){
|
||||
this(event.absolutePath, event.mediaPath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-09-22.
|
||||
*/
|
||||
public class MainActivityImageSelectedUIEvent extends ImageSelectedUIEvent {
|
||||
public MainActivityImageSelectedUIEvent(ImageSelectedUIEvent event) {
|
||||
super(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-11-08.
|
||||
*/
|
||||
public class MemberCircleToggledEvent extends AdapterPositionedEvent{
|
||||
public MemberCircleToggledEvent(int adapterPosition) {
|
||||
super(adapterPosition);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import data.event.BaseEvent;
|
||||
import data.event.IdentifiableEvent;
|
||||
|
||||
/**
|
||||
* Created by AlirezaF on 7/16/2015.
|
||||
*/
|
||||
public class MemberClickedUIEvent extends IdentifiableEvent {
|
||||
public int adapterPosition;
|
||||
public MemberClickedUIEvent(int adapterPosition, BaseEvent.ReceiverName receiverTag) {
|
||||
super(receiverTag);
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-19.
|
||||
*/
|
||||
public class NeutralDialogButtonClickedUIEvent {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
|
||||
import data.model.SuggestedWebPagePost;
|
||||
|
||||
public class NewWebsitePostEvent {
|
||||
public SuggestedWebPagePost suggestedPost;
|
||||
|
||||
public NewWebsitePostEvent(SuggestedWebPagePost suggestedPost) {
|
||||
this.suggestedPost = suggestedPost;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-10-25.
|
||||
*/
|
||||
public class NotifActorClickedUIEvent {
|
||||
public int adapterPosition;
|
||||
|
||||
public NotifActorClickedUIEvent(int adapterPosition) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import data.model.ImageUrls;
|
||||
import data.model.Participant;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-11-02.
|
||||
*/
|
||||
public class NotifParticipantClickedUIEvent {
|
||||
public Participant participant;
|
||||
public ImageUrls.ImageType participantsType;
|
||||
|
||||
public NotifParticipantClickedUIEvent(Participant participant, ImageUrls.ImageType participantsType) {
|
||||
this.participant = participant;
|
||||
this.participantsType = participantsType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import data.model.FriendRequestAnswer;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-15.
|
||||
*/
|
||||
public class OnAnswerFriendshipUIEvent {
|
||||
private int adapterPosition;
|
||||
public FriendRequestAnswer accept;
|
||||
|
||||
public OnAnswerFriendshipUIEvent(int adapterPosition, FriendRequestAnswer answer) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
this.accept = answer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-06.
|
||||
*/
|
||||
public class OnFollowUnfollowCollectionUIEvent {
|
||||
public int adapterPosition;
|
||||
public boolean follow;
|
||||
|
||||
public OnFollowUnfollowCollectionUIEvent(int adapterPosition) {
|
||||
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
|
||||
public OnFollowUnfollowCollectionUIEvent(int adapterPosition, boolean follow) {
|
||||
|
||||
this.adapterPosition = adapterPosition;
|
||||
this.follow = follow;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
|
||||
import data.model.Frame;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-08.
|
||||
*/
|
||||
public class OnFrameClickedUIEvent {
|
||||
public Frame frame;
|
||||
|
||||
public OnFrameClickedUIEvent(Frame frame) {
|
||||
|
||||
this.frame = frame;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-09-07.
|
||||
*/
|
||||
public class OnOffSettingToggledUIEvent {
|
||||
public int adapterPosition;
|
||||
public boolean settingOn;
|
||||
|
||||
public OnOffSettingToggledUIEvent(int adapterPosition, boolean settingOn) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
this.settingOn = settingOn;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
|
||||
import data.event.BaseEvent;
|
||||
|
||||
/**
|
||||
* Created by iran on 1/18/2016.
|
||||
*/
|
||||
public class PermissionEvent extends BaseEvent {
|
||||
public String permissionString;
|
||||
|
||||
public PermissionEvent(String permissionString) {
|
||||
|
||||
this.permissionString = permissionString;
|
||||
}
|
||||
/*public final boolean granted;
|
||||
public final int requestCode;
|
||||
|
||||
public PermissionEvent(boolean granted, int requestCode) {
|
||||
this.granted = granted;
|
||||
this.requestCode = requestCode;
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by AlirezaF on 7/17/2015.
|
||||
*/
|
||||
public class PhotoCapturedEvent {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-28.
|
||||
*/
|
||||
public class PositiveButtonClickedUIEvent {
|
||||
private Object data;
|
||||
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public PositiveButtonClickedUIEvent setData(Object data) {
|
||||
this.data = data;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
|
||||
import data.event.BaseEvent;
|
||||
import data.event.IdentifiableEvent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-23.
|
||||
*/
|
||||
public class PostClickedUIEvent extends IdentifiableEvent {
|
||||
public int adapterPosition;
|
||||
|
||||
public PostClickedUIEvent(int adapterPosition, BaseEvent.ReceiverName receiverTag) {
|
||||
super(receiverTag);
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import data.event.BaseEvent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-11-18.
|
||||
*/
|
||||
public class PostComponentClickedUIEvent extends BaseEvent {
|
||||
public Type type;
|
||||
|
||||
public PostComponentClickedUIEvent(Type type){
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public enum Type{
|
||||
Fave,
|
||||
FaversList,
|
||||
Comments,
|
||||
RepostersList,
|
||||
Repost,
|
||||
Reference,
|
||||
Collection,
|
||||
Poster,
|
||||
OriginalCollection,
|
||||
FullImage;
|
||||
|
||||
public static List<Type> guestCantPerformActions = Arrays.asList(Fave, Repost);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-10-14.
|
||||
*/
|
||||
public class PostHeightUIEvent {
|
||||
public final int position;
|
||||
public final int height;
|
||||
|
||||
public PostHeightUIEvent(int position, int height) {
|
||||
this.position = position;
|
||||
this.height = height;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-09-22.
|
||||
*/
|
||||
public class PostListActivityImageSelectedUIEvent extends ImageSelectedUIEvent {
|
||||
public PostListActivityImageSelectedUIEvent(ImageSelectedUIEvent event) {
|
||||
super(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-09-13.
|
||||
*/
|
||||
public class ProfilePicSelectedEvent {
|
||||
public String absolutePath;
|
||||
public Uri mediaPath;
|
||||
|
||||
public ProfilePicSelectedEvent(String absolutePath, Uri mediaPath) {
|
||||
this.absolutePath = absolutePath;
|
||||
this.mediaPath = mediaPath;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
|
||||
import data.event.BaseEvent;
|
||||
|
||||
/**
|
||||
* Created by iran on 1/20/2016.
|
||||
*/
|
||||
public class RatePonilaEvent extends BaseEvent {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-26.
|
||||
*/
|
||||
public class RemoveItemUIEvent {
|
||||
public RemoveItemUIEvent(int adapterPosition) {
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
|
||||
public int adapterPosition;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-08-16.
|
||||
*/
|
||||
public class RemovePostUIEvent {
|
||||
public int adapterPosition;
|
||||
|
||||
public RemovePostUIEvent(int adapterPosition) {
|
||||
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Created by AlirezaF on 7/22/2015.
|
||||
*/
|
||||
public class RemoveTagEvent {
|
||||
public View tagView;
|
||||
public int adapterPosition;
|
||||
|
||||
public RemoveTagEvent(View tagView) {
|
||||
this.tagView = tagView;
|
||||
}
|
||||
|
||||
public RemoveTagEvent(int adapterPosition) {
|
||||
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Created by AlirezaF on 7/17/2015.
|
||||
*/
|
||||
public class SelectImageEvent {
|
||||
public final Intent intent;
|
||||
public int requestCode;
|
||||
|
||||
public SelectImageEvent(Intent selectImageIntent, int requestSelectImage) {
|
||||
intent = selectImageIntent;
|
||||
requestCode = requestSelectImage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-12.
|
||||
*/
|
||||
public class ShowSelectInterestUIEvent {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 7/20/2016.
|
||||
*/
|
||||
public class ShowVerifySnackbarEvent {
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import com.shaya.poinila.android.presentation.view.activity.SettingActivity.SettingType;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-21.
|
||||
*/
|
||||
public class SimpleSettingTextSetEvent {
|
||||
public SettingType settingType;
|
||||
public String value;
|
||||
public int itemPosition;
|
||||
|
||||
public SimpleSettingTextSetEvent(SettingType settingType, String value, int itemPosition) {
|
||||
this.settingType = settingType;
|
||||
this.value = value;
|
||||
this.itemPosition = itemPosition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 12/8/2015.
|
||||
*/
|
||||
public class SmsReceivedEvent {
|
||||
public String str;
|
||||
|
||||
public SmsReceivedEvent(String str) {
|
||||
this.str = str;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import data.event.BaseEvent;
|
||||
import data.model.Post;
|
||||
|
||||
/**
|
||||
* Created by iran on 7/24/2016.
|
||||
*/
|
||||
public class SuggestionPosts extends BaseEvent {
|
||||
public List<Post> posts;
|
||||
|
||||
public SuggestionPosts(List<Post> posts){
|
||||
this.posts = posts;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import com.raizlabs.android.dbflow.structure.BaseModel;
|
||||
|
||||
/**
|
||||
* Created by iran on 8/1/2016.
|
||||
*/
|
||||
public class UpdateNewPostDialogEvent extends data.event.ModelEvent {
|
||||
public UpdateNewPostDialogEvent(BaseModel model) {
|
||||
super(model);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-09-30.
|
||||
*/
|
||||
public class UpdateUICommentEvent {
|
||||
public static final int INCREMENT_COMMENTS = 1;
|
||||
public static final int DECREMENT_COMMENTS = 2;
|
||||
public String postId;
|
||||
|
||||
public int action;
|
||||
|
||||
public UpdateUICommentEvent(int action, String postId) {
|
||||
this.action = action;
|
||||
this.postId = postId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
import data.event.BaseEvent;
|
||||
import data.model.Post;
|
||||
|
||||
/**
|
||||
* Created by iran on 7/11/2016.
|
||||
*/
|
||||
public class UpdateUiRepostEvent extends BaseEvent {
|
||||
|
||||
public boolean isSuccess = true;
|
||||
public int postId;
|
||||
|
||||
public UpdateUiRepostEvent(int postId, boolean isSuccess){
|
||||
this.isSuccess = isSuccess;
|
||||
this.postId = postId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-11-18.
|
||||
*/
|
||||
public class UrlClickedUIEvent {
|
||||
public String url;
|
||||
|
||||
public UrlClickedUIEvent(String Url) {
|
||||
url = Url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.shaya.poinila.android.presentation.uievent;
|
||||
|
||||
/**
|
||||
* Created by iran on 2015-07-28.
|
||||
*/
|
||||
public class ViewCircleMembersUIEvent {
|
||||
public int adapterPosition;
|
||||
|
||||
public ViewCircleMembersUIEvent(int adapterPosition) {
|
||||
|
||||
this.adapterPosition = adapterPosition;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user