mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-02-22 06:24:44 +01:00
[Feedback] Add new feedback fragment and API.
This commit is contained in:
parent
759afcf3ca
commit
21b2e5d194
@ -188,6 +188,8 @@ dependencies {
|
|||||||
implementation "com.squareup.retrofit2:converter-gson:${versions.retrofit}"
|
implementation "com.squareup.retrofit2:converter-gson:${versions.retrofit}"
|
||||||
|
|
||||||
implementation 'com.github.jetradarmobile:android-snowfall:1.2.0'
|
implementation 'com.github.jetradarmobile:android-snowfall:1.2.0'
|
||||||
|
|
||||||
|
implementation "io.coil-kt:coil:0.9.2"
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-21.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.events
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
|
||||||
|
|
||||||
|
data class FeedbackMessageEvent(val message: FeedbackMessage)
|
@ -17,6 +17,7 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.response.ApiResponse
|
|||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.WebPushResponse
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.WebPushResponse
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
@ -214,4 +215,14 @@ class SzkolnyApi(val app: App) {
|
|||||||
fun getUpdate(channel: String): ApiResponse<List<Update>>? {
|
fun getUpdate(channel: String): ApiResponse<List<Update>>? {
|
||||||
return api.updates(channel).execute().body()
|
return api.updates(channel).execute().body()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun sendFeedbackMessage(senderName: String?, targetDeviceId: String?, text: String): FeedbackMessage? {
|
||||||
|
return api.feedbackMessage(FeedbackMessageRequest(
|
||||||
|
deviceId = app.deviceId,
|
||||||
|
device = getDevice(),
|
||||||
|
senderName = senderName,
|
||||||
|
targetDeviceId = targetDeviceId,
|
||||||
|
text = text
|
||||||
|
)).execute().body()?.data?.message
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,7 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.szkolny
|
package pl.szczodrzynski.edziennik.data.api.szkolny
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.request.*
|
import pl.szczodrzynski.edziennik.data.api.szkolny.request.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.ApiResponse
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.ServerSyncResponse
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.WebPushResponse
|
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
@ -34,4 +31,7 @@ interface SzkolnyService {
|
|||||||
|
|
||||||
@GET("updates/app")
|
@GET("updates/app")
|
||||||
fun updates(@Query("channel") channel: String = "release"): Call<ApiResponse<List<Update>>>
|
fun updates(@Query("channel") channel: String = "release"): Call<ApiResponse<List<Update>>>
|
||||||
|
|
||||||
|
@POST("feedbackMessage")
|
||||||
|
fun feedbackMessage(@Body request: FeedbackMessageRequest): Call<ApiResponse<FeedbackMessageResponse>>
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-21.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.szkolny.request
|
||||||
|
|
||||||
|
data class FeedbackMessageRequest(
|
||||||
|
val deviceId: String,
|
||||||
|
val device: Device? = null,
|
||||||
|
|
||||||
|
val senderName: String?,
|
||||||
|
val targetDeviceId: String?,
|
||||||
|
val text: String
|
||||||
|
)
|
@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-21.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.szkolny.response
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
|
||||||
|
|
||||||
|
data class FeedbackMessageResponse(val message: FeedbackMessage)
|
@ -42,7 +42,7 @@ import pl.szczodrzynski.edziennik.data.db.migration.*
|
|||||||
ConfigEntry::class,
|
ConfigEntry::class,
|
||||||
LibrusLesson::class,
|
LibrusLesson::class,
|
||||||
Metadata::class
|
Metadata::class
|
||||||
], version = 75)
|
], version = 76)
|
||||||
@TypeConverters(
|
@TypeConverters(
|
||||||
ConverterTime::class,
|
ConverterTime::class,
|
||||||
ConverterDate::class,
|
ConverterDate::class,
|
||||||
@ -158,7 +158,8 @@ abstract class AppDb : RoomDatabase() {
|
|||||||
Migration72(),
|
Migration72(),
|
||||||
Migration73(),
|
Migration73(),
|
||||||
Migration74(),
|
Migration74(),
|
||||||
Migration75()
|
Migration75(),
|
||||||
|
Migration76()
|
||||||
).allowMainThreadQueries().build()
|
).allowMainThreadQueries().build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.db.dao;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.room.Dao;
|
|
||||||
import androidx.room.Insert;
|
|
||||||
import androidx.room.OnConflictStrategy;
|
|
||||||
import androidx.room.Query;
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.FeedbackMessageWithCount;
|
|
||||||
|
|
||||||
@Dao
|
|
||||||
public interface FeedbackMessageDao {
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
void add(FeedbackMessage feedbackMessage);
|
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
||||||
void addAll(List<FeedbackMessage> feedbackMessageList);
|
|
||||||
|
|
||||||
@Query("DELETE FROM feedbackMessages")
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
@Query("SELECT * FROM feedbackMessages")
|
|
||||||
List<FeedbackMessage> getAllNow();
|
|
||||||
|
|
||||||
@Query("SELECT * FROM feedbackMessages WHERE fromUser = :fromUser")
|
|
||||||
List<FeedbackMessage> getAllByUserNow(String fromUser);
|
|
||||||
|
|
||||||
@Query("SELECT * FROM feedbackMessages")
|
|
||||||
LiveData<List<FeedbackMessage>> getAll();
|
|
||||||
|
|
||||||
@Query("SELECT *, COUNT(*) AS messageCount FROM feedbackMessages GROUP BY fromUser ORDER BY sentTime DESC")
|
|
||||||
List<FeedbackMessageWithCount> getAllWithCountNow();
|
|
||||||
}
|
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||||
|
*/
|
||||||
|
package pl.szczodrzynski.edziennik.data.db.dao
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface FeedbackMessageDao {
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
fun add(feedbackMessage: FeedbackMessage)
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
fun addAll(feedbackMessageList: List<FeedbackMessage>)
|
||||||
|
|
||||||
|
@Query("DELETE FROM feedbackMessages")
|
||||||
|
fun clear()
|
||||||
|
|
||||||
|
@get:Query("SELECT * FROM feedbackMessages ORDER BY sentTime DESC LIMIT 50")
|
||||||
|
val allNow: List<FeedbackMessage>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM feedbackMessages WHERE deviceId = :deviceId ORDER BY sentTime DESC LIMIT 50")
|
||||||
|
fun getByDeviceIdNow(deviceId: String): List<FeedbackMessage>
|
||||||
|
|
||||||
|
@get:Query("SELECT * FROM feedbackMessages")
|
||||||
|
val all: LiveData<List<FeedbackMessage>>
|
||||||
|
|
||||||
|
@get:Query("SELECT *, COUNT(*) AS count FROM feedbackMessages WHERE received = 1 AND devId IS NULL AND deviceId != 'szkolny.eu' GROUP BY deviceId ORDER BY sentTime DESC")
|
||||||
|
val allWithCountNow: List<FeedbackMessage.WithCount>
|
||||||
|
}
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.db.entity;
|
|
||||||
|
|
||||||
import androidx.room.Entity;
|
|
||||||
import androidx.room.Ignore;
|
|
||||||
import androidx.room.PrimaryKey;
|
|
||||||
|
|
||||||
@Entity(tableName = "feedbackMessages")
|
|
||||||
public class FeedbackMessage {
|
|
||||||
|
|
||||||
@PrimaryKey(autoGenerate = true)
|
|
||||||
public int messageId;
|
|
||||||
|
|
||||||
public boolean received = false;
|
|
||||||
public String fromUser = null;
|
|
||||||
public String fromUserName = null;
|
|
||||||
public long sentTime = System.currentTimeMillis();
|
|
||||||
public String text;
|
|
||||||
|
|
||||||
public FeedbackMessage(boolean received, String text) {
|
|
||||||
this.received = received;
|
|
||||||
this.sentTime = System.currentTimeMillis();
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Ignore
|
|
||||||
public FeedbackMessage() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-21.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.db.entity
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
|
@Entity(tableName = "feedbackMessages")
|
||||||
|
open class FeedbackMessage(
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
val messageId: Int = 0,
|
||||||
|
|
||||||
|
val received: Boolean,
|
||||||
|
val text: String,
|
||||||
|
|
||||||
|
// used always - contains the sender name
|
||||||
|
val senderName: String,
|
||||||
|
|
||||||
|
// used in DEV apps - contains device ID and model
|
||||||
|
var deviceId: String? = null,
|
||||||
|
var deviceName: String? = null,
|
||||||
|
|
||||||
|
val devId: Int? = null,
|
||||||
|
val devImage: String? = null,
|
||||||
|
|
||||||
|
val sentTime: Long = System.currentTimeMillis()
|
||||||
|
) {
|
||||||
|
class WithCount(messageId: Int, received: Boolean, text: String, senderName: String, deviceId: String?, deviceName: String?, devId: Int?, devImage: String?, sentTime: Long) : FeedbackMessage(messageId, received, text, senderName, deviceId, deviceName, devId, devImage, sentTime) {
|
||||||
|
var count = 0
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.db.full;
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage;
|
|
||||||
|
|
||||||
public class FeedbackMessageWithCount extends FeedbackMessage {
|
|
||||||
public int messageCount = 0;
|
|
||||||
}
|
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kacper Ziubryniewicz 2020-1-25
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.db.migration
|
||||||
|
|
||||||
|
import androidx.room.migration.Migration
|
||||||
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
|
|
||||||
|
class Migration76 : Migration(75, 76) {
|
||||||
|
override fun migrate(database: SupportSQLiteDatabase) {
|
||||||
|
database.execSQL("ALTER TABLE feedbackMessages RENAME TO _feedbackMessages;")
|
||||||
|
database.execSQL("CREATE TABLE feedbackMessages (\n" +
|
||||||
|
"\tmessageId INTEGER NOT NULL PRIMARY KEY,\n" +
|
||||||
|
"\treceived INTEGER NOT NULL,\n" +
|
||||||
|
"\ttext TEXT NOT NULL,\n" +
|
||||||
|
"\tsenderName TEXT NOT NULL,\n" +
|
||||||
|
"\tdeviceId TEXT DEFAULT NULL,\n" +
|
||||||
|
"\tdeviceName TEXT DEFAULT NULL,\n" +
|
||||||
|
"\tdevId INTEGER DEFAULT NULL,\n" +
|
||||||
|
"\tdevImage TEXT DEFAULT NULL,\n" +
|
||||||
|
"\tsentTime INTEGER NOT NULL\n" +
|
||||||
|
");")
|
||||||
|
database.execSQL("INSERT INTO feedbackMessages (messageId, received, text, senderName, deviceId, deviceName, devId, devImage, sentTime)\n" +
|
||||||
|
"SELECT messageId, received, text,\n" +
|
||||||
|
"CASE fromUser IS NOT NULL WHEN 1 THEN CASE fromUserName IS NULL WHEN 1 THEN \"\" ELSE fromUserName END ELSE \"\" END AS senderName,\n" +
|
||||||
|
"fromUser AS deviceId,\n" +
|
||||||
|
"NULL AS deviceName,\n" +
|
||||||
|
"CASE received AND fromUser IS NULL WHEN 1 THEN 100 ELSE NULL END AS devId,\n" +
|
||||||
|
"NULL AS devImage,\n" +
|
||||||
|
"sentTime\n" +
|
||||||
|
"FROM _feedbackMessages;")
|
||||||
|
database.execSQL("DROP TABLE _feedbackMessages;")
|
||||||
|
}
|
||||||
|
}
|
@ -5,17 +5,13 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.firebase
|
package pl.szczodrzynski.edziennik.data.firebase
|
||||||
|
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import org.greenrobot.eventbus.EventBus
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.FeedbackMessageEvent
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.PostNotifications
|
import pl.szczodrzynski.edziennik.data.api.task.PostNotifications
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
@ -49,7 +45,18 @@ class SzkolnyAppFirebase(val app: App, val profiles: List<Profile>, val message:
|
|||||||
message.data.getString("title") ?: "",
|
message.data.getString("title") ?: "",
|
||||||
message.data.getString("message") ?: ""
|
message.data.getString("message") ?: ""
|
||||||
)
|
)
|
||||||
"appUpdate" -> launch { UpdateWorker.runNow(app, app.gson.fromJson(message.data.get("update"), Update::class.java)) }
|
"appUpdate" -> launch { UpdateWorker.runNow(app, app.gson.fromJson(message.data.getString("update"), Update::class.java)) }
|
||||||
|
"feedbackMessage" -> launch {
|
||||||
|
val message = app.gson.fromJson(message.data.getString("message"), FeedbackMessage::class.java)
|
||||||
|
if (message.deviceId == app.deviceId) {
|
||||||
|
message.deviceId = null
|
||||||
|
message.deviceName = null
|
||||||
|
}
|
||||||
|
withContext(Dispatchers.Default) {
|
||||||
|
app.db.feedbackMessageDao().add(message)
|
||||||
|
}
|
||||||
|
EventBus.getDefault().postSticky(FeedbackMessageEvent(message))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,180 +1,22 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.modules.feedback;
|
package pl.szczodrzynski.edziennik.ui.modules.feedback;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.widget.PopupMenu;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
|
||||||
import com.github.bassaer.chatmessageview.model.IChatUser;
|
|
||||||
import com.github.bassaer.chatmessageview.model.Message;
|
|
||||||
import com.github.bassaer.chatmessageview.view.ChatView;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.App;
|
import pl.szczodrzynski.edziennik.App;
|
||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.FeedbackMessageWithCount;
|
|
||||||
import pl.szczodrzynski.edziennik.databinding.ActivityFeedbackBinding;
|
import pl.szczodrzynski.edziennik.databinding.ActivityFeedbackBinding;
|
||||||
import pl.szczodrzynski.edziennik.network.ServerRequest;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Anim;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes;
|
import pl.szczodrzynski.edziennik.utils.Themes;
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils;
|
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.utils.Utils.crc16;
|
|
||||||
import static pl.szczodrzynski.edziennik.utils.Utils.openUrl;
|
|
||||||
|
|
||||||
public class FeedbackActivity extends AppCompatActivity {
|
public class FeedbackActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private static final String TAG = "FeedbackActivity";
|
private static final String TAG = "FeedbackActivity";
|
||||||
private App app;
|
private App app;
|
||||||
private ActivityFeedbackBinding b;
|
private ActivityFeedbackBinding b;
|
||||||
private boolean firstSend = true;
|
|
||||||
private String deviceToSend = null;
|
|
||||||
private String nameToSend = null;
|
|
||||||
|
|
||||||
private BroadcastReceiver receiver;
|
|
||||||
|
|
||||||
private class User implements IChatUser {
|
|
||||||
Integer id;
|
|
||||||
String name;
|
|
||||||
Bitmap icon;
|
|
||||||
|
|
||||||
public User(int id, String name, Bitmap icon) {
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
this.icon = icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return this.id.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Bitmap getIcon() {
|
|
||||||
return this.icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setIcon(Bitmap icon) {
|
|
||||||
this.icon = icon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private User dev;
|
|
||||||
private User user;
|
|
||||||
private ChatView mChatView;
|
|
||||||
|
|
||||||
private void send(String text){
|
|
||||||
/*if ("enable dev mode pls".equals(text)) {
|
|
||||||
try {
|
|
||||||
Log.d(TAG, Utils.AESCrypt.encrypt("ok here you go it's enabled now", "8iryqZUfIUiLmJGi"));
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
MaterialDialog progressDialog = new MaterialDialog.Builder(this)
|
|
||||||
.title(R.string.loading)
|
|
||||||
.content(R.string.sending_message)
|
|
||||||
.negativeText(R.string.cancel)
|
|
||||||
.show();
|
|
||||||
new ServerRequest(app, "https://edziennik.szczodrzynski.pl/app/main.php?feedback_message", "FeedbackSend")
|
|
||||||
.setBodyParameter("message_text", text)
|
|
||||||
.setBodyParameter("target_device", deviceToSend == null ? "null" : deviceToSend)
|
|
||||||
.run(((e, result) -> {
|
|
||||||
progressDialog.dismiss();
|
|
||||||
if (result != null && result.get("success") != null && result.get("success").getAsBoolean()) {
|
|
||||||
FeedbackMessage feedbackMessage = new FeedbackMessage(false, text);
|
|
||||||
if (deviceToSend != null) {
|
|
||||||
feedbackMessage.fromUser = deviceToSend;
|
|
||||||
feedbackMessage.fromUserName = nameToSend;
|
|
||||||
}
|
|
||||||
AsyncTask.execute(() -> app.db.feedbackMessageDao().add(feedbackMessage));
|
|
||||||
Message message = new Message.Builder()
|
|
||||||
.setUser(user)
|
|
||||||
.setRight(true)
|
|
||||||
.setText(feedbackMessage.text)
|
|
||||||
.hideIcon(true)
|
|
||||||
.build();
|
|
||||||
mChatView.send(message);
|
|
||||||
mChatView.setInputText("");
|
|
||||||
b.textInput.setText("");
|
|
||||||
if (firstSend) {
|
|
||||||
Anim.fadeOut(b.inputLayout, 500, new Animation.AnimationListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationStart(Animation animation) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animation animation) {
|
|
||||||
b.inputLayout.setVisibility(View.GONE);
|
|
||||||
Anim.fadeIn(b.chatLayout, 500, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationRepeat(Animation animation) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (deviceToSend == null) {
|
|
||||||
// we are not the developer
|
|
||||||
FeedbackMessage feedbackMessage2 = new FeedbackMessage(true, "Postaram się jak najszybciej Tobie odpowiedzieć. Dostaniesz powiadomienie o odpowiedzi, która pokaże się w tym miejscu.");
|
|
||||||
AsyncTask.execute(() -> app.db.feedbackMessageDao().add(feedbackMessage2));
|
|
||||||
message = new Message.Builder()
|
|
||||||
.setUser(dev)
|
|
||||||
.setRight(false)
|
|
||||||
.setText(feedbackMessage2.text)
|
|
||||||
.hideIcon(false)
|
|
||||||
.build();
|
|
||||||
mChatView.receive(message);
|
|
||||||
}
|
|
||||||
firstSend = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Toast.makeText(app, "Nie udało się wysłać wiadomości.", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void openFaq() {
|
|
||||||
openUrl(this, "http://szkolny.eu/pomoc/");
|
|
||||||
new MaterialDialog.Builder(this)
|
|
||||||
.title(R.string.faq_back_title)
|
|
||||||
.content(R.string.faq_back_text)
|
|
||||||
.positiveText(R.string.yes)
|
|
||||||
.negativeText(R.string.no)
|
|
||||||
.onPositive(((dialog, which) -> {
|
|
||||||
|
|
||||||
}))
|
|
||||||
.onNegative(((dialog, which) -> {
|
|
||||||
|
|
||||||
}))
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -188,154 +30,6 @@ public class FeedbackActivity extends AppCompatActivity {
|
|||||||
if (getSupportActionBar() != null)
|
if (getSupportActionBar() != null)
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
|
||||||
b.faqText.setOnClickListener((v -> {
|
|
||||||
openFaq();
|
|
||||||
}));
|
|
||||||
b.faqButton.setOnClickListener((v -> {
|
|
||||||
openFaq();
|
|
||||||
}));
|
|
||||||
|
|
||||||
receiver = new BroadcastReceiver() {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
FeedbackMessage message = app.getGson().fromJson(intent.getStringExtra("message"), FeedbackMessage.class);
|
|
||||||
Calendar c = Calendar.getInstance();
|
|
||||||
c.setTimeInMillis(message.sentTime);
|
|
||||||
Message chatMessage = new Message.Builder()
|
|
||||||
.setUser(intent.getStringExtra("type").equals("dev_chat") ? new User(crc16(message.fromUser.getBytes()), message.fromUserName, BitmapFactory.decodeResource(getResources(), R.drawable.ic_account_circle)) : dev)
|
|
||||||
.setRight(!message.received)
|
|
||||||
.setText(message.text)
|
|
||||||
.setSendTime(c)
|
|
||||||
.hideIcon(!message.received)
|
|
||||||
.build();
|
|
||||||
if (message.received)
|
|
||||||
mChatView.receive(chatMessage);
|
|
||||||
else
|
|
||||||
mChatView.send(chatMessage);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mChatView = b.chatView;
|
|
||||||
|
|
||||||
dev = new User(0, "Szkolny.eu", BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
|
|
||||||
user = new User(1, "Ja", BitmapFactory.decodeResource(getResources(), R.drawable.profile));
|
|
||||||
|
|
||||||
//Set UI parameters if you need
|
|
||||||
mChatView.setLeftBubbleColor(Utils.getAttr(this, R.attr.colorSurface));
|
|
||||||
mChatView.setLeftMessageTextColor(Utils.getAttr(this, android.R.attr.textColorPrimary));
|
|
||||||
mChatView.setRightBubbleColor(Utils.getAttr(this, R.attr.colorPrimary));
|
|
||||||
mChatView.setRightMessageTextColor(Color.WHITE);
|
|
||||||
|
|
||||||
//mChatView.setBackgroundColor(ContextCompat.getColor(this, R.color.blueGray500));
|
|
||||||
mChatView.setSendButtonColor(Utils.getAttr(this, R.attr.colorAccent));
|
|
||||||
mChatView.setSendIcon(R.drawable.ic_action_send);
|
|
||||||
//mChatView.setUsernameTextColor(Color.WHITE);
|
|
||||||
//mChatView.setSendTimeTextColor(Color.WHITE);
|
|
||||||
//mChatView.setDateSeparatorColor(Color.WHITE);
|
|
||||||
mChatView.setInputTextHint("Napisz...");
|
|
||||||
//mChatView.setInputTextColor(Color.BLACK);
|
|
||||||
mChatView.setMessageMarginTop(5);
|
|
||||||
mChatView.setMessageMarginBottom(5);
|
|
||||||
|
|
||||||
if (App.Companion.getDevMode() && app.getDeviceId().equals("f054761fbdb6a238")) {
|
|
||||||
b.targetDeviceLayout.setVisibility(View.VISIBLE);
|
|
||||||
b.targetDeviceDropDown.setOnClickListener((v -> {
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
List<FeedbackMessageWithCount> messageList = app.db.feedbackMessageDao().getAllWithCountNow();
|
|
||||||
runOnUiThread(() -> {
|
|
||||||
PopupMenu popupMenu = new PopupMenu(this, b.targetDeviceDropDown);
|
|
||||||
int index = 0;
|
|
||||||
for (FeedbackMessageWithCount message: messageList) {
|
|
||||||
popupMenu.getMenu().add(0, index, index, message.fromUserName+" - "+message.fromUser+" ("+message.messageCount+")");
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
popupMenu.setOnMenuItemClickListener(item -> {
|
|
||||||
b.targetDeviceDropDown.setText(item.getTitle());
|
|
||||||
mChatView.getMessageView().removeAll();
|
|
||||||
FeedbackMessageWithCount message = messageList.get(item.getItemId());
|
|
||||||
deviceToSend = message.fromUser;
|
|
||||||
nameToSend = message.fromUserName;
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
List<FeedbackMessage> messageList2 = app.db.feedbackMessageDao().getAllByUserNow(deviceToSend);
|
|
||||||
runOnUiThread(() -> {
|
|
||||||
b.chatLayout.setVisibility(View.VISIBLE);
|
|
||||||
b.inputLayout.setVisibility(View.GONE);
|
|
||||||
for (FeedbackMessage message2 : messageList2) {
|
|
||||||
Calendar c = Calendar.getInstance();
|
|
||||||
c.setTimeInMillis(message2.sentTime);
|
|
||||||
Message chatMessage = new Message.Builder()
|
|
||||||
.setUser(message2.received ? new User(crc16(message2.fromUser.getBytes()), message2.fromUserName, BitmapFactory.decodeResource(getResources(), R.drawable.ic_account_circle)) : user)
|
|
||||||
.setRight(!message2.received)
|
|
||||||
.setText(message2.text)
|
|
||||||
.setSendTime(c)
|
|
||||||
.hideIcon(!message2.received)
|
|
||||||
.build();
|
|
||||||
if (message2.received)
|
|
||||||
mChatView.receive(chatMessage);
|
|
||||||
else
|
|
||||||
mChatView.send(chatMessage);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
popupMenu.show();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
List<FeedbackMessage> messageList = app.db.feedbackMessageDao().getAllNow();
|
|
||||||
firstSend = messageList.size() == 0;
|
|
||||||
runOnUiThread(() -> {
|
|
||||||
if (firstSend) {
|
|
||||||
openFaq();
|
|
||||||
b.chatLayout.setVisibility(View.GONE);
|
|
||||||
b.inputLayout.setVisibility(View.VISIBLE);
|
|
||||||
b.sendButton.setOnClickListener((v -> {
|
|
||||||
if (b.textInput.getText() == null || b.textInput.getText().length() == 0) {
|
|
||||||
Toast.makeText(app, "Podaj treść wiadomości.", Toast.LENGTH_SHORT).show();
|
|
||||||
} else {
|
|
||||||
send(b.textInput.getText().toString());
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
/*new MaterialDialog.Builder(this)
|
|
||||||
.title(R.string.faq)
|
|
||||||
.content(R.string.faq_text)
|
|
||||||
.positiveText(R.string.yes)
|
|
||||||
.negativeText(R.string.no)
|
|
||||||
.onPositive(((dialog, which) -> {
|
|
||||||
openFaq();
|
|
||||||
}))
|
|
||||||
.show();*/
|
|
||||||
b.chatLayout.setVisibility(View.VISIBLE);
|
|
||||||
b.inputLayout.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
for (FeedbackMessage message : messageList) {
|
|
||||||
Calendar c = Calendar.getInstance();
|
|
||||||
c.setTimeInMillis(message.sentTime);
|
|
||||||
Message chatMessage = new Message.Builder()
|
|
||||||
.setUser(message.fromUser != null ? new User(crc16(message.fromUser.getBytes()), message.fromUserName, BitmapFactory.decodeResource(getResources(), R.drawable.ic_account_circle)) : message.received ? dev : user)
|
|
||||||
.setRight(!message.received)
|
|
||||||
.setText(message.text)
|
|
||||||
.setSendTime(c)
|
|
||||||
.hideIcon(!message.received)
|
|
||||||
.build();
|
|
||||||
if (message.received)
|
|
||||||
mChatView.receive(chatMessage);
|
|
||||||
else
|
|
||||||
mChatView.send(chatMessage);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//Click Send Button
|
|
||||||
mChatView.setOnClickSendButtonListener(view -> {
|
|
||||||
send(mChatView.getInputText());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -351,12 +45,10 @@ public class FeedbackActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
registerReceiver(receiver, new IntentFilter("pl.szczodrzynski.edziennik.ui.modules.base.FeedbackActivity"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
unregisterReceiver(receiver);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,333 +1,268 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.modules.feedback
|
package pl.szczodrzynski.edziennik.ui.modules.feedback
|
||||||
|
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.IntentFilter
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
|
import android.graphics.Canvas
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.AsyncTask
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.animation.Animation
|
|
||||||
import android.widget.PopupMenu
|
import android.widget.PopupMenu
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import coil.Coil
|
||||||
|
import coil.api.load
|
||||||
import com.github.bassaer.chatmessageview.model.IChatUser
|
import com.github.bassaer.chatmessageview.model.IChatUser
|
||||||
import com.github.bassaer.chatmessageview.model.Message
|
import com.github.bassaer.chatmessageview.model.Message
|
||||||
import com.github.bassaer.chatmessageview.view.ChatView
|
import com.github.bassaer.chatmessageview.view.ChatView
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.greenrobot.eventbus.Subscribe
|
||||||
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.FeedbackMessageEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
|
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
|
||||||
import pl.szczodrzynski.edziennik.databinding.FragmentFeedbackBinding
|
import pl.szczodrzynski.edziennik.databinding.FragmentFeedbackBinding
|
||||||
import pl.szczodrzynski.edziennik.network.ServerRequest
|
import pl.szczodrzynski.edziennik.onClick
|
||||||
import pl.szczodrzynski.edziennik.utils.Anim
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.crc16
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.openUrl
|
import pl.szczodrzynski.edziennik.utils.Utils.openUrl
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class FeedbackFragment : Fragment() {
|
class FeedbackFragment : Fragment(), CoroutineScope {
|
||||||
|
|
||||||
private lateinit var app: App
|
private lateinit var app: App
|
||||||
private lateinit var activity: MainActivity
|
private lateinit var activity: MainActivity
|
||||||
private lateinit var b: FragmentFeedbackBinding
|
private lateinit var b: FragmentFeedbackBinding
|
||||||
|
|
||||||
|
private val job: Job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
|
private val chatView: ChatView by lazy { b.chatView }
|
||||||
|
private val api by lazy { SzkolnyApi(app) }
|
||||||
|
private var isDev = false
|
||||||
|
private var currentDeviceId: String? = null
|
||||||
|
|
||||||
|
private var receiver: BroadcastReceiver? = null
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
activity = (getActivity() as MainActivity?) ?: return null
|
activity = (getActivity() as MainActivity?) ?: return null
|
||||||
if (context == null)
|
if (context == null)
|
||||||
return null
|
return null
|
||||||
app = activity.application as App
|
app = activity.application as App
|
||||||
context!!.theme.applyStyle(Themes.appTheme, true)
|
context!!.theme.applyStyle(Themes.appTheme, true)
|
||||||
if (app.profile == null)
|
|
||||||
return inflater.inflate(R.layout.fragment_loading, container, false)
|
|
||||||
// activity, context and profile is valid
|
// activity, context and profile is valid
|
||||||
b = FragmentFeedbackBinding.inflate(inflater)
|
b = FragmentFeedbackBinding.inflate(inflater)
|
||||||
return b.root
|
return b.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
// TODO check if app, activity, b can be null
|
fun onFeedbackMessageEvent(event: FeedbackMessageEvent) {
|
||||||
if (app.profile == null || !isAdded)
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
return
|
val message = event.message
|
||||||
|
val chatMessage = getChatMessage(message)
|
||||||
|
if (message.received) chatView.receive(chatMessage)
|
||||||
|
else chatView.send(chatMessage)
|
||||||
|
}
|
||||||
|
|
||||||
b.faqText.setOnClickListener { v -> openFaq() }
|
private val users = mutableMapOf(
|
||||||
b.faqButton.setOnClickListener { v -> openFaq() }
|
0 to User(0, "Ja", null)
|
||||||
|
)
|
||||||
|
private fun getUser(message: FeedbackMessage): User {
|
||||||
|
val userId = message.devId ?: if (message.received) 1 else 0
|
||||||
|
return users[userId] ?: run {
|
||||||
|
User(userId, message.senderName, message.devImage).also { users[userId] = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
receiver = object : BroadcastReceiver() {
|
private fun getChatMessage(message: FeedbackMessage): Message = Message.Builder()
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
.setUser(getUser(message))
|
||||||
val message = app.gson.fromJson(intent.getStringExtra("message"), FeedbackMessage::class.java)
|
|
||||||
val c = Calendar.getInstance()
|
|
||||||
c.timeInMillis = message.sentTime
|
|
||||||
val chatMessage = Message.Builder()
|
|
||||||
.setUser(
|
|
||||||
if (intent.getStringExtra("type") == "dev_chat")
|
|
||||||
User(crc16(message.fromUser.toByteArray()), message.fromUserName, BitmapFactory.decodeResource(resources, R.drawable.ic_account_circle))
|
|
||||||
else
|
|
||||||
dev)
|
|
||||||
.setRight(!message.received)
|
.setRight(!message.received)
|
||||||
.setText(message.text)
|
.setText(message.text)
|
||||||
.setSendTime(c)
|
.setSendTime(Calendar.getInstance().apply { timeInMillis = message.sentTime })
|
||||||
.hideIcon(!message.received)
|
.hideIcon(!message.received)
|
||||||
.build()
|
.build()
|
||||||
if (message.received)
|
|
||||||
mChatView.receive(chatMessage)
|
|
||||||
else
|
|
||||||
mChatView.send(chatMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set UI parameters if you need
|
private fun launchDeviceSelection() {
|
||||||
mChatView.setLeftBubbleColor(Utils.getAttr(activity, R.attr.colorSurface))
|
if (!isDev)
|
||||||
mChatView.setLeftMessageTextColor(Utils.getAttr(activity, android.R.attr.textColorPrimary))
|
return
|
||||||
mChatView.setRightBubbleColor(Utils.getAttr(activity, R.attr.colorPrimary))
|
launch {
|
||||||
mChatView.setRightMessageTextColor(Color.WHITE)
|
val messages = withContext(Dispatchers.Default) { app.db.feedbackMessageDao().allWithCountNow }
|
||||||
|
|
||||||
//mChatView.setBackgroundColor(ContextCompat.getColor(this, R.color.blueGray500));
|
|
||||||
mChatView.setSendButtonColor(Utils.getAttr(activity, R.attr.colorAccent))
|
|
||||||
mChatView.setSendIcon(R.drawable.ic_action_send)
|
|
||||||
//mChatView.setUsernameTextColor(Color.WHITE);
|
|
||||||
//mChatView.setSendTimeTextColor(Color.WHITE);
|
|
||||||
//mChatView.setDateSeparatorColor(Color.WHITE);
|
|
||||||
mChatView.setInputTextHint("Napisz...")
|
|
||||||
//mChatView.setInputTextColor(Color.BLACK);
|
|
||||||
mChatView.setMessageMarginTop(5)
|
|
||||||
mChatView.setMessageMarginBottom(5)
|
|
||||||
|
|
||||||
if (App.devMode && app.deviceId == "f054761fbdb6a238") {
|
|
||||||
b.targetDeviceLayout.visibility = View.VISIBLE
|
|
||||||
b.targetDeviceDropDown.setOnClickListener { v ->
|
|
||||||
AsyncTask.execute {
|
|
||||||
val messageList = app.db.feedbackMessageDao().allWithCountNow
|
|
||||||
activity.runOnUiThread {
|
|
||||||
val popupMenu = PopupMenu(activity, b.targetDeviceDropDown)
|
val popupMenu = PopupMenu(activity, b.targetDeviceDropDown)
|
||||||
var index = 0
|
messages.forEachIndexed { index, m ->
|
||||||
for (message in messageList) {
|
popupMenu.menu.add(0, index, index, "${m.senderName} ${m.deviceName} (${m.count})")
|
||||||
popupMenu.menu.add(0, index, index, message.fromUserName + " - " + message.fromUser + " (" + message.messageCount + ")")
|
|
||||||
index++
|
|
||||||
}
|
}
|
||||||
popupMenu.setOnMenuItemClickListener { item ->
|
popupMenu.setOnMenuItemClickListener { item ->
|
||||||
b.targetDeviceDropDown.setText(item.title)
|
b.targetDeviceDropDown.setText(item.title)
|
||||||
mChatView.getMessageView().removeAll()
|
chatView.getMessageView().removeAll()
|
||||||
val message = messageList[item.itemId]
|
val message = messages[item.itemId]
|
||||||
deviceToSend = message.fromUser
|
currentDeviceId = message.deviceId
|
||||||
nameToSend = message.fromUserName
|
this@FeedbackFragment.launch { loadMessages() }
|
||||||
AsyncTask.execute {
|
|
||||||
val messageList2 = app.db.feedbackMessageDao().getAllByUserNow(deviceToSend)
|
|
||||||
activity.runOnUiThread {
|
|
||||||
b.chatLayout.visibility = View.VISIBLE
|
|
||||||
b.inputLayout.visibility = View.GONE
|
|
||||||
for (message2 in messageList2) {
|
|
||||||
val c = Calendar.getInstance()
|
|
||||||
c.timeInMillis = message2.sentTime
|
|
||||||
val chatMessage = Message.Builder()
|
|
||||||
.setUser(if (message2.received) User(crc16(message2.fromUser.toByteArray()), message2.fromUserName, BitmapFactory.decodeResource(resources, R.drawable.ic_account_circle)) else user)
|
|
||||||
.setRight(!message2.received)
|
|
||||||
.setText(message2.text)
|
|
||||||
.setSendTime(c)
|
|
||||||
.hideIcon(!message2.received)
|
|
||||||
.build()
|
|
||||||
if (message2.received)
|
|
||||||
mChatView.receive(chatMessage)
|
|
||||||
else
|
|
||||||
mChatView.send(chatMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
popupMenu.show()
|
popupMenu.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun loadMessages(messageList: List<FeedbackMessage>? = null) {
|
||||||
|
/*if (messageList != null && messageList.isNotEmpty())
|
||||||
|
return*/
|
||||||
|
val messages = messageList ?: withContext(Dispatchers.Default) {
|
||||||
|
if (currentDeviceId == null)
|
||||||
|
app.db.feedbackMessageDao().allNow
|
||||||
|
else
|
||||||
|
app.db.feedbackMessageDao().getByDeviceIdNow(currentDeviceId!!)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
AsyncTask.execute {
|
if (messages.isNotEmpty()) {
|
||||||
val messageList = app.db.feedbackMessageDao().allNow
|
|
||||||
firstSend = messageList.size == 0
|
|
||||||
activity.runOnUiThread {
|
|
||||||
if (firstSend) {
|
|
||||||
openFaq()
|
|
||||||
b.chatLayout.visibility = View.GONE
|
|
||||||
b.inputLayout.visibility = View.VISIBLE
|
|
||||||
b.sendButton.setOnClickListener { v ->
|
|
||||||
if (b.textInput.text == null || b.textInput.text!!.length == 0) {
|
|
||||||
Toast.makeText(app, "Podaj treść wiadomości.", Toast.LENGTH_SHORT).show()
|
|
||||||
} else {
|
|
||||||
send(b.textInput.text!!.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*new MaterialDialog.Builder(this)
|
|
||||||
.title(R.string.faq)
|
|
||||||
.content(R.string.faq_text)
|
|
||||||
.positiveText(R.string.yes)
|
|
||||||
.negativeText(R.string.no)
|
|
||||||
.onPositive(((dialog, which) -> {
|
|
||||||
openFaq();
|
|
||||||
}))
|
|
||||||
.show();*/
|
|
||||||
b.chatLayout.visibility = View.VISIBLE
|
b.chatLayout.visibility = View.VISIBLE
|
||||||
b.inputLayout.visibility = View.GONE
|
b.inputLayout.visibility = View.GONE
|
||||||
}
|
}
|
||||||
for (message in messageList) {
|
|
||||||
val c = Calendar.getInstance()
|
messages.forEach {
|
||||||
c.timeInMillis = message.sentTime
|
val chatMessage = getChatMessage(it)
|
||||||
val chatMessage = Message.Builder()
|
if (it.received) chatView.receive(chatMessage)
|
||||||
.setUser(if (message.fromUser != null) User(crc16(message.fromUser.toByteArray()), message.fromUserName, BitmapFactory.decodeResource(resources, R.drawable.ic_account_circle)) else if (message.received) dev else user)
|
else chatView.send(chatMessage)
|
||||||
.setRight(!message.received)
|
|
||||||
.setText(message.text)
|
|
||||||
.setSendTime(c)
|
|
||||||
.hideIcon(!message.received)
|
|
||||||
.build()
|
|
||||||
if (message.received)
|
|
||||||
mChatView.receive(chatMessage)
|
|
||||||
else
|
|
||||||
mChatView.send(chatMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Click Send Button
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
mChatView.setOnClickSendButtonListener(View.OnClickListener { send(mChatView.inputText) })
|
// TODO check if app, activity, b can be null
|
||||||
|
if (!isAdded)
|
||||||
|
return
|
||||||
|
|
||||||
|
b.faqText.setOnClickListener { openFaq() }
|
||||||
|
b.faqButton.setOnClickListener { openFaq() }
|
||||||
|
|
||||||
|
with(chatView) {
|
||||||
|
setLeftBubbleColor(Utils.getAttr(activity, R.attr.colorSurface))
|
||||||
|
setLeftMessageTextColor(Utils.getAttr(activity, android.R.attr.textColorPrimary))
|
||||||
|
setRightBubbleColor(Utils.getAttr(activity, R.attr.colorPrimary))
|
||||||
|
setRightMessageTextColor(Color.WHITE)
|
||||||
|
setSendButtonColor(Utils.getAttr(activity, R.attr.colorAccent))
|
||||||
|
setSendIcon(R.drawable.ic_action_send)
|
||||||
|
setInputTextHint("Napisz...")
|
||||||
|
setMessageMarginTop(5)
|
||||||
|
setMessageMarginBottom(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var firstSend = true
|
launch {
|
||||||
private var deviceToSend: String? = null
|
val messages = withContext(Dispatchers.Default) {
|
||||||
private var nameToSend: String? = null
|
val messages = app.db.feedbackMessageDao().allNow
|
||||||
|
isDev = App.devMode && messages.any { it.deviceId != null }
|
||||||
private var receiver: BroadcastReceiver? = null
|
messages
|
||||||
|
|
||||||
class User(internal var id: Int?, internal var name: String, internal var icon: Bitmap) : IChatUser {
|
|
||||||
|
|
||||||
override fun getId(): String {
|
|
||||||
return this.id!!.toString()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(): String? {
|
b.targetDeviceLayout.visibility = if (isDev) View.VISIBLE else View.GONE
|
||||||
return this.name
|
b.targetDeviceDropDown.onClick {
|
||||||
|
launchDeviceSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIcon(): Bitmap? {
|
if (isDev) {
|
||||||
return this.icon
|
messages.firstOrNull()?.let {
|
||||||
|
currentDeviceId = it.deviceId
|
||||||
|
b.targetDeviceDropDown.setText("${it.senderName} ${it.deviceName}")
|
||||||
}
|
}
|
||||||
|
b.chatLayout.visibility = View.VISIBLE
|
||||||
override fun setIcon(icon: Bitmap) {
|
|
||||||
this.icon = icon
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val dev: User by lazy {
|
|
||||||
User(0, "Szkolny.eu", BitmapFactory.decodeResource(activity.resources, R.mipmap.ic_splash))
|
|
||||||
}
|
|
||||||
private val user: User by lazy {
|
|
||||||
User(1, "Ja", BitmapFactory.decodeResource(activity.resources, R.drawable.profile_))
|
|
||||||
}
|
|
||||||
private val mChatView: ChatView by lazy {
|
|
||||||
b.chatView
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun send(text: String) {
|
|
||||||
/*if ("enable dev mode pls".equals(text)) {
|
|
||||||
try {
|
|
||||||
Log.d(TAG, Utils.AESCrypt.encrypt("ok here you go it's enabled now", "8iryqZUfIUiLmJGi"));
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
val progressDialog = MaterialDialog.Builder(activity)
|
|
||||||
.title(R.string.loading)
|
|
||||||
.content(R.string.sending_message)
|
|
||||||
.negativeText(R.string.cancel)
|
|
||||||
.show()
|
|
||||||
ServerRequest(app, "https://edziennik.szczodrzynski.pl/app/main.php?feedback_message", "FeedbackSend")
|
|
||||||
.setBodyParameter("message_text", text)
|
|
||||||
.setBodyParameter("target_device", if (deviceToSend == null) "null" else deviceToSend)
|
|
||||||
.run { e, result ->
|
|
||||||
progressDialog.dismiss()
|
|
||||||
if (result != null && result.get("success") != null && result.get("success").asBoolean) {
|
|
||||||
val feedbackMessage = FeedbackMessage(false, text)
|
|
||||||
if (deviceToSend != null) {
|
|
||||||
feedbackMessage.fromUser = deviceToSend
|
|
||||||
feedbackMessage.fromUserName = nameToSend
|
|
||||||
}
|
|
||||||
AsyncTask.execute { app.db.feedbackMessageDao().add(feedbackMessage) }
|
|
||||||
var message = Message.Builder()
|
|
||||||
.setUser(user!!)
|
|
||||||
.setRight(true)
|
|
||||||
.setText(feedbackMessage.text)
|
|
||||||
.hideIcon(true)
|
|
||||||
.build()
|
|
||||||
mChatView!!.send(message)
|
|
||||||
mChatView!!.inputText = ""
|
|
||||||
b.textInput.setText("")
|
|
||||||
if (firstSend) {
|
|
||||||
Anim.fadeOut(b.inputLayout, 500, object : Animation.AnimationListener {
|
|
||||||
override fun onAnimationStart(animation: Animation) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAnimationEnd(animation: Animation) {
|
|
||||||
b.inputLayout.visibility = View.GONE
|
b.inputLayout.visibility = View.GONE
|
||||||
Anim.fadeIn(b.chatLayout, 500, null)
|
}
|
||||||
|
else if (messages.isEmpty()) {
|
||||||
|
b.chatLayout.visibility = View.GONE
|
||||||
|
b.inputLayout.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAnimationRepeat(animation: Animation) {
|
loadMessages(messages)
|
||||||
|
|
||||||
|
b.sendButton.onClick {
|
||||||
|
send(b.textInput.text.toString())
|
||||||
}
|
}
|
||||||
|
chatView.setOnClickSendButtonListener(View.OnClickListener {
|
||||||
|
send(chatView.inputText)
|
||||||
})
|
})
|
||||||
if (deviceToSend == null) {
|
|
||||||
// we are not the developer
|
|
||||||
val feedbackMessage2 = FeedbackMessage(true, "Postaram się jak najszybciej Tobie odpowiedzieć. Dostaniesz powiadomienie o odpowiedzi, która pokaże się w tym miejscu.")
|
|
||||||
AsyncTask.execute { app.db.feedbackMessageDao().add(feedbackMessage2) }
|
|
||||||
message = Message.Builder()
|
|
||||||
.setUser(dev!!)
|
|
||||||
.setRight(false)
|
|
||||||
.setText(feedbackMessage2.text)
|
|
||||||
.hideIcon(false)
|
|
||||||
.build()
|
|
||||||
mChatView!!.receive(message)
|
|
||||||
}
|
}
|
||||||
firstSend = false
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
inner class User(val id: Int, val userName: String, val image: String?) : IChatUser {
|
||||||
|
override fun getIcon(): Bitmap? {
|
||||||
|
if (image == null)
|
||||||
|
return BitmapFactory.decodeResource(activity.resources, R.drawable.profile_)
|
||||||
|
return Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888).also { bmp ->
|
||||||
|
launch {
|
||||||
|
Coil.load(activity, image) {
|
||||||
|
target {
|
||||||
|
val canvas = Canvas(bmp)
|
||||||
|
it.setBounds(0, 0, bmp.width, bmp.height)
|
||||||
|
it.draw(canvas)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getId() = id.toString()
|
||||||
|
override fun getName() = userName
|
||||||
|
override fun setIcon(bmp: Bitmap) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun send(text: String?) {
|
||||||
|
if (text?.isEmpty() != false) {
|
||||||
|
Toast.makeText(activity, "Podaj treść wiadomości.", Toast.LENGTH_SHORT).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDev && currentDeviceId == null || currentDeviceId == "szkolny.eu") {
|
||||||
|
Toast.makeText(activity, "Wybierz urządzenie docelowe.", Toast.LENGTH_SHORT).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
launch {
|
||||||
|
val message = withContext(Dispatchers.Default) {
|
||||||
|
try {
|
||||||
|
api.sendFeedbackMessage(
|
||||||
|
senderName = App.profile.accountName ?: App.profile.studentNameLong,
|
||||||
|
targetDeviceId = if (isDev) currentDeviceId else null,
|
||||||
|
text = text
|
||||||
|
)?.also {
|
||||||
|
app.db.feedbackMessageDao().add(it)
|
||||||
|
}
|
||||||
|
} catch (ignore: Exception) { null }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message == null) {
|
||||||
Toast.makeText(app, "Nie udało się wysłać wiadomości.", Toast.LENGTH_SHORT).show()
|
Toast.makeText(app, "Nie udało się wysłać wiadomości.", Toast.LENGTH_SHORT).show()
|
||||||
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b.chatLayout.visibility = View.VISIBLE
|
||||||
|
b.inputLayout.visibility = View.GONE
|
||||||
|
|
||||||
|
b.textInput.text = null
|
||||||
|
b.chatView.inputText = ""
|
||||||
|
|
||||||
|
val chatMessage = getChatMessage(message)
|
||||||
|
if (message.received) chatView.receive(chatMessage)
|
||||||
|
else chatView.send(chatMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openFaq() {
|
private fun openFaq() {
|
||||||
openUrl(activity, "http://szkolny.eu/pomoc/")
|
openUrl(activity, "http://szkolny.eu/pomoc/")
|
||||||
MaterialDialog.Builder(activity)
|
|
||||||
.title(R.string.faq_back_title)
|
|
||||||
.content(R.string.faq_back_text)
|
|
||||||
.positiveText(R.string.yes)
|
|
||||||
.negativeText(R.string.no)
|
|
||||||
.onPositive { dialog, which ->
|
|
||||||
|
|
||||||
}
|
|
||||||
.onNegative { dialog, which ->
|
|
||||||
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
if (receiver != null)
|
EventBus.getDefault().register(this)
|
||||||
activity.registerReceiver(receiver, IntentFilter("pl.szczodrzynski.edziennik.ui.modules.base.FeedbackActivity"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
if (receiver != null)
|
EventBus.getDefault().unregister(this)
|
||||||
activity.unregisterReceiver(receiver)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user