Improve reviews list and add Russian localization

Thanks to an anonymous contributor
This commit is contained in:
xynngh 2019-07-20 21:46:24 +04:00
parent 8143913753
commit e1cc5b46d1
13 changed files with 314 additions and 46 deletions

View File

@ -93,10 +93,16 @@ git clone https://gitlab.com/xynngh/YetAnotherCallBlocker_data
Sym-link the assets:
Linux
```
cd YetAnotherCallBlocker/app/src/main/assets/
ln -s ../../../../../YetAnotherCallBlocker_data/assets/sia .
```
Windows
```
cd YetAnotherCallBlocker\app\src\main\assets
mklink /d sia ..\..\..\..\..\YetAnotherCallBlocker_data\assets\sia
```
**or** copy the whole directory `YetAnotherCallBlocker_data/assets/sia` into `YetAnotherCallBlocker/app/src/main/assets/`.

View File

@ -19,6 +19,9 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
disable 'MissingTranslation'
}
}
dependencies {

View File

@ -0,0 +1,95 @@
package dummydomain.yetanothercallblocker;
import android.content.res.ColorStateList;
import android.support.annotation.NonNull;
import android.support.v4.widget.ImageViewCompat;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.Collections;
import java.util.List;
import dummydomain.yetanothercallblocker.sia.model.CommunityReview;
import dummydomain.yetanothercallblocker.sia.model.NumberRating;
class CustomListViewAdapter extends RecyclerView.Adapter<CustomListViewAdapter.CommunityReviewViewHolder> {
private List<CommunityReview> reviewsList = Collections.emptyList();
public void setItems(List<CommunityReview> reviewsList) {
this.reviewsList = reviewsList;
}
@NonNull
@Override
public CommunityReviewViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.review_item, viewGroup, false);
return new CommunityReviewViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull CommunityReviewViewHolder viewHolder, int i) {
viewHolder.bind(reviewsList.get(i));
}
@Override
public int getItemCount() {
return reviewsList.size();
}
class CommunityReviewViewHolder extends RecyclerView.ViewHolder {
AppCompatImageView ivRating;
TextView tvNumberCategory, tvTitle, tvDescription;
public CommunityReviewViewHolder(@NonNull View itemView) {
super(itemView);
ivRating = itemView.findViewById(R.id.rating_icon);
tvNumberCategory = itemView.findViewById(R.id.number_category);
tvTitle = itemView.findViewById(R.id.review_title);
tvDescription = itemView.findViewById(R.id.review_comment);
}
public void bind(CommunityReview item) {
tvNumberCategory.setText(item.getCategory().getStringId());
String title = item.getTitle();
if (TextUtils.isEmpty(title)) {
tvTitle.setVisibility(View.GONE);
} else {
tvTitle.setText(title);
tvTitle.setVisibility(View.VISIBLE);
}
String comment = item.getComment();
if (TextUtils.isEmpty(comment)) {
tvDescription.setVisibility(View.GONE);
} else {
tvDescription.setText(comment);
tvDescription.setVisibility(View.VISIBLE);
}
IconAndColor iconAndColor = getRatingIconData(item.getRating());
ivRating.setImageResource(iconAndColor.getIconResId());
ImageViewCompat.setImageTintList(ivRating, ColorStateList.valueOf(
itemView.getContext().getResources().getColor(iconAndColor.getColorResId())));
}
protected IconAndColor getRatingIconData(NumberRating rating) {
switch (rating) {
case NEUTRAL:
case UNKNOWN:
return IconAndColor.of(R.drawable.ic_thumbs_up_down_black_24dp, R.color.rateNeutral);
case POSITIVE:
return IconAndColor.of(R.drawable.ic_thumb_up_black_24dp, R.color.ratePositive);
case NEGATIVE:
return IconAndColor.of(R.drawable.ic_thumb_down_black_24dp, R.color.rateNegative);
}
return IconAndColor.of(R.drawable.ic_thumbs_up_down_black_24dp, R.color.notFound);
}
}
}

View File

@ -0,0 +1,23 @@
package dummydomain.yetanothercallblocker;
class IconAndColor {
private int iconResId;
private int colorResId;
public IconAndColor(int icon, int color) {
this.iconResId = icon;
this.colorResId = color;
}
static IconAndColor of(int icon, int color) {
return new IconAndColor(icon, color);
}
public int getIconResId() {
return iconResId;
}
public int getColorResId() {
return colorResId;
}
}

View File

