diff --git a/.idea/misc.xml b/.idea/misc.xml index b0c7b20..dc44dda 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -29,7 +29,7 @@ - + diff --git a/app/release/release/fmtBeta0.9.5v18.aab b/app/release/release/fmtBeta0.9.5v18.aab new file mode 100644 index 0000000..fb0edf9 Binary files /dev/null and b/app/release/release/fmtBeta0.9.5v18.aab differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0203712..da2d313 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,10 +27,10 @@ tools:ignore="AllowBackup,GoogleAppIndexingWarning"> + android:theme="@style/AppTheme.NoActionBar"> @@ -40,20 +40,21 @@ + android:screenOrientation="portrait" /> + android:screenOrientation="portrait" /> + android:configChanges="keyboardHidden|orientation|screenSize" + android:screenOrientation="portrait" /> + + android:theme="@style/AppTheme" /> + \ No newline at end of file diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java index 3a5956e..c7935ba 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/BaseActivity.java @@ -102,8 +102,8 @@ public abstract class BaseActivity /* launchIntent = new Intent(getApplicationContext(), WhitelistActivity.class); startActivity(launchIntent);*/ } else if (itemName.equals(getResources().getString(R.string.navigation_item_blacklist))) { - /* launchIntent = new Intent(getApplicationContext(), BlacklistActivity.class); - startActivity(launchIntent);*/ + launchIntent = new Intent(getApplicationContext(),BlackList.class); + startActivity(launchIntent); } else if (itemName.equals(getResources().getString(R.string.navigation_item_profile))) { diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/BlackList.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/BlackList.java new file mode 100644 index 0000000..c9faef8 --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/BlackList.java @@ -0,0 +1,335 @@ +package com.uam.wmi.findmytutor.activity; + +import android.annotation.SuppressLint; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.support.design.widget.CoordinatorLayout; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.text.TextUtils; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.PopupWindow; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; +import android.widget.ToggleButton; + +import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; +import com.mapbox.geojson.Point; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.uam.wmi.findmytutor.R; +import com.uam.wmi.findmytutor.adapters.BlackListAdapter; +import com.uam.wmi.findmytutor.model.IsUsingListBool; +import com.uam.wmi.findmytutor.model.PredefinedCoordViewModel; +import com.uam.wmi.findmytutor.model.StudentIdModel; +import com.uam.wmi.findmytutor.model.User; +import com.uam.wmi.findmytutor.model.UserResponseModel; +import com.uam.wmi.findmytutor.network.ApiClient; +import com.uam.wmi.findmytutor.service.PredefinedStatusesService; +import com.uam.wmi.findmytutor.service.UserService; +import com.uam.wmi.findmytutor.utils.MyDividerItemDecoration; +import com.uam.wmi.findmytutor.utils.PrefUtils; +import com.uam.wmi.findmytutor.utils.RecyclerTouchListener; +import com.uam.wmi.findmytutor.utils.RestApiHelper; +import com.uam.wmi.findmytutor.utils.SharingLevel; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.observers.DisposableSingleObserver; +import io.reactivex.schedulers.Schedulers; +import okhttp3.ResponseBody; + +public class BlackList extends AppCompatActivity { + + private CompositeDisposable disposable = new CompositeDisposable(); + private UserService userService; + private boolean didFetched = false; + private String tutorId; + + @BindView(R.id.recycler_view) + RecyclerView recyclerView; + @BindView(R.id.black_list_empty_text_view) + TextView noNotesView; + @BindView(R.id.switch_blacklist_toggle) + Switch aSwitch; + @BindView(R.id.add_to_black_list_fab) + FloatingActionButton addToBlackListFab; + + private BlackListAdapter mAdapter; + private List blacklistedUsers = new ArrayList<>(); + private HashSet blacklistedUsersIDs = new HashSet<>(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + setContentView(R.layout.activity_black_list); + ButterKnife.bind(this); + aSwitch.setText(getString(R.string.blacklist) +" ON"); + tutorId = PrefUtils.getUserId(getApplicationContext()); + + Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setTitle(getString(R.string.activity_title_blacklist)); + setSupportActionBar(toolbar); + + userService = ApiClient.getClient(getApplicationContext()) + .create(UserService.class); + + mAdapter = new BlackListAdapter(this, blacklistedUsers); + RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext()); + recyclerView.setLayoutManager(mLayoutManager); + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL, 16)); + recyclerView.setAdapter(mAdapter); + + /** + * On long press on RecyclerView item, open alert dialog + * with options to choose + * Edit and Delete + * */ + recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this, + recyclerView, new RecyclerTouchListener.ClickListener() { + @Override + public void onClick(View view, final int position) { + } + + @Override + public void onLongClick(View view, int position) { + } + })); + + addToBlackListFab.setOnClickListener(this::showFabDialog); + + fetchBlackListedUsersIDs(PrefUtils.getUserId(getApplicationContext())); + handleSwitch(); + } + + private void fetchBlackListedUsersIDs(String userId) { + disposable.add( + userService.getTutorBlacklistedByID(userId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeWith(new DisposableSingleObserver>() { + @Override + public void onSuccess(List users) { + blacklistedUsersIDs.addAll(users); + didFetched = true; + fetchBlackListedUsers(); + toggleEmptyNotes(); + } + + @Override + public void onError(Throwable e) { + showError(e); + } + }) + ); + } + + private void fetchBlackListedUsers() { + for (String GUID : blacklistedUsersIDs){ + disposable.add( + userService.getUserById(GUID) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeWith(new DisposableSingleObserver() { + @Override + public void onSuccess(User user) { + blacklistedUsers.add(user); + Snackbar.make(getWindow().getDecorView().getRootView(), "user fetch OK! success", Snackbar.LENGTH_LONG) + .setAction("Action", null).show(); + toggleEmptyNotes(); + if (blacklistedUsers.size() == blacklistedUsersIDs.size()) { + mAdapter.notifyDataSetChanged(); + } + } + + @Override + public void onError(Throwable e) { + showError(e); + } + }) + ); + } + } + + + private void showFabDialog(View v){ + LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext()); + @SuppressLint("InflateParams") View view = layoutInflaterAndroid.inflate(R.layout.black_list_fab_modal, null); + AlertDialog.Builder alertDialogBuilderUserInput = new android.support.v7.app.AlertDialog.Builder(this); + + alertDialogBuilderUserInput.setView(view).setPositiveButton(getApplicationContext().getString(R.string.modal_location_send), null); + + alertDialogBuilderUserInput + .setPositiveButton(R.string.add, null) + .setNegativeButton(R.string.cancel, null); + + final AlertDialog alertDialog = alertDialogBuilderUserInput.create(); + alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + + EditText modalUserInput = view.findViewById(R.id.black_list_modal_input); + + alertDialog.setOnShowListener(dialogInterface -> { + Button sendButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); + + Button dismissButton = alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE); + + dismissButton.setOnClickListener(view1 -> alertDialog.dismiss()); + + sendButton.setOnClickListener(view1 -> { + String body = modalUserInput.getText().toString(); + + if (TextUtils.isEmpty(body)) { + Toast.makeText(getApplicationContext(), R.string.can_not_be_empty, Toast.LENGTH_SHORT).show(); + modalUserInput.requestFocus(); + } else { + sendUserToBlacklist(body); + alertDialog.dismiss(); + } + }); + }); + + alertDialog.show(); + } + + private void sendUserToBlacklist(String body) { + StudentIdModel studentIdModel = new StudentIdModel(body); + disposable.add( + userService.addStudentToBlacklist(PrefUtils.getUserId(getApplicationContext()), studentIdModel) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(()->{ + fetchBlackListedUsersIDs(PrefUtils.getUserId(getApplicationContext())); + Toast.makeText(getApplicationContext(), R.string.user_added, Toast.LENGTH_SHORT).show(); + },this::showError) + ); + } + + private void showError(Throwable e) { + String message; + + if (e instanceof HttpException) { + ResponseBody responseBody = ((HttpException) e).response().errorBody(); + message = RestApiHelper.getErrorMessage(responseBody); + } else { + message = "Network Error !"; + } + Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show(); + + + Snackbar.make(getWindow().getDecorView().getRootView(), message, Snackbar.LENGTH_LONG) + .setAction("Action", null).show(); + } + + private void toggleEmptyNotes() { + + if (didFetched && blacklistedUsers.size() == 0) { + noNotesView.setText(R.string.list_is_empty); + noNotesView.setVisibility(View.VISIBLE); + }else if (blacklistedUsers.size() > 0) { + noNotesView.setVisibility(View.GONE); + } else { + noNotesView.setText(getString(R.string.loading)); + noNotesView.setVisibility(View.VISIBLE); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + disposable.dispose(); + } + + @Override + public void onResume() { + super.onResume(); + } + + @Override + public void onPause() { + super.onPause(); + } + + @Override + public void onStop() { + super.onStop(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_black_list, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + if (item.getItemId()==R.id.action_blacklist_info_popup){ + int layoutID = R.layout.info_popup_blacklist; + + View popupView = getLayoutInflater().inflate(layoutID,null); + + PopupWindow popupWindow = new PopupWindow(popupView, + LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); + // If the PopupWindow should be focusable + popupWindow.setFocusable(true); + // If you need the PopupWindow to dismiss when when touched outside + popupWindow.setBackgroundDrawable(new ColorDrawable()); + // Get the View's(the one that was clicked in the Fragment) location + View anchorView= getWindow().getDecorView().findViewById(android.R.id.content); + popupWindow.showAtLocation(anchorView,Gravity.TOP|Gravity.END, 0, 0); + } + + return super.onOptionsItemSelected(item); + } + + private void handleSwitch(){ + aSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (isChecked){ + aSwitch.setText(getString(R.string.blacklist) + " "+ getString(R.string.on)); + handleChangeRequest(true); + }else { + aSwitch.setText(getString(R.string.blacklist) + " "+getString(R.string.off)); + handleChangeRequest(false); + } + }); + } + + private void handleChangeRequest(boolean value){ + IsUsingListBool isUsingListBool = new IsUsingListBool(); + isUsingListBool.setIsUsing(value); + disposable.add( + userService.setTutorBlacklist(tutorId, isUsingListBool) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(()->{ + },this::showError) + ); + } +} diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/SpecialList.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/SpecialList.java new file mode 100644 index 0000000..ec12a92 --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/SpecialList.java @@ -0,0 +1,19 @@ +package com.uam.wmi.findmytutor.activity; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; + +import com.uam.wmi.findmytutor.R; + +public abstract class SpecialList extends AppCompatActivity { + @Override + protected void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + setContentView(getContentViewId()); + + } + + abstract int getContentViewId(); + + +} diff --git a/app/src/main/java/com/uam/wmi/findmytutor/adapters/BlackListAdapter.java b/app/src/main/java/com/uam/wmi/findmytutor/adapters/BlackListAdapter.java new file mode 100644 index 0000000..3fd9043 --- /dev/null +++ b/app/src/main/java/com/uam/wmi/findmytutor/adapters/BlackListAdapter.java @@ -0,0 +1,134 @@ +package com.uam.wmi.findmytutor.adapters; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.support.annotation.NonNull; +import android.support.design.widget.Snackbar; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.TextView; +import android.widget.Toast; + +import com.jakewharton.retrofit2.adapter.rxjava2.HttpException; +import com.uam.wmi.findmytutor.R; +import com.uam.wmi.findmytutor.model.StudentIdModel; +import com.uam.wmi.findmytutor.model.User; +import com.uam.wmi.findmytutor.network.ApiClient; +import com.uam.wmi.findmytutor.service.UserService; +import com.uam.wmi.findmytutor.utils.PrefUtils; +import com.uam.wmi.findmytutor.utils.RestApiHelper; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.schedulers.Schedulers; +import okhttp3.ResponseBody; + +import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext; + + +public class BlackListAdapter extends RecyclerView.Adapter { + + private Context context; + private List tutorsList; + private CompositeDisposable disposable = new CompositeDisposable(); + private UserService userService; + + + public BlackListAdapter(Context context, List tutors) { + this.context = context; + this.tutorsList = tutors; + } + @NonNull + @Override + public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + userService = ApiClient.getClient(getApplicationContext()) + .create(UserService.class); + View itemView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.black_list_row, parent, false); + + return new MyViewHolder(itemView); + } + + @Override + public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { + Drawable image = null; + User tutor = tutorsList.get(position); + + holder.firstName.setText(tutor.getFirstName() + " " + tutor.getLastName()); + holder.lastName.setText("Index: " + tutor.getLdapLogin() + " Email: " + tutor.getEmail()); +//"s416196" + holder.imageButton.setOnClickListener(l ->{ + StudentIdModel studentIdModel = new StudentIdModel(tutor.getLdapLogin()); + String tutorId = PrefUtils.getUserId(getApplicationContext()); + disposable.add( + userService.removeStudentFromBlacklist(tutorId, studentIdModel) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(()->{ + Toast.makeText(getApplicationContext(), "User removed", Toast.LENGTH_SHORT).show(); + tutorsList.remove(position); + notifyDataSetChanged(); + },this::showError) + ); + }); +// +// if (tutor.isIsOnline()) { +// image = context.getResources().getDrawable(R.drawable.user_list_online); +// } else { +// image = context.getResources().getDrawable(R.drawable.user_list_offline); +// } +// +// if (!tutor.isIsActive()) { +// image = context.getResources().getDrawable(R.drawable.user_list_off); +// } + +// image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight()); +// holder.isOnline.setCompoundDrawables(image, null, null, null); + } + + @Override + public int getItemCount() { + return tutorsList.size(); + } + + class MyViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.firstName) + TextView firstName; + + @BindView(R.id.lastName) + TextView lastName; + +// @BindView(R.id.isOnline) +// TextView isOnline; + @BindView(R.id.removeUserImageButton) + ImageButton imageButton; + + MyViewHolder(View view) { + super(view); + ButterKnife.bind(this, view); + } + } + + private void showError(Throwable e) { + String message; + + if (e instanceof HttpException) { + ResponseBody responseBody = ((HttpException) e).response().errorBody(); + message = RestApiHelper.getErrorMessage(responseBody); + } else { + message = "Network Error !"; + } + Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show(); + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/uam/wmi/findmytutor/adapters/TutorsListAdapter.java b/app/src/main/java/com/uam/wmi/findmytutor/adapters/TutorsListAdapter.java index 87210e5..ed2f50a 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/adapters/TutorsListAdapter.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/adapters/TutorsListAdapter.java @@ -37,7 +37,7 @@ public class TutorsListAdapter extends RecyclerView.Adapter> getTutorBlacklistedByID(@Path("tutorID") String tutorID); + Single> getTutorBlacklistedByID(@Path("tutorID") String tutorID); @PUT("api/users/blacklist/{tutorID}") Completable setTutorBlacklist(@Path("tutorID") String tutorID, @Body IsUsingListBool isUsing); @@ -75,7 +76,8 @@ public interface UserService { @POST("api/users/blacklist/{tutorID}") Completable addStudentToBlacklist(@Path("tutorID") String tutorID, @Body StudentIdModel student); - @DELETE("api/users/blacklist/{tutorID}") +// @DELETE("api/users/blacklist/{tutorID}") + @HTTP(method = "DELETE", path = "api/users/blacklist/{tutorID}", hasBody = true) Completable removeStudentFromBlacklist(@Path("tutorID") String tutorID, @Body StudentIdModel student); @GET("api/users/whitelist/{tutorID}") diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java index 48fd35f..f5103c7 100644 --- a/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java +++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/Const.java @@ -6,7 +6,7 @@ import java.util.Arrays; import java.util.List; public class Const { - public final static String BASE_URL = "https://s416084.projektstudencki.pl/master/"; + public final static String BASE_URL = "https://s416084.projektstudencki.pl/develop/"; public final static Integer onlineBackgroundLocationInterval = 7000; public final static Integer offlineBackgroundLocationInterval = 36000; public final static Integer defaultMapZoom = 17; diff --git a/app/src/main/res/layout/activity_black_list.xml b/app/src/main/res/layout/activity_black_list.xml new file mode 100644 index 0000000..7b69662 --- /dev/null +++ b/app/src/main/res/layout/activity_black_list.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/black_list_fab_modal.xml b/app/src/main/res/layout/black_list_fab_modal.xml new file mode 100644 index 0000000..5d49f4f --- /dev/null +++ b/app/src/main/res/layout/black_list_fab_modal.xml @@ -0,0 +1,42 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/black_list_row.xml b/app/src/main/res/layout/black_list_row.xml new file mode 100644 index 0000000..d2efd45 --- /dev/null +++ b/app/src/main/res/layout/black_list_row.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/content_black_list.xml b/app/src/main/res/layout/content_black_list.xml new file mode 100644 index 0000000..a252726 --- /dev/null +++ b/app/src/main/res/layout/content_black_list.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/info_popup_blacklist.xml b/app/src/main/res/layout/info_popup_blacklist.xml new file mode 100644 index 0000000..d014fd3 --- /dev/null +++ b/app/src/main/res/layout/info_popup_blacklist.xml @@ -0,0 +1,39 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index c6e0307..c149fc1 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -4,11 +4,11 @@ --> + android:title="@string/navigation_item_blacklist" /> + + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 0bc326e..07e6ed9 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -211,7 +211,11 @@ - użytkownik jest obecnie offline - użytkownik jest nieaktywny (nie udostępnił żadnych danych o lokalizacji od conajmniej tygodnia) - Po kliknięciu w imię i nazwisko wyświetli się karta zawierająca dokładne informacje o profesorze. + Dodaj + Index użytkownika + Dodaj użytkownika do Blacklsi + + Po kliknięciu w imię i nazwisko, wyświetli się karta zawierająca dokładne informacje o profesorze. @@ -239,6 +243,13 @@ Nie Aby skorzystać z tej funkcji musisz pozwolić na udostępnianie lokalizacji. Zgadzasz sie? Udostępnianie + Czarna lista + Pole nie może być puste + Użytkownik dodany + Lista jest pusta + WŁĄCZONA + WYŁĄCZONA + Czarna lista Pobierz dane z WMI Dane zostały zaktualizwane! diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index bcc07bd..5bc97f5 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -19,4 +19,6 @@ 13sp 12dp 10dp + 180dp + 16dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ebd5c88..ab998bf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,7 +32,7 @@ Settings - Notes + Blacklist Password Sign in or register Sign out @@ -297,6 +297,99 @@ - user is currently offline - user is inactive (didn’t share any localization data since 7 days) + BlackList + User index + Add user to Blacklist + + "Material is the metaphor.\n\n" + + "A material metaphor is the unifying theory of a rationalized space and a system of motion." + "The material is grounded in tactile reality, inspired by the study of paper and ink, yet " + "technologically advanced and open to imagination and magic.\n" + "Surfaces and edges of the material provide visual cues that are grounded in reality. The " + "use of familiar tactile attributes helps users quickly understand affordances. Yet the " + "flexibility of the material creates new affordances that supercede those in the physical " + "world, without breaking the rules of physics.\n" + "The fundamentals of light, surface, and movement are key to conveying how objects move, " + "interact, and exist in space and in relation to each other. Realistic lighting shows " + "seams, divides space, and indicates moving parts.\n\n" + + "Bold, graphic, intentional.\n\n" + + "The foundational elements of print based design typography, grids, space, scale, color, " + "and use of imagery guide visual treatments. These elements do far more than please the " + "eye. They create hierarchy, meaning, and focus. Deliberate color choices, edge to edge " + "imagery, large scale typography, and intentional white space create a bold and graphic " + "interface that immerse the user in the experience.\n" + "An emphasis on user actions makes core functionality immediately apparent and provides " + "waypoints for the user.\n\n" + + "Motion provides meaning.\n\n" + + "Motion respects and reinforces the user as the prime mover. Primary user actions are " + "inflection points that initiate motion, transforming the whole design.\n" + "All action takes place in a single environment. Objects are presented to the user without " + "breaking the continuity of experience even as they transform and reorganize.\n" + "Motion is meaningful and appropriate, serving to focus attention and maintain continuity. " + "Feedback is subtle yet clear. Transitions are efficient yet coherent.\n\n" + + "3D world.\n\n" + + "The material environment is a 3D space, which means all objects have x, y, and z " + "dimensions. The z-axis is perpendicularly aligned to the plane of the display, with the " + "positive z-axis extending towards the viewer. Every sheet of material occupies a single " + "position along the z-axis and has a standard 1dp thickness.\n" + "On the web, the z-axis is used for layering and not for perspective. The 3D world is " + "emulated by manipulating the y-axis.\n\n" + + "Light and shadow.\n\n" + + "Within the material environment, virtual lights illuminate the scene. Key lights create " + "directional shadows, while ambient light creates soft shadows from all angles.\n" + "Shadows in the material environment are cast by these two light sources. In Android " + "development, shadows occur when light sources are blocked by sheets of material at " + "various positions along the z-axis. On the web, shadows are depicted by manipulating the " + "y-axis only. The following example shows the card with a height of 6dp.\n\n" + + "Resting elevation.\n\n" + + "All material objects, regardless of size, have a resting elevation, or default elevation " + "that does not change. If an object changes elevation, it should return to its resting " + "elevation as soon as possible.\n\n" + + "Component elevations.\n\n" + + "The resting elevation for a component type is consistent across apps (e.g., FAB elevation " + "does not vary from 6dp in one app to 16dp in another app).\n" + "Components may have different resting elevations across platforms, depending on the depth " + "of the environment (e.g., TV has a greater depth than mobile or desktop).\n\n" + + "Responsive elevation and dynamic elevation offsets.\n\n" + + "Some component types have responsive elevation, meaning they change elevation in response " + "to user input (e.g., normal, focused, and pressed) or system events. These elevation " + "changes are consistently implemented using dynamic elevation offsets.\n" + "Dynamic elevation offsets are the goal elevation that a component moves towards, relative " + "to the component’s resting state. They ensure that elevation changes are consistent " + "across actions and component types. For example, all components that lift on press have " + "the same elevation change relative to their resting elevation.\n" + "Once the input event is completed or cancelled, the component will return to its resting " + "elevation.\n\n" + + "Avoiding elevation interference.\n\n" + + "Components with responsive elevations may encounter other components as they move between " + "their resting elevations and dynamic elevation offsets. Because material cannot pass " + "through other material, components avoid interfering with one another any number of ways, " + "whether on a per component basis or using the entire app layout.\n" + "On a component level, components can move or be removed before they cause interference. " + "For example, a floating action button (FAB) can disappear or move off screen before a " + "user picks up a card, or it can move if a snackbar appears.\n" + "On the layout level, design your app layout to minimize opportunities for interference. " + "For example, position the FAB to one side of stream of a cards so the FAB won’t interfere " + "when a user tries to pick up one of cards.\n\n" + + Add After clicking on a name, the tutor tab will pop up, containing details about selected tutor. Yes @@ -319,8 +412,13 @@ In order to use this function, you have to enable localization sharing. May I do it for you? Sharing The user hasn\'t defined a status. + Field can not be empty + User added + The list is empty + Map + ON + OFF Scrap! - Thank you for scraping your tab! Currently, there are no\nonline users. Currently, there are no\noffline users. Only online users diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index ad4f49e..703fa27 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -22,4 +22,5 @@ @drawable/fab_label_background @color/mapboxWhite +