init commit

This commit is contained in:
2025-11-07 22:14:34 +01:00
parent 02909af48a
commit 37d8826019
945 changed files with 48551 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -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
View 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
View 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
View 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
View 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

Binary file not shown.

View File

@@ -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

Binary file not shown.

273
src/main/AndroidManifest.xml Executable file
View 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

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

View 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;
}
}

View 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;
}
}

View File

@@ -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();
}
}

View 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;
}
}

File diff suppressed because it is too large Load Diff

View 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");
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}
};
}
}

View File

@@ -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;
}
}

View 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;
}
}

View File

@@ -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);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 {
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -0,0 +1,7 @@
package com.shaya.poinila.android.presentation.uievent;
/**
* Created by iran on 12/6/2015.
*/
public class GoPreviousPhaseUIEvent {
}

View File

@@ -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;
}

View File

@@ -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 {
}

View File

@@ -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 {
}

View File

@@ -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 {
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,7 @@
package com.shaya.poinila.android.presentation.uievent;
/**
* Created by iran on 2015-08-19.
*/
public class NeutralDialogButtonClickedUIEvent {
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}*/
}

View File

@@ -0,0 +1,7 @@
package com.shaya.poinila.android.presentation.uievent;
/**
* Created by AlirezaF on 7/17/2015.
*/
public class PhotoCapturedEvent {
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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 {
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,7 @@
package com.shaya.poinila.android.presentation.uievent;
/**
* Created by iran on 2015-07-12.
*/
public class ShowSelectInterestUIEvent {
}

View File

@@ -0,0 +1,7 @@
package com.shaya.poinila.android.presentation.uievent;
/**
* Created by iran on 7/20/2016.
*/
public class ShowVerifySnackbarEvent {
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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