@ -5,18 +5,23 @@ import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.TextView;
import java.util.List;
import dummydomain.yetanothercallblocker.sia.model.CommunityReview;
import dummydomain.yetanothercallblocker.sia.model.CommunityReviewsLoader;
import dummydomain.yetanothercallblocker.sia.model.NumberCategory;
public class ReviewsActivity extends AppCompatActivity {
private static final String PARAM_NUMBER = "param_number";
private CustomListViewAdapter listViewAdapter;
private RecyclerView reviewsList;
public static Intent getNumberIntent(Context context, String number) {
Intent intent = new Intent(context, ReviewsActivity.class);
intent.putExtra(PARAM_NUMBER, number);
@ -35,7 +40,13 @@ public class ReviewsActivity extends AppCompatActivity {
final String paramNumber = getIntent().getStringExtra(PARAM_NUMBER);
setText("Loading");
setText(getString(R.string.reviews_loading, paramNumber));
listViewAdapter = new CustomListViewAdapter();
reviewsList = findViewById(R.id.reviews_list);
reviewsList.setLayoutManager(new LinearLayoutManager(this));
reviewsList.setAdapter(listViewAdapter);
reviewsList.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
new AsyncTask<Void, Void, List<CommunityReview>>() {
@Override
@ -45,33 +56,19 @@ public class ReviewsActivity extends AppCompatActivity {
@Override
protected void onPostExecute(List<CommunityReview> reviews) {
setText(reviewsToString(ReviewsActivity.this, reviews));
setText(paramNumber);
handleReviews(reviews);
}
}.execute();
}
private void setText(String mainPart) {
TextView textView = findViewById(R.id.text_view);
textView.setText(getHeader() + "\n\n" + mainPart);
private void setText(String text) {
this.<TextView>findViewById(R.id.text_view).setText(text);
}
private String getHeader() {
return "Reviews for " + getIntent().getStringExtra(PARAM_NUMBER);
}
private static String reviewsToString(Context context, List<CommunityReview> reviews) {
StringBuilder sb = new StringBuilder();
for (CommunityReview review : reviews) {
sb.append(review.getAuthor()).append('\n');
sb.append(review.getRating()).append('\n');
sb.append(NumberCategory.getString(context, review.getCategory())).append('\n');
sb.append(review.getTitle()).append('\n');
sb.append(review.getComment()).append('\n');
sb.append('\n');
}
return sb.toString();
private void handleReviews(List<CommunityReview> reviews) {
listViewAdapter.setItems(reviews);
listViewAdapter.notifyDataSetChanged();
}
}

View File

@ -1,5 +1,7 @@
package dummydomain.yetanothercallblocker.sia.model.database;
import android.annotation.SuppressLint;
import android.support.annotation.Nullable;
import android.util.SparseArray;
import org.slf4j.Logger;
@ -39,6 +41,7 @@ public class CommunityDatabase extends AbstractDatabase<CommunityDatabaseDataSli
private SparseArray<CommunityDatabaseDataSlice> secondarySliceCache = new SparseArray<>();
@SuppressLint("UseSparseArrays") // uses null as a special value
private SparseArray<Boolean> existingSecondarySliceFiles = new SparseArray<>();
public int getEffectiveDbVersion() {
@ -153,7 +156,7 @@ public class CommunityDatabase extends AbstractDatabase<CommunityDatabaseDataSli
return communityDatabaseDataSlice;
}
private String getCachedSecondarySliceFilePath(int id) {
@Nullable private String getCachedSecondarySliceFilePath(int id) {
String path = getSecondarySliceFilePath(id);
Boolean exists = existingSecondarySliceFiles.get(id, null);
if (exists == null) {

View File

@ -1,27 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/text_margin"
android:orientation="vertical"
tools:context=".MainActivity">
<android.support.v7.widget.SwitchCompat
android:id="@+id/notificationsEnabledSwitch"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/incoming_call_notifications_enabled" />
android:layout_gravity="start"
android:layout_marginStart="@dimen/text_margin"
android:layout_marginLeft="@dimen/text_margin"
android:paddingTop="@dimen/item_padding"
android:text="@string/general_settings"
android:textAlignment="textStart" />
<android.support.v7.widget.SwitchCompat
android:id="@+id/blockCallsSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/block_calls" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="?android:listDivider"
android:orientation="vertical"
android:paddingLeft="@dimen/item_padding"
android:paddingRight="@dimen/item_padding"
android:showDividers="middle">
<android.support.v7.widget.SwitchCompat
android:id="@+id/autoUpdateEnabledSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/auto_update_enabled" />
<android.support.v7.widget.SwitchCompat
android:id="@+id/notificationsEnabledSwitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginBottom="@dimen/text_margin"
android:text="@string/incoming_call_notifications_enabled" />
<android.support.v7.widget.SwitchCompat
android:id="@+id/blockCallsSwitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginBottom="@dimen/text_margin"
android:text="@string/block_calls" />
<android.support.v7.widget.SwitchCompat
android:id="@+id/autoUpdateEnabledSwitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginBottom="@dimen/text_margin"
android:text="@string/auto_update_enabled" />
</LinearLayout>
</LinearLayout>

View File

@ -8,11 +8,23 @@
tools:context=".ReviewsActivity"
tools:showIn="@layout/activity_reviews">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:text="" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_margin="@dimen/text_margin"
android:text=""
tools:text="@string/debug_default_test_number"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/reviews_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tool="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.v7.widget.AppCompatImageView
android:id="@+id/rating_icon"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="top|center_horizontal"
android:layout_marginTop="6dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:tint="@color/rateNeutral"
android:src="@drawable/ic_thumbs_up_down_black_24dp"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:layout_marginRight="6dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/number_category"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textSize="16sp"
android:textStyle="bold"
tool:text="Category"/>
<TextView
android:id="@+id/review_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
tool:text="Title"/>
<TextView
android:id="@+id/review_comment"
android:layout_width="wrap_content"
android:layout_height="match_parent"
tool:text="Comment"/>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Yet Another Call Blocker</string>
<string name="notification_channel_group_name_incoming_calls">Входящие вызовы</string>
<string name="notification_channel_name_neutral">С нейтральной оценкой</string>
<string name="notification_channel_name_unknown">Неизвестные (без оценки)</string>
<string name="notification_channel_name_negative">С плохой оценкой</string>
<string name="sia_category_telemarketer">Товары/маркетинг</string>
<string name="notification_channel_group_name_blocked_calls">Заблокированные вызовы</string>
<string name="sia_category_dept_collector">Сбор задолженностей</string>
<string name="sia_category_silent">Немой вызов</string>
<string name="sia_category_call_center">Call-центр</string>
<string name="sia_category_political">Политика</string>
<string name="sia_category_prank">Хулиганство</string>
<string name="sia_category_survey">Опрос</string>
<string name="sia_category_other">Другое</string>
<string name="sia_category_scam">Развод/мошенники</string>
<string name="sia_category_financial_service">Финансовые услуги</string>
<string name="sia_category_company">Компания</string>
<string name="sia_category_service">Сервис/услуги</string>
<string name="sia_category_robocall">Робот/автомат</string>
<string name="sia_category_nonprofit">Некоммерческая орг</string>
<string name="block_calls">Блокировать нежелательные вызовы</string>
<string name="auto_update_enabled">Авто-обновление баз номеров</string>
<string name="open_debug_activity">Открыть экран отладки</string>
<string name="debug_activity_label">Отладка</string>
<string name="debug_query_db">Искать в общей базе</string>
<string name="debug_query_featured_db">Искать в базе организаций</string>
<string name="debug_load_reviews">Показать online-отзывы</string>
<string name="debug_update_db">Обновить базы</string>
<string name="debug_not_found">Не найдено</string>
<string name="debug_update_result">Обновление завершено. Версия: %d</string>
<string name="incoming_call_notifications_enabled">Отображать уведомление при входящих</string>
<string name="title_activity_reviews">Отзывы</string>
<string name="reviews_loading">%s загрузка…</string>
<string name="general_settings">Основные настройки</string>
<string name="sia_category_fax">Факс</string>
<string name="sia_category_nuisance">Злонамеренный</string>
<string name="sia_category_unsolicited">Нежелательный</string>
<string name="notification_incoming_call_text_description">Отриц. %d, положит. %d, нейтр. %d</string>
<string name="sia_category_none">Без категории</string>
<string name="notification_incoming_call_unknown">Отзывов нет</string>
<string name="notification_incoming_call_neutral">Нейтрально</string>
<string name="notification_incoming_call_negative">Плохие отзывы</string>
<string name="notification_blocked_call">Блокировано</string>
<string name="notification_channel_name_positive">С хорошей оценкой</string>
<string name="notification_channel_name_blocked_info">Показать причину блокировки</string>
<string name="notification_channel_name_positive_known">Из моего списка контактов</string>
<string name="notification_incoming_call_positive">Одобрено</string>
</resources>

View File

@ -3,4 +3,10 @@
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
<color name="ratePositive">#1b5e1f</color>
<color name="rateNeutral">#ffb300</color>
<color name="rateNegative">#ff0000</color>
<color name="rateUnknown">#999999</color>
<color name="notFound">#999999</color>
</resources>

View File

@ -1,4 +1,5 @@
<resources>
<dimen name="app_bar_height">180dp</dimen>
<dimen name="text_margin">16dp</dimen>
<dimen name="item_padding">16dp</dimen>
</resources>

View File

@ -44,6 +44,9 @@
<string name="sia_category_safe_nonprofit">Safe nonprofit</string>
<string name="title_activity_reviews">Reviews</string>
<string name="reviews_loading">%s loading…</string>
<string name="general_settings">General settings</string>
<string name="incoming_call_notifications_enabled">Incoming call notifications enabled</string>
<string name="block_calls">Block unwanted calls</string>
@ -54,7 +57,7 @@
<string name="debug_query_db">Query DB</string>
<string name="debug_query_featured_db">Query featured DB</string>
<string name="debug_load_reviews">Load reviews (online)</string>
<string name="debug_default_test_number">74995861192</string>
<string name="debug_default_test_number" translatable="false">74995861192</string>
<string name="debug_update_db">Manually update DB</string>
<string name="debug_not_found">Not found</string>
<string name="debug_update_result">Update finished; DB ver: %d</string>