diff options
author | stefan-niedermann <info@niedermann.it> | 2019-10-19 15:44:07 +0300 |
---|---|---|
committer | stefan-niedermann <info@niedermann.it> | 2019-10-19 15:44:07 +0300 |
commit | a261fc8463409f72972bbc1b18d7a089a0a5906f (patch) | |
tree | d6a4e53da282866b3ae91d89db6b669d25029fd6 /app/src | |
parent | 6cafeee354083a6df3a957cf4760fded079ab70a (diff) | |
parent | 1f25eb3b662777aa79de4d6220204d6c85581365 (diff) |
Merge branch 'acl-ui'
Diffstat (limited to 'app/src')
36 files changed, 711 insertions, 244 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java index 2ce246f97..1cb212373 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java @@ -263,7 +263,9 @@ public class SyncManager { } public void updateAccessControl(AccessControl entity) { - dataBaseAdapter.updateAccessControl(entity, true); + doAsync(() -> { + dataBaseAdapter.updateAccessControl(entity, true); + }); } public LiveData<FullBoard> getFullBoardById(Long accountId, Long localId) { diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java index c6373bb6b..95fe0ef47 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/ServerAdapter.java @@ -19,6 +19,8 @@ import java.util.List; import java.util.Locale; import java.util.TimeZone; +import butterknife.BindString; +import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.api.ApiProvider; import it.niedermann.nextcloud.deck.api.IResponseCallback; @@ -39,6 +41,9 @@ import it.niedermann.nextcloud.deck.util.DateUtil; public class ServerAdapter { + @BindString(R.string.pref_key_wifi_only) + String prefKeyWifiOnly; + private static final DateFormat API_FORMAT = new SimpleDateFormat("E, dd MMM yyyy hh:mm:ss z", Locale.US); @@ -54,6 +59,7 @@ public class ServerAdapter { public ServerAdapter(Context applicationContext, Activity sourceActivity) { this.applicationContext = applicationContext; this.sourceActivity = sourceActivity; + ButterKnife.bind(this, sourceActivity); provider = new ApiProvider(applicationContext); lastSyncPref = applicationContext.getSharedPreferences( applicationContext.getString(R.string.shared_preference_last_sync), Context.MODE_PRIVATE); @@ -82,7 +88,7 @@ public class ServerAdapter { ConnectivityManager cm = (ConnectivityManager) applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE); if (cm != null) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext); - if (sharedPreferences.getBoolean(applicationContext.getResources().getString(R.string.pref_key_wifi_only), false)){ + if (sharedPreferences.getBoolean(prefKeyWifiOnly, false)){ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { Network network = cm.getActiveNetwork(); NetworkCapabilities capabilities = cm.getNetworkCapabilities(network); @@ -100,7 +106,7 @@ public class ServerAdapter { } else { - return cm != null && cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected(); + return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected(); } } return false; diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/AboutActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/AboutActivity.java index bb82139c1..a72cbe666 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/AboutActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/AboutActivity.java @@ -2,6 +2,7 @@ package it.niedermann.nextcloud.deck.ui; import android.os.Bundle; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; @@ -11,6 +12,7 @@ import androidx.viewpager.widget.ViewPager; import com.google.android.material.tabs.TabLayout; +import butterknife.BindString; import butterknife.BindView; import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.Application; @@ -29,6 +31,13 @@ public class AboutActivity extends AppCompatActivity { @BindView(R.id.tabs) TabLayout mTabLayout; + @BindString(R.string.about_credits_tab_title) + String creditsTitle; + @BindString(R.string.about_license_tab_title) + String licenseTitle; + @BindString(R.string.about_contribution_tab_title) + String contributionTitle; + @Override protected void onCreate(Bundle savedInstanceState) { setTheme(Application.getAppTheme(this) ? R.style.DarkAppTheme : R.style.AppTheme); @@ -57,6 +66,7 @@ public class AboutActivity extends AppCompatActivity { /** * return the right fragment for the given position */ + @NonNull @Override public Fragment getItem(int position) { switch (position) { @@ -70,7 +80,7 @@ public class AboutActivity extends AppCompatActivity { return new AboutFragmentLicenseTab(); default: - return null; + throw new IllegalArgumentException("position must be between 0 and 2"); } } @@ -81,16 +91,16 @@ public class AboutActivity extends AppCompatActivity { public CharSequence getPageTitle(int position) { switch (position) { case 0: - return getString(R.string.about_credits_tab_title); + return creditsTitle; case 1: - return getString(R.string.about_contribution_tab_title); + return contributionTitle; case 2: - return getString(R.string.about_license_tab_title); + return licenseTitle; default: - return null; + throw new IllegalArgumentException("position must be between 0 and 2"); } } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/DrawerActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/DrawerActivity.java index 35681fe86..62068ac3a 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/DrawerActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/DrawerActivity.java @@ -49,6 +49,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import butterknife.BindInt; +import butterknife.BindString; import butterknife.BindView; import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.Application; @@ -83,6 +85,27 @@ public abstract class DrawerActivity extends AppCompatActivity implements Naviga @BindView(R.id.toolbar) Toolbar toolbar; + @BindString(R.string.account_is_getting_imported) + String accountIsGettingImported; + @BindString(R.string.account_already_added) + String accountAlreadyAdded; + @BindString(R.string.shared_preference_last_account) + String sharedPreferenceLastAccount; + @BindString(R.string.url_fragment_update_deck) + String urlFragmentUpdateDeck; + @BindString(R.string.add_board) + String addBoard; + @BindString(R.string.no_account) + String noAccount; + @BindString(R.string.add_account) + String addAccount; + @BindInt(R.integer.minimum_server_app_major) + int minimumServerAppMajor; + @BindInt(R.integer.minimum_server_app_minor) + int minimumServerAppMinor; + @BindInt(R.integer.minimum_server_app_patch) + int minimumServerAppPatch; + protected List<Account> accountsList = new ArrayList<>(); protected Account account; protected boolean accountChooserActive = false; @@ -112,29 +135,26 @@ public abstract class DrawerActivity extends AppCompatActivity implements Naviga try { accountLiveData.throwError(); } catch (SQLiteConstraintException ex) { - Snackbar.make(coordinatorLayout, getString(R.string.account_already_added), Snackbar.LENGTH_LONG).show(); + Snackbar.make(coordinatorLayout, accountAlreadyAdded, Snackbar.LENGTH_LONG).show(); } } else { // Remember last account - THIS HAS TO BE DONE SYNCHRONOUSLY SharedPreferences.Editor editor = sharedPreferences.edit(); DeckLog.log("--- Write: shared_preference_last_account" + " | " + createdAccount.getId()); - editor.putLong(getString(R.string.shared_preference_last_account), createdAccount.getId()); + editor.putLong(sharedPreferenceLastAccount, createdAccount.getId()); editor.commit(); syncManager.getServerVersion(new IResponseCallback<Capabilities>(createdAccount) { @Override public void onResponse(Capabilities response) { - if (response.getDeckVersion().compareTo(new Version( - getResources().getInteger(R.integer.minimum_server_app_major), - getResources().getInteger(R.integer.minimum_server_app_minor), - getResources().getInteger(R.integer.minimum_server_app_patch))) < 0) { + if (response.getDeckVersion().compareTo(new Version(minimumServerAppMajor, minimumServerAppMinor, minimumServerAppPatch)) < 0) { deckVersionTooLowSnackbar = Snackbar.make(coordinatorLayout, R.string.your_deck_version_is_too_old, Snackbar.LENGTH_INDEFINITE).setAction("Learn more", v -> { new AlertDialog.Builder(DrawerActivity.this, Application.getAppTheme(getApplicationContext()) ? R.style.DialogDarkTheme : R.style.ThemeOverlay_AppCompat_Dialog_Alert) .setTitle(R.string.update_deck) .setMessage(R.string.deck_outdated_please_update) .setPositiveButton(R.string.simple_update, (dialog, whichButton) -> { Intent openURL = new Intent(Intent.ACTION_VIEW); - openURL.setData(Uri.parse(createdAccount.getUrl() + getString(R.string.url_fragment_update_deck))); + openURL.setData(Uri.parse(createdAccount.getUrl() + urlFragmentUpdateDeck)); startActivity(openURL); }) .setNegativeButton(R.string.simple_discard, null).show(); @@ -142,10 +162,10 @@ public abstract class DrawerActivity extends AppCompatActivity implements Naviga deckVersionTooLowSnackbar.show(); syncManager.deleteAccount(createdAccount.getId()); - sharedPreferences.getLong(getString(R.string.shared_preference_last_account), NO_ACCOUNTS); + sharedPreferences.getLong(sharedPreferenceLastAccount, NO_ACCOUNTS); SharedPreferences.Editor editor = sharedPreferences.edit(); DeckLog.log("--- Remove: shared_preference_last_account" + " | " + createdAccount.getId()); - editor.remove(getString(R.string.shared_preference_last_account)); + editor.remove(sharedPreferenceLastAccount); editor.commit(); // Has to be done synchronously } else { accountIsGettingImportedSnackbar.show(); @@ -167,7 +187,7 @@ public abstract class DrawerActivity extends AppCompatActivity implements Naviga Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this)); setSupportActionBar(toolbar); - accountIsGettingImportedSnackbar = Snackbar.make(coordinatorLayout, getString(R.string.account_is_getting_imported), Snackbar.LENGTH_INDEFINITE); + accountIsGettingImportedSnackbar = Snackbar.make(coordinatorLayout, accountIsGettingImported, Snackbar.LENGTH_INDEFINITE); View header = navigationView.getHeaderView(0); headerViewHolder = new HeaderViewHolder(header); @@ -186,7 +206,7 @@ public abstract class DrawerActivity extends AppCompatActivity implements Naviga syncManager.readAccounts().observe(this, (List<Account> accounts) -> { DeckLog.log("+++ readAccounts()"); accountsList = accounts; - long lastAccountId = sharedPreferences.getLong(getString(R.string.shared_preference_last_account), NO_ACCOUNTS); + long lastAccountId = sharedPreferences.getLong(sharedPreferenceLastAccount, NO_ACCOUNTS); DeckLog.log("--- Read: shared_preference_last_account" + " | " + lastAccountId); for (Account account : accounts) { @@ -283,7 +303,7 @@ public abstract class DrawerActivity extends AppCompatActivity implements Naviga // Remember last account SharedPreferences.Editor editor = sharedPreferences.edit(); DeckLog.log("--- Write: shared_preference_last_account" + " | " + this.account.getId()); - editor.putLong(getString(R.string.shared_preference_last_account), this.account.getId()); + editor.putLong(sharedPreferenceLastAccount, this.account.getId()); editor.apply(); } } else { @@ -297,7 +317,7 @@ public abstract class DrawerActivity extends AppCompatActivity implements Naviga startActivityForResult(settingsIntent, ACTIVITY_ABOUT); break; case MENU_ID_ADD_BOARD: - EditBoardDialogFragment.newInstance().show(getSupportFragmentManager(), getString(R.string.add_board)); + EditBoardDialogFragment.newInstance().show(getSupportFragmentManager(), addBoard); break; default: boardSelected(item.getItemId(), account); @@ -316,7 +336,7 @@ public abstract class DrawerActivity extends AppCompatActivity implements Naviga protected void setNoAccountHeaderView() { ViewUtil.addAvatar(this, navigationView.getHeaderView(0).findViewById(R.id.drawer_current_account), null, "", R.mipmap.ic_launcher_round); - ((TextView) navigationView.getHeaderView(0).findViewById(R.id.drawer_username_full)).setText(getResources().getString(R.string.no_account)); + ((TextView) navigationView.getHeaderView(0).findViewById(R.id.drawer_username_full)).setText(noAccount); } private void buildSidenavAccountChooser() { @@ -362,7 +382,7 @@ public abstract class DrawerActivity extends AppCompatActivity implements Naviga // Remember last account SharedPreferences.Editor editor = sharedPreferences.edit(); DeckLog.log("--- Write: shared_preference_last_account" + " | " + this.account.getId()); - editor.putLong(getString(R.string.shared_preference_last_account), this.account.getId()); + editor.putLong(sharedPreferenceLastAccount, this.account.getId()); editor.apply(); } else if (accountsList.size() > 1) { // Select second account after deletion this.account = accountsList.get(1); @@ -375,7 +395,7 @@ public abstract class DrawerActivity extends AppCompatActivity implements Naviga // Remember last account SharedPreferences.Editor editor = sharedPreferences.edit(); DeckLog.log("--- Write: shared_preference_last_account" + " | " + this.account.getId()); - editor.putLong(getString(R.string.shared_preference_last_account), this.account.getId()); + editor.putLong(sharedPreferenceLastAccount, this.account.getId()); editor.apply(); } else { accountsList.clear(); @@ -388,7 +408,7 @@ public abstract class DrawerActivity extends AppCompatActivity implements Naviga m.setActionView(contextMenu); } } - menu.add(Menu.NONE, MENU_ID_ADD_ACCOUNT, Menu.NONE, getString(R.string.add_account)).setIcon(R.drawable.ic_person_add_black_24dp); + menu.add(Menu.NONE, MENU_ID_ADD_ACCOUNT, Menu.NONE, addAccount).setIcon(R.drawable.ic_person_add_black_24dp); } abstract void buildSidenavMenu(); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/EditActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/EditActivity.java index 01888bb2b..2f9965467 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/EditActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/EditActivity.java @@ -8,7 +8,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.widget.EditText; -import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; @@ -19,8 +18,8 @@ import com.google.android.material.textfield.TextInputLayout; import java.util.ArrayList; import java.util.Date; -import java.util.Objects; +import butterknife.BindString; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.Unbinder; @@ -44,7 +43,6 @@ import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.NO_LOCAL_ID; public class EditActivity extends AppCompatActivity { SyncManager syncManager; - private ActionBar actionBar; @BindView(R.id.toolbar) Toolbar toolbar; @@ -57,6 +55,11 @@ public class EditActivity extends AppCompatActivity { @BindView(R.id.pager) ViewPager pager; + @BindString(R.string.simple_add) + String add; + @BindString(R.string.edit) + String edit; + private Unbinder unbinder; private boolean modified = false; @@ -80,7 +83,6 @@ public class EditActivity extends AppCompatActivity { unbinder = ButterKnife.bind(this); setSupportActionBar(toolbar); - actionBar = Objects.requireNonNull(getSupportActionBar()); Bundle extras = getIntent().getExtras(); if (extras != null) { @@ -156,7 +158,7 @@ public class EditActivity extends AppCompatActivity { private void setupViewPager() { tabLayout.removeAllTabs(); tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); - CardTabAdapter adapter = new CardTabAdapter(getSupportFragmentManager(), getResources(), accountId, localId, boardId, canEdit); + CardTabAdapter adapter = new CardTabAdapter(getSupportFragmentManager(), this, accountId, localId, boardId, canEdit); pager.setOffscreenPageLimit(2); pager.setAdapter(adapter); tabLayout.setupWithViewPager(pager); @@ -164,14 +166,14 @@ public class EditActivity extends AppCompatActivity { private void setupTitle(boolean createMode) { title.setText(fullCard.getCard().getTitle()); - if(canEdit) { - if(createMode) { + if (canEdit) { + if (createMode) { title.requestFocus(); - if(fullCard.getCard().getTitle() != null) { + if (fullCard.getCard().getTitle() != null) { title.setSelection(fullCard.getCard().getTitle().length()); } } - titleTextInputLayout.setHint(getString(createMode ? R.string.simple_add : R.string.edit)); + titleTextInputLayout.setHint(createMode ? add : edit); title.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { @@ -203,8 +205,6 @@ public class EditActivity extends AppCompatActivity { if (fullCard != null) { fullCard.getCard().setTitle(title); } - String prefix = NO_LOCAL_ID.equals(localId) ? getString(R.string.add_card) : getString(R.string.edit); - actionBar.setTitle(prefix + " " + title); modified = true; } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java index 4fa43865a..51c5e2535 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java @@ -27,6 +27,7 @@ import com.h6ah4i.android.tablayouthelper.TabLayoutHelper; import java.util.List; import java.util.Objects; +import butterknife.BindString; import butterknife.BindView; import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.Application; @@ -38,6 +39,7 @@ import it.niedermann.nextcloud.deck.model.Stack; import it.niedermann.nextcloud.deck.model.full.FullBoard; import it.niedermann.nextcloud.deck.model.full.FullStack; import it.niedermann.nextcloud.deck.ui.board.EditBoardDialogFragment; +import it.niedermann.nextcloud.deck.ui.board.ShareBoardDialogFragment; import it.niedermann.nextcloud.deck.ui.exception.ExceptionHandler; import it.niedermann.nextcloud.deck.ui.helper.dnd.CrossTabDragAndDrop; import it.niedermann.nextcloud.deck.ui.stack.EditStackDialogFragment; @@ -67,6 +69,25 @@ public class MainActivity extends DrawerActivity { @BindView(R.id.no_stacks) RelativeLayout noStacks; + @BindString(R.string.shared_preference_last_board_for_account_) + String sharedPreferencesLastBoardForAccount_; + @BindString(R.string.shared_preference_last_stack_for_account_and_board_) + String sharedPreferencesLastStackForAccountAndBoard_; + @BindString(R.string.simple_settings) + String simpleSettings; + @BindString(R.string.simple_boards) + String simpleBoards; + @BindString(R.string.about) + String about; + @BindString(R.string.share_board) + String shareBoard; + @BindString(R.string.edit_board) + String editBoard; + @BindString(R.string.add_column) + String addColumn; + @BindString(R.string.action_card_list_rename_column) + String actionCardListRenameColumn; + private StackAdapter stackAdapter; private List<Board> boardsList; private LiveData<List<Board>> boardsLiveData; @@ -112,10 +133,10 @@ public class MainActivity extends DrawerActivity { startActivity(intent); } catch (IndexOutOfBoundsException e) { EditStackDialogFragment.newInstance(NO_STACK_ID) - .show(getSupportFragmentManager(), getString(R.string.add_column)); + .show(getSupportFragmentManager(), addColumn); } } else { - EditBoardDialogFragment.newInstance().show(getSupportFragmentManager(), getString(R.string.add_board)); + EditBoardDialogFragment.newInstance().show(getSupportFragmentManager(), addBoard); } }); @@ -133,7 +154,7 @@ public class MainActivity extends DrawerActivity { long currentStackId = stackAdapter.getItem(position).getStackId(); SharedPreferences.Editor editor = sharedPreferences.edit(); DeckLog.log("--- Write: shared_preference_last_stack_for_account_and_board_" + account.getId() + "_" + currentBoardId + " | " + currentStackId); - editor.putLong(getString(R.string.shared_preference_last_stack_for_account_and_board) + account.getId() + "_" + currentBoardId, currentStackId); + editor.putLong(sharedPreferencesLastStackForAccountAndBoard_ + account.getId() + "_" + currentBoardId, currentStackId); editor.apply(); } }); @@ -189,13 +210,12 @@ public class MainActivity extends DrawerActivity { currentBoardId = board.getLocalId(); buildSidenavMenu(); - EditStackDialogFragment.newInstance(NO_STACK_ID) - .show(getSupportFragmentManager(), getString(R.string.add_column)); + EditStackDialogFragment.newInstance(NO_STACK_ID).show(getSupportFragmentManager(), addColumn); // Remember last board for this account SharedPreferences.Editor editor = sharedPreferences.edit(); DeckLog.log("--- Write: shared_preference_last_board_for_account_" + account.getId() + " | " + currentBoardId); - editor.putLong(getString(R.string.shared_preference_last_board_for_account_) + this.account.getId(), currentBoardId); + editor.putLong(sharedPreferencesLastBoardForAccount_ + this.account.getId(), currentBoardId); editor.apply(); } }); @@ -207,7 +227,7 @@ public class MainActivity extends DrawerActivity { @Override protected void accountSet(Account account) { - currentBoardId = sharedPreferences.getLong(getString(R.string.shared_preference_last_board_for_account_) + this.account.getId(), NO_BOARDS); + currentBoardId = sharedPreferences.getLong(sharedPreferencesLastBoardForAccount_ + this.account.getId(), NO_BOARDS); DeckLog.log("--- Read: shared_preference_last_board_for_account_" + account.getId() + " | " + currentBoardId); if (boardsLiveData != null && boardsLiveDataObserver != null) { @@ -231,7 +251,7 @@ public class MainActivity extends DrawerActivity { // Remember last board for this account SharedPreferences.Editor editor = sharedPreferences.edit(); DeckLog.log("--- Write: shared_preference_last_board_for_account_" + account.getId() + " | " + currentBoardId); - editor.putLong(getString(R.string.shared_preference_last_board_for_account_) + this.account.getId(), currentBoardId); + editor.putLong(sharedPreferencesLastBoardForAccount_ + this.account.getId(), currentBoardId); editor.apply(); } @@ -240,7 +260,7 @@ public class MainActivity extends DrawerActivity { navigationView.setItemIconTintList(null); Menu menu = navigationView.getMenu(); menu.clear(); - SubMenu boardsMenu = menu.addSubMenu(getString(R.string.simple_boards)); + SubMenu boardsMenu = menu.addSubMenu(simpleBoards); if (boardsList != null) { int index = 0; for (Board board : boardsList) { @@ -255,16 +275,16 @@ public class MainActivity extends DrawerActivity { popup.getMenuInflater() .inflate(R.menu.navigation_context_menu, popup.getMenu()); final int SHARE_BOARD_ID = -1; - if(board.isPermissionShare()) { + if (board.isPermissionShare()) { MenuItem shareItem = popup.getMenu().add(Menu.NONE, SHARE_BOARD_ID, 5, R.string.share_board); } popup.setOnMenuItemClickListener((MenuItem item) -> { switch (item.getItemId()) { case SHARE_BOARD_ID: - Snackbar.make(drawer, "Sharing boards is not yet supported.", Snackbar.LENGTH_LONG).show(); + ShareBoardDialogFragment.newInstance(account.getId(), board.getLocalId()).show(getSupportFragmentManager(), shareBoard); break; case R.id.edit_board: - EditBoardDialogFragment.newInstance(account.getId(), board.getLocalId()).show(getSupportFragmentManager(), getString(R.string.edit_board)); + EditBoardDialogFragment.newInstance(account.getId(), board.getLocalId()).show(getSupportFragmentManager(), editBoard); break; case R.id.archive_board: // TODO implement @@ -282,7 +302,7 @@ public class MainActivity extends DrawerActivity { boardSelected(1, account); } else { // No other board is available, open create dialog Objects.requireNonNull(getSupportActionBar()).setTitle(R.string.app_name_short); - EditBoardDialogFragment.newInstance().show(getSupportFragmentManager(), getString(R.string.add_board)); + EditBoardDialogFragment.newInstance().show(getSupportFragmentManager(), addBoard); } } syncManager.deleteBoard(board); @@ -298,20 +318,20 @@ public class MainActivity extends DrawerActivity { popup.show(); }); m.setActionView(contextMenu); - } else if(board.isPermissionShare()) { + } else if (board.isPermissionShare()) { AppCompatImageButton contextMenu = new AppCompatImageButton(this); contextMenu.setBackgroundDrawable(null); contextMenu.setImageDrawable(ViewUtil.getTintedImageView(this, R.drawable.ic_share_grey600_18dp, R.color.grey600)); contextMenu.setOnClickListener((v) -> { - Snackbar.make(drawer, "Sharing boards is not yet supported.", Snackbar.LENGTH_LONG).show(); + ShareBoardDialogFragment.newInstance(account.getId(), board.getLocalId()).show(getSupportFragmentManager(), shareBoard); }); m.setActionView(contextMenu); } } } - boardsMenu.add(Menu.NONE, MENU_ID_ADD_BOARD, Menu.NONE, getString(R.string.add_board)).setIcon(R.drawable.ic_add_grey_24dp); - menu.add(Menu.NONE, MENU_ID_SETTINGS, Menu.NONE, getString(R.string.simple_settings)).setIcon(R.drawable.ic_settings_grey600_24dp); - menu.add(Menu.NONE, MENU_ID_ABOUT, Menu.NONE, getString(R.string.about)).setIcon(R.drawable.ic_info_outline_grey_24dp); + boardsMenu.add(Menu.NONE, MENU_ID_ADD_BOARD, Menu.NONE, addBoard).setIcon(R.drawable.ic_add_grey_24dp); + menu.add(Menu.NONE, MENU_ID_SETTINGS, Menu.NONE, simpleSettings).setIcon(R.drawable.ic_settings_grey600_24dp); + menu.add(Menu.NONE, MENU_ID_ABOUT, Menu.NONE, about).setIcon(R.drawable.ic_info_outline_grey_24dp); if (currentBoardId == NO_BOARDS && boardsList.size() > 0) { Board currentBoard = boardsList.get(0); currentBoardId = currentBoard.getLocalId(); @@ -350,7 +370,7 @@ public class MainActivity extends DrawerActivity { noStacks.setVisibility(View.VISIBLE); currentBoardHasStacks = false; } else { - long savedStackId = sharedPreferences.getLong(getString(R.string.shared_preference_last_stack_for_account_and_board) + account.getId() + "_" + this.currentBoardId, NO_STACKS); + long savedStackId = sharedPreferences.getLong(sharedPreferencesLastStackForAccountAndBoard_ + account.getId() + "_" + this.currentBoardId, NO_STACKS); DeckLog.log("--- Read: shared_preference_last_stack_for_account_and_board" + account.getId() + "_" + this.currentBoardId + " | " + savedStackId); if (fullStacks.size() == 0) { noStacks.setVisibility(View.VISIBLE); @@ -386,7 +406,7 @@ public class MainActivity extends DrawerActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); - if(currentBoardHasEditPermission) { + if (currentBoardHasEditPermission) { inflater.inflate(R.menu.card_list_menu, menu); menu.findItem(R.id.action_card_list_rename_column).setVisible(currentBoardHasStacks); menu.findItem(R.id.action_card_list_delete_column).setVisible(currentBoardHasStacks); @@ -414,11 +434,11 @@ public class MainActivity extends DrawerActivity { break; case R.id.action_card_list_add_column: EditStackDialogFragment.newInstance(NO_STACK_ID) - .show(getSupportFragmentManager(), getString(R.string.add_column)); + .show(getSupportFragmentManager(), addColumn); break; case R.id.action_card_list_rename_column: EditStackDialogFragment.newInstance(stackAdapter.getItem(viewPager.getCurrentItem()).getStackId()) - .show(getSupportFragmentManager(), getString(R.string.action_card_list_rename_column)); + .show(getSupportFragmentManager(), actionCardListRenameColumn); break; } return super.onOptionsItemSelected(item); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/about/AboutFragmentCreditsTab.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/about/AboutFragmentCreditsTab.java index 88a4f18d8..adacda0e5 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/about/AboutFragmentCreditsTab.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/about/AboutFragmentCreditsTab.java @@ -1,6 +1,5 @@ package it.niedermann.nextcloud.deck.ui.about; -import android.content.res.Resources; import android.graphics.Typeface; import android.os.Bundle; import android.text.Spannable; @@ -18,6 +17,7 @@ import androidx.fragment.app.Fragment; import java.util.Objects; +import butterknife.BindString; import butterknife.BindView; import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.BuildConfig; @@ -39,24 +39,31 @@ public class AboutFragmentCreditsTab extends Fragment { @BindView(R.id.about_translators) TextView aboutTranslators; + @BindString(R.string.you_are_currently_offline) + String offlineText; + @BindString(R.string.strong_start) + String strongStart; + @BindString(R.string.strong_end) + String strongEnd; + @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_about_credits_tab, container, false); ButterKnife.bind(this, v); - LinkUtil.setHtml(aboutVersion, getString(R.string.about_version, getVersionStrongTag(getResources(), BuildConfig.VERSION_NAME))); + LinkUtil.setHtml(aboutVersion, getString(R.string.about_version, getVersionStrongTag(BuildConfig.VERSION_NAME))); SyncManager syncManager = new SyncManager(Objects.requireNonNull(getActivity())); try { syncManager.getServerVersion(new IResponseCallback<Capabilities>(null) { @Override public void onResponse(Capabilities response) { - Objects.requireNonNull(getActivity()).runOnUiThread(() -> LinkUtil.setHtml(aboutServerAppVersion, getVersionStrongTag(getResources(), response.getDeckVersion().toString()))); + Objects.requireNonNull(getActivity()).runOnUiThread(() -> LinkUtil.setHtml(aboutServerAppVersion, getVersionStrongTag(response.getDeckVersion().toString()))); } }); } catch (OfflineException e) { - Spannable offlineText = new SpannableString(getString(R.string.you_are_currently_offline)); - offlineText.setSpan(new StyleSpan(Typeface.ITALIC), 0, offlineText.length(), 0); - offlineText.setSpan(new ForegroundColorSpan(ContextCompat.getColor(Objects.requireNonNull(getContext()), R.color.fg_secondary)), 0, offlineText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - aboutServerAppVersion.setText(offlineText); + Spannable offlineTextSpannable = new SpannableString(offlineText); + offlineTextSpannable.setSpan(new StyleSpan(Typeface.ITALIC), 0, offlineTextSpannable.length(), 0); + offlineTextSpannable.setSpan(new ForegroundColorSpan(ContextCompat.getColor(Objects.requireNonNull(getContext()), R.color.fg_secondary)), 0, offlineTextSpannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + aboutServerAppVersion.setText(offlineTextSpannable); } LinkUtil.setHtml(aboutMaintainer, LinkUtil.concatenateResources(v.getResources(), R.string.anchor_start, R.string.url_maintainer, R.string.anchor_middle, R.string.about_maintainer, R.string.anchor_end)); @@ -67,10 +74,7 @@ public class AboutFragmentCreditsTab extends Fragment { return v; } - private static String getVersionStrongTag(Resources resources, String version) { - return resources.getString(R.string.strong_start) + - "v" + - version + - resources.getString(R.string.strong_end); + private String getVersionStrongTag(String version) { + return strongStart + "v" + version + strongEnd; } }
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/about/AboutFragmentLicenseTab.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/about/AboutFragmentLicenseTab.java index d06da58fb..3ab1ea2b1 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/about/AboutFragmentLicenseTab.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/about/AboutFragmentLicenseTab.java @@ -13,6 +13,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import butterknife.BindString; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -26,6 +27,11 @@ public class AboutFragmentLicenseTab extends Fragment { @BindView(R.id.about_app_license_button) Button appLicenseButton; + @BindString(R.string.paragraph_start) + String paragraphStart; + @BindString(R.string.paragraph_end) + String paragraphEnd; + @OnClick(R.id.about_app_license_button) void openLicense() { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.url_license)))); @@ -36,21 +42,15 @@ public class AboutFragmentLicenseTab extends Fragment { View v = inflater.inflate(R.layout.fragment_about_license_tab, container, false); ButterKnife.bind(this, v); Resources resources = getResources(); - LinkUtil.setHtml(iconsDisclaimer, - resources.getString(R.string.paragraph_start), - resources.getString(R.string.about_icons_disclaimer, getAppIconHint(resources), getMdiLink(resources)), - resources.getString(R.string.paragraph_end) - ); + LinkUtil.setHtml(iconsDisclaimer, paragraphStart, resources.getString(R.string.about_icons_disclaimer, getAppIconHint(resources), getMdiLink(resources)), paragraphEnd); return v; } - private static String getAppIconHint(Resources resources) { - return LinkUtil.makeLink(resources, R.string.url_about_icon_author, R.string.about_app_icon_author_link_label) + - resources.getString(R.string.paragraph_end) + - resources.getString(R.string.paragraph_start); + private String getAppIconHint(Resources resources) { + return LinkUtil.makeLink(resources, R.string.url_about_icon_author, R.string.about_app_icon_author_link_label) + paragraphEnd + paragraphStart; } - private static String getMdiLink(Resources resources) { + private String getMdiLink(Resources resources) { return LinkUtil.makeLink(resources, R.string.url_about_icons_disclaimer_mdi, R.string.about_icons_disclaimer_mdi); } }
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/AccessControlAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/AccessControlAdapter.java new file mode 100644 index 000000000..a16c47b89 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/AccessControlAdapter.java @@ -0,0 +1,83 @@ +package it.niedermann.nextcloud.deck.ui.board; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.SwitchCompat; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import it.niedermann.nextcloud.deck.R; +import it.niedermann.nextcloud.deck.model.AccessControl; + +public class AccessControlAdapter extends RecyclerView.Adapter<AccessControlAdapter.ActivitiesViewHolder> { + + @NonNull + private List<AccessControl> accessControls; + + public AccessControlAdapter(@NonNull List<AccessControl> accessControls) { + super(); + this.accessControls = accessControls; + } + + @NonNull + @Override + public ActivitiesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_access_control, parent, false); + return new ActivitiesViewHolder(v); + } + + @Override + public void onBindViewHolder(@NonNull ActivitiesViewHolder holder, int position) { + AccessControl ac = accessControls.get(position); + + if (ac.getUser() != null) + holder.username.setText(ac.getUser().getUid()); + + holder.switchEdit.setChecked(ac.isPermissionEdit()); + holder.switchEdit.setOnCheckedChangeListener((buttonView, isChecked) -> { + ac.setPermissionEdit(isChecked); +// syncManager.updateAccessControl(ac); + }); + + holder.switchManage.setChecked(ac.isPermissionManage()); + holder.switchManage.setOnCheckedChangeListener((buttonView, isChecked) -> { + ac.setPermissionManage(isChecked); +// syncManager.updateAccessControl(ac); + }); + + holder.switchShare.setChecked(ac.isPermissionShare()); + holder.switchShare.setOnCheckedChangeListener((buttonView, isChecked) -> { + ac.setPermissionShare(isChecked); +// syncManager.updateAccessControl(ac); + }); + } + + @Override + public int getItemCount() { + return accessControls.size(); + } + + static class ActivitiesViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.username) + TextView username; + @BindView(R.id.permission_edit) + SwitchCompat switchEdit; + @BindView(R.id.permission_manage) + SwitchCompat switchManage; + @BindView(R.id.permission_share) + SwitchCompat switchShare; + + private ActivitiesViewHolder(View view) { + super(view); + ButterKnife.bind(this, view); + } + } + +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/EditBoardDialogFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/EditBoardDialogFragment.java index 630c0ba72..4a83a547a 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/EditBoardDialogFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/EditBoardDialogFragment.java @@ -16,6 +16,7 @@ import androidx.fragment.app.DialogFragment; import java.util.Objects; +import butterknife.BindColor; import butterknife.BindView; import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.Application; @@ -35,10 +36,12 @@ public class EditBoardDialogFragment extends DialogFragment { @BindView(R.id.input) EditText boardTitle; - @BindView(R.id.colorChooser) ColorChooser colorChooser; + @BindColor(R.color.board_default_color) + int boardDefaultColor; + /** * Use newInstance()-Method */ @@ -58,7 +61,7 @@ public class EditBoardDialogFragment extends DialogFragment { if (NO_BOARD_ID.equals(boardId)) { dialogBuilder.setTitle(R.string.add_board); dialogBuilder.setPositiveButton(R.string.simple_add, (dialog, which) -> ((MainActivity) getActivity()).onCreateBoard(boardTitle.getText().toString(), colorChooser.getSelectedColor())); - this.colorChooser.selectColor(String.format("#%06X", 0xFFFFFF & getResources().getColor(R.color.board_default_color))); + this.colorChooser.selectColor(String.format("#%06X", 0xFFFFFF & boardDefaultColor)); } else { dialogBuilder.setTitle(R.string.edit_board); dialogBuilder.setPositiveButton(R.string.simple_save, (dialog, which) -> { diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/ShareBoardDialogFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/ShareBoardDialogFragment.java new file mode 100644 index 000000000..53a043799 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/ShareBoardDialogFragment.java @@ -0,0 +1,79 @@ +package it.niedermann.nextcloud.deck.ui.board; + +import android.app.Activity; +import android.app.Dialog; +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.DialogFragment; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.Objects; + +import butterknife.BindView; +import butterknife.ButterKnife; +import it.niedermann.nextcloud.deck.Application; +import it.niedermann.nextcloud.deck.R; +import it.niedermann.nextcloud.deck.model.full.FullBoard; +import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; + +import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper.observeOnce; + +public class ShareBoardDialogFragment extends DialogFragment { + + private static final String KEY_ACCOUNT_ID = "account_id"; + private static final String KEY_BOARD_ID = "board_id"; + private static final Long NO_BOARD_ID = -1L; + + @BindView(R.id.peopleList) + RecyclerView peopleList; + + /** + * Use newInstance()-Method + */ + private ShareBoardDialogFragment() { + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Activity activity = Objects.requireNonNull(getActivity()); + View view = activity.getLayoutInflater().inflate(R.layout.dialog_board_share, null); + ButterKnife.bind(this, view); + Long boardId = Objects.requireNonNull(getArguments()).getLong(KEY_BOARD_ID); + + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity, Application.getAppTheme(getContext()) ? R.style.DialogDarkTheme : R.style.ThemeOverlay_AppCompat_Dialog_Alert); + + if (NO_BOARD_ID.equals(boardId)) { + throw new IllegalArgumentException("boardId does not exist"); + } else { + SyncManager syncManager = new SyncManager(activity); + final long accountId = Objects.requireNonNull(getArguments()).getLong(KEY_ACCOUNT_ID); + observeOnce(syncManager.getFullBoardById(accountId, boardId), ShareBoardDialogFragment.this, (FullBoard fb) -> { + RecyclerView.Adapter adapter = new AccessControlAdapter(fb.getParticipants()); + peopleList.setAdapter(adapter); + }); + } + + return dialogBuilder + .setView(view) + .setPositiveButton(R.string.simple_close, (dialog, which) -> { + }) + .create(); + } + + public static ShareBoardDialogFragment newInstance(@NonNull Long accountId, @NonNull Long boardId) { + ShareBoardDialogFragment dialog = new ShareBoardDialogFragment(); + + Bundle args = new Bundle(); + args.putLong(KEY_ACCOUNT_ID, accountId); + args.putLong(KEY_BOARD_ID, boardId); + dialog.setArguments(args); + + return dialog; + } + +}
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/ActivityAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/ActivityAdapter.java new file mode 100644 index 000000000..16bc1a9c8 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/ActivityAdapter.java @@ -0,0 +1,88 @@ +package it.niedermann.nextcloud.deck.ui.card; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import it.niedermann.nextcloud.deck.R; +import it.niedermann.nextcloud.deck.model.enums.ActivityType; +import it.niedermann.nextcloud.deck.model.ocs.Activity; +import it.niedermann.nextcloud.deck.util.DateUtil; + +public class ActivityAdapter extends RecyclerView.Adapter<ActivityAdapter.ActivitiesViewHolder> { + + @NonNull + private List<Activity> activities; + private Context context; + + public ActivityAdapter(@NonNull List<Activity> activities) { + super(); + this.activities = activities; + } + + @NonNull + @Override + public ActivitiesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + this.context = parent.getContext(); + View v = LayoutInflater.from(context).inflate(R.layout.item_activity, parent, false); + return new ActivitiesViewHolder(v); + } + + @Override + public void onBindViewHolder(@NonNull ActivitiesViewHolder holder, int position) { + Activity activity = activities.get(position); + holder.date.setText(DateUtil.getRelativeDateTimeString(context, activity.getLastModified().getTime())); + holder.subject.setText(activity.getSubject()); + switch (ActivityType.findById(activity.getType())) { + case DECK: + break; + case CHANGE: + holder.type.setImageResource(R.drawable.type_change_36dp); + break; + case ADD: + holder.type.setImageResource(R.drawable.type_add_color_36dp); + break; + case DELETE: + holder.type.setImageResource(R.drawable.type_delete_color_36dp); + break; + case ARCHIVE: + break; + case HISTORY: + break; + case FILES: + break; + case COMMENT: + break; + } + } + + @Override + public int getItemCount() { + return activities.size(); + } + + static class ActivitiesViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.date) + TextView date; + @BindView(R.id.subject) + TextView subject; + @BindView(R.id.type) + ImageView type; + + private ActivitiesViewHolder(View view) { + super(view); + ButterKnife.bind(this, view); + } + } + +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java new file mode 100644 index 000000000..5f1bddb42 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/AttachmentAdapter.java @@ -0,0 +1,78 @@ +package it.niedermann.nextcloud.deck.ui.card; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.text.format.DateUtils; +import android.text.format.Formatter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import it.niedermann.nextcloud.deck.R; +import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.Attachment; + +public class AttachmentAdapter extends RecyclerView.Adapter<AttachmentAdapter.AttachmentViewHolder> { + + private final Account account; + private final long cardRemoteId; + @NonNull + private List<Attachment> attachments; + private Context context; + + AttachmentAdapter(@NonNull Account account, long cardRemoteId, @NonNull List<Attachment> attachments) { + super(); + this.attachments = attachments; + this.account = account; + this.cardRemoteId = cardRemoteId; + } + + @NonNull + @Override + public AttachmentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + this.context = parent.getContext(); + View v = LayoutInflater.from(context).inflate(R.layout.item_attachment, parent, false); + return new AttachmentViewHolder(v); + } + + @Override + public void onBindViewHolder(@NonNull AttachmentViewHolder holder, int position) { + Attachment attachment = attachments.get(position); + holder.filename.setText(attachment.getFilename()); + holder.filesize.setText(Formatter.formatFileSize(context, attachment.getFilesize())); + holder.modified.setText(DateUtils.getRelativeTimeSpanString(context, attachment.getLastModified().getTime())); + holder.filename.getRootView().setOnClickListener((event) -> { + Intent openURL = new Intent(android.content.Intent.ACTION_VIEW); + openURL.setData(Uri.parse(account.getUrl() + "/index.php/apps/deck/cards/" + cardRemoteId + "/attachment/" + attachment.getId())); + context.startActivity(openURL); + }); + } + + @Override + public int getItemCount() { + return attachments.size(); + } + + static class AttachmentViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.filename) + TextView filename; + @BindView(R.id.filesize) + TextView filesize; + @BindView(R.id.modified) + TextView modified; + + private AttachmentViewHolder(View view) { + super(view); + ButterKnife.bind(this, view); + } + } +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardActivityFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardActivityFragment.java index 92debb597..20a4d5b1f 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardActivityFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardActivityFragment.java @@ -4,14 +4,11 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.LinearLayout; import android.widget.RelativeLayout; -import android.widget.ScrollView; -import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.appcompat.widget.AppCompatImageView; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; import java.util.Objects; @@ -19,10 +16,7 @@ import butterknife.BindView; import butterknife.ButterKnife; import butterknife.Unbinder; import it.niedermann.nextcloud.deck.R; -import it.niedermann.nextcloud.deck.model.enums.ActivityType; -import it.niedermann.nextcloud.deck.model.ocs.Activity; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; -import it.niedermann.nextcloud.deck.util.DateUtil; import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_ACCOUNT_ID; import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_BOARD_ID; @@ -31,10 +25,8 @@ import static it.niedermann.nextcloud.deck.ui.card.CardAdapter.BUNDLE_KEY_LOCAL_ public class CardActivityFragment extends Fragment { private Unbinder unbinder; - @BindView(R.id.scrollView) - ScrollView scrollView; @BindView(R.id.activity_list) - LinearLayout activitiesList; + RecyclerView activitiesList; @BindView(R.id.no_activities) RelativeLayout noActivities; @@ -65,57 +57,26 @@ public class CardActivityFragment extends Fragment { if (args != null) { long accountId = args.getLong(BUNDLE_KEY_ACCOUNT_ID); long localId = args.getLong(BUNDLE_KEY_LOCAL_ID); - long boardId = args.getLong(BUNDLE_KEY_BOARD_ID); - setupView(accountId, localId, boardId); + SyncManager syncManager = new SyncManager(Objects.requireNonNull(getActivity())); + if (syncManager.hasInternetConnection()) { + syncManager.getCardByLocalId(accountId, localId).observe(CardActivityFragment.this, (fullCard) -> + syncManager.syncActivitiesForCard(fullCard.getCard()).observe(CardActivityFragment.this, (activities -> { + if (activities == null || activities.size() == 0) { + noActivities.setVisibility(View.VISIBLE); + activitiesList.setVisibility(View.GONE); + } else { + noActivities.setVisibility(View.GONE); + activitiesList.setVisibility(View.VISIBLE); + RecyclerView.Adapter adapter = new ActivityAdapter(activities); + activitiesList.setAdapter(adapter); + } + }))); + } } return view; } - private void setupView(long accountId, long localId, long boardId) { - SyncManager syncManager = new SyncManager(Objects.requireNonNull(getActivity())); - if (syncManager.hasInternetConnection()) { - syncManager.getCardByLocalId(accountId, localId).observe(CardActivityFragment.this, (fullCard) -> syncManager.syncActivitiesForCard(fullCard.getCard()).observe(CardActivityFragment.this, (activities -> { - if (activities == null || activities.size() == 0) { - noActivities.setVisibility(View.VISIBLE); - scrollView.setVisibility(View.GONE); - } else { - noActivities.setVisibility(View.GONE); - scrollView.setVisibility(View.VISIBLE); - activitiesList.removeAllViews(); - for (Activity a : activities) { - View v = getLayoutInflater().inflate(R.layout.fragment_card_edit_tab_activity, null); - ((TextView) v.findViewById(R.id.date)).setText(DateUtil.getRelativeDateTimeString(getContext(), a.getLastModified().getTime())); - ((TextView) v.findViewById(R.id.subject)).setText(a.getSubject()); - AppCompatImageView type = v.findViewById(R.id.type); - switch (ActivityType.findById(a.getType())) { - case DECK: - break; - case CHANGE: - type.setImageResource(R.drawable.type_change_36dp); - break; - case ADD: - type.setImageResource(R.drawable.type_add_color_36dp); - break; - case DELETE: - type.setImageResource(R.drawable.type_delete_color_36dp); - break; - case ARCHIVE: - break; - case HISTORY: - break; - case FILES: - break; - case COMMENT: - break; - } - activitiesList.addView(v); - } - } - }))); - } - } - @Override public void onDestroy() { super.onDestroy(); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java index edf9ee27f..aaf53e5d2 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAdapter.java @@ -34,7 +34,9 @@ import com.nextcloud.android.sso.model.SingleSignOnAccount; import java.util.LinkedList; import java.util.List; +import java.util.Objects; +import butterknife.BindInt; import butterknife.BindView; import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.DeckLog; @@ -53,7 +55,9 @@ import it.niedermann.nextcloud.deck.util.DimensionUtil; import it.niedermann.nextcloud.deck.util.ViewUtil; public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder> { + private static final String TAG = CardAdapter.class.getCanonicalName(); + public static final int REQUEST_CODE_START_EDIT_ACTIVITY = 100; public static final String BUNDLE_KEY_ACCOUNT_ID = "accountId"; public static final String BUNDLE_KEY_LOCAL_ID = "localId"; @@ -61,7 +65,6 @@ public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder public static final String BUNDLE_KEY_STACK_ID = "stackId"; public static final String BUNDLE_KEY_CAN_EDIT = "canEdit"; public static final Long NO_LOCAL_ID = -1L; - public static final int MAX_AVATAR_COUNT = 3; private Context context; private List<FullCard> cardList = new LinkedList<>(); @@ -73,7 +76,15 @@ public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder private Fragment fragment; private boolean pendingEditActivity = false; + @BindInt(R.integer.max_avatar_count) + int maxAvatarCount; + @BindInt(R.integer.max_labels_shown) + int maxLabelsShown; + @BindInt(R.integer.max_labels_chars) + int maxLabelsChars; + public CardAdapter(long boardId, boolean canEdit, @NonNull SyncManager syncManager, @NonNull Fragment fragment) { + ButterKnife.bind(this, Objects.requireNonNull(fragment.getActivity())); this.boardId = boardId; this.canEdit = canEdit; this.syncManager = syncManager; @@ -84,7 +95,7 @@ public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder @Override public CardViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) { this.context = viewGroup.getContext(); - View v = LayoutInflater.from(this.context).inflate(R.layout.fragment_card, viewGroup, false); + View v = LayoutInflater.from(this.context).inflate(R.layout.item_card, viewGroup, false); try { account = SingleAccountHelper.getCurrentSingleSignOnAccount(context); } catch (NextcloudFilesAppAccountNotFoundException e) { @@ -189,8 +200,6 @@ public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder } private void setupLabels(@NonNull ChipGroup labels, List<Label> labelList) { - int maxLabelsShown = context.getResources().getInteger(R.integer.max_labels_shown); - int maxLabelsChars = context.getResources().getInteger(R.integer.max_labels_chars); Chip chip; for (int i = 0; i < labelList.size(); i++) { if (i > maxLabelsShown - 1 && labelList.size() > maxLabelsShown) { @@ -249,7 +258,7 @@ public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder peopleList.removeAllViews(); RelativeLayout.LayoutParams avatarLayoutParams; int avatarCount; - for (avatarCount = 0; avatarCount < card.getAssignedUsers().size() && avatarCount < MAX_AVATAR_COUNT; avatarCount++) { + for (avatarCount = 0; avatarCount < card.getAssignedUsers().size() && avatarCount < maxAvatarCount; avatarCount++) { avatarLayoutParams = new RelativeLayout.LayoutParams(avatarSize, avatarSize); avatarLayoutParams.setMargins(0, 0, avatarCount * context.getResources().getDimensionPixelSize(R.dimen.avatar_overlapping_small), 0); avatarLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java index 8473035ff..c8c5c6324 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardAttachmentsFragment.java @@ -1,19 +1,14 @@ package it.niedermann.nextcloud.deck.ui.card; -import android.content.Intent; -import android.net.Uri; import android.os.Bundle; -import android.text.format.DateUtils; -import android.text.format.Formatter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.LinearLayout; import android.widget.RelativeLayout; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; import java.util.Objects; @@ -22,7 +17,6 @@ import butterknife.ButterKnife; import butterknife.Unbinder; import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.model.Account; -import it.niedermann.nextcloud.deck.model.Attachment; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; import static it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper.observeOnce; @@ -34,7 +28,7 @@ public class CardAttachmentsFragment extends Fragment { private Unbinder unbinder; @BindView(R.id.attachments_list) - LinearLayout attachmentsList; + RecyclerView attachmentsList; @BindView(R.id.no_attachments) RelativeLayout noAttachments; @@ -50,9 +44,21 @@ public class CardAttachmentsFragment extends Fragment { if (args != null) { long accountId = args.getLong(BUNDLE_KEY_ACCOUNT_ID); long localId = args.getLong(BUNDLE_KEY_LOCAL_ID); - long boardId = args.getLong(BUNDLE_KEY_BOARD_ID); - setupView(accountId, localId, boardId); + SyncManager syncManager = new SyncManager(Objects.requireNonNull(getActivity())); + observeOnce(syncManager.getCardByLocalId(accountId, localId), CardAttachmentsFragment.this, (fullCard) -> { + if (fullCard.getAttachments().size() == 0) { + this.noAttachments.setVisibility(View.VISIBLE); + this.attachmentsList.setVisibility(View.GONE); + } else { + this.noAttachments.setVisibility(View.GONE); + this.attachmentsList.setVisibility(View.VISIBLE); + syncManager.readAccount(accountId).observe(CardAttachmentsFragment.this, (Account account) -> { + RecyclerView.Adapter adapter = new AttachmentAdapter(account, fullCard.getCard().getId(), fullCard.getAttachments()); + attachmentsList.setAdapter(adapter); + }); + } + }); } return view; @@ -72,34 +78,6 @@ public class CardAttachmentsFragment extends Fragment { return fragment; } - private void setupView(long accountId, long localId, long boardId) { - SyncManager syncManager = new SyncManager(Objects.requireNonNull(getActivity())); - observeOnce(syncManager.getCardByLocalId(accountId, localId), CardAttachmentsFragment.this, (fullCard) -> { - if (fullCard.getAttachments().size() == 0) { - this.noAttachments.setVisibility(View.VISIBLE); - this.attachmentsList.setVisibility(View.GONE); - } else { - this.noAttachments.setVisibility(View.GONE); - this.attachmentsList.setVisibility(View.VISIBLE); - syncManager.readAccount(accountId).observe(CardAttachmentsFragment.this, (Account account) -> { - for (Attachment a : fullCard.getAttachments()) { - View v = getLayoutInflater().inflate(R.layout.fragment_card_edit_tab_attachment, null); - ((TextView) v.findViewById(R.id.filename)).setText(a.getFilename()); - ((TextView) v.findViewById(R.id.filesize)).setText(Formatter.formatFileSize(getContext(), a.getFilesize())); - ((TextView) v.findViewById(R.id.modified)).setText(DateUtils.getRelativeTimeSpanString(getContext(), a.getLastModified().getTime())); - this.attachmentsList.addView(v); - v.setOnClickListener((event) -> { - Intent openURL = new Intent(android.content.Intent.ACTION_VIEW); - openURL.setData(Uri.parse(account.getUrl() + "/index.php/apps/deck/cards/" + fullCard.getCard().getId() + "/attachment/" + a.getId())); - startActivity(openURL); - }); - } - }); - } - }); - } - - @Override public void onDestroy() { super.onDestroy(); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardDetailsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardDetailsFragment.java index f143e39ae..de6db9861 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardDetailsFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardDetailsFragment.java @@ -41,6 +41,7 @@ import java.util.Date; import java.util.Locale; import java.util.Objects; +import butterknife.BindDrawable; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.Unbinder; @@ -84,28 +85,24 @@ public class CardDetailsFragment extends Fragment implements DatePickerDialog.On @BindView(R.id.description) RxMDEditText description; - @BindView(R.id.people) DelayedAutoCompleteTextView people; - @BindView(R.id.labels) DelayedAutoCompleteTextView labels; - @BindView(R.id.peopleList) LinearLayout peopleList; - @BindView(R.id.dueDateDate) TextView dueDate; - @BindView(R.id.dueDateTime) TextView dueDateTime; - @BindView(R.id.clearDueDate) ImageView clearDueDate; - @BindView(R.id.labelsGroup) ChipGroup labelsGroup; + @BindDrawable(R.drawable.ic_close_circle_grey600) + Drawable closeCircleDrawable; + public CardDetailsFragment() { } @@ -358,7 +355,7 @@ public class CardDetailsFragment extends Fragment implements DatePickerDialog.On Chip chip = new Chip(activity); chip.setText(label.getTitle()); if (canEdit) { - chip.setCloseIcon(activity.getResources().getDrawable(R.drawable.ic_close_circle_grey600)); + chip.setCloseIcon(closeCircleDrawable); chip.setCloseIconVisible(true); chip.setOnCloseIconClickListener(v -> { labelsGroup.removeView(chip); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardTabAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardTabAdapter.java index 76ed9af96..971abe6c9 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardTabAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/CardTabAdapter.java @@ -1,25 +1,33 @@ package it.niedermann.nextcloud.deck.ui.card; -import android.content.res.Resources; +import android.app.Activity; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentStatePagerAdapter; +import butterknife.BindString; +import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.R; public class CardTabAdapter extends FragmentStatePagerAdapter { - private Resources resources; private long accountId; private long localId; private long boardId; private boolean canEdit; - public CardTabAdapter(FragmentManager fm, Resources resources, long accountId, long localId, long boardId, boolean canEdit) { + @BindString(R.string.card_edit_details) + String details; + @BindString(R.string.card_edit_attachments) + String attachments; + @BindString(R.string.card_edit_activity) + String activity; + + public CardTabAdapter(FragmentManager fm, Activity activity, long accountId, long localId, long boardId, boolean canEdit) { super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - this.resources = resources; + ButterKnife.bind(this, activity); this.accountId = accountId; this.localId = localId; this.boardId = boardId; @@ -46,11 +54,11 @@ public class CardTabAdapter extends FragmentStatePagerAdapter { public CharSequence getPageTitle(int position) { switch (position) { case 0: - return this.resources.getString(R.string.card_edit_details); + return details; case 1: - return this.resources.getString(R.string.card_edit_attachments); + return attachments; case 2: - return this.resources.getString(R.string.card_edit_activity); + return activity; default: throw new IllegalArgumentException("position " + position + "is not available"); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/LabelAutoCompleteAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/LabelAutoCompleteAdapter.java index e67eed7ee..8bd7fc5c3 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/LabelAutoCompleteAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/LabelAutoCompleteAdapter.java @@ -20,6 +20,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import butterknife.BindColor; +import butterknife.BindInt; +import butterknife.BindString; import butterknife.BindView; import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.R; @@ -39,18 +42,23 @@ public class LabelAutoCompleteAdapter extends BaseAdapter implements Filterable private long cardId; private LifecycleOwner owner; private Label createLabel; - private String createLabelText; private String lastFilterText; private boolean canManage = false; - private int maxLabelsSuggested; + + @BindInt(R.integer.max_labels_suggested) + int maxLabelsSuggested; + @BindString(R.string.label_add) + String createLabelText; + @BindColor(R.color.grey600) + int createLabelColor; public LabelAutoCompleteAdapter(@NonNull LifecycleOwner owner, Activity activity, long accountId, long boardId, long cardId) { + ButterKnife.bind(this, activity); this.owner = owner; this.context = activity; this.accountId = accountId; this.boardId = boardId; this.cardId = cardId; - this.maxLabelsSuggested = activity.getResources().getInteger(R.integer.max_labels_suggested); syncManager = new SyncManager(activity); syncManager.getFullBoardById(accountId, boardId).observe(owner, (fullBoard) -> { if (fullBoard.getBoard().isPermissionManage()) { @@ -58,8 +66,7 @@ public class LabelAutoCompleteAdapter extends BaseAdapter implements Filterable createLabel.setLocalId(CREATE_ID); createLabel.setBoardId(boardId); createLabel.setAccountId(accountId); - createLabelText = activity.getResources().getString(R.string.label_add); - createLabel.setColor("757575"); + createLabel.setColor(Integer.toHexString(createLabelColor)); canManage = true; } }); @@ -88,7 +95,7 @@ public class LabelAutoCompleteAdapter extends BaseAdapter implements Filterable } else { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - convertView = inflater.inflate(R.layout.dropdown_item_singleline, parent, false); + convertView = inflater.inflate(R.layout.item_autocomplete_dropdown, parent, false); holder = new ViewHolder(convertView); convertView.setTag(holder); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/UserAutoCompleteAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/UserAutoCompleteAdapter.java index 2857b3c16..d59316392 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/UserAutoCompleteAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/card/UserAutoCompleteAdapter.java @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import butterknife.BindInt; import butterknife.BindView; import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.DeckLog; @@ -42,14 +43,16 @@ public class UserAutoCompleteAdapter extends BaseAdapter implements Filterable { private long accountId; private long cardId; private LifecycleOwner owner; - private int maxUsersSuggested; + + @BindInt(R.integer.max_users_suggested) + int maxUsersSuggested; public UserAutoCompleteAdapter(@NonNull LifecycleOwner owner, Activity activity, long accountId, long cardId) { + ButterKnife.bind(this, activity); this.owner = owner; this.activity = activity; this.accountId = accountId; this.cardId = cardId; - this.maxUsersSuggested = activity.getResources().getInteger(R.integer.max_users_suggested); syncManager = new SyncManager(activity); } @@ -76,7 +79,7 @@ public class UserAutoCompleteAdapter extends BaseAdapter implements Filterable { } else { LayoutInflater inflater = (LayoutInflater) activity .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - convertView = inflater.inflate(R.layout.dropdown_item_singleline, parent, false); + convertView = inflater.inflate(R.layout.item_autocomplete_dropdown, parent, false); holder = new ViewHolder(convertView); convertView.setTag(holder); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/exception/ExceptionActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/exception/ExceptionActivity.java index 5b558e304..f121a89b4 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/exception/ExceptionActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/exception/ExceptionActivity.java @@ -14,6 +14,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.Objects; +import butterknife.BindString; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -30,6 +31,12 @@ public class ExceptionActivity extends AppCompatActivity { TextView message; @BindView(R.id.stacktrace) TextView stacktrace; + @BindString(R.string.error) + String title; + @BindString(R.string.simple_exception) + String exception; + @BindString(R.string.copied_to_clipboard) + String copiedToClipboard; public static final String KEY_THROWABLE = "T"; @@ -41,7 +48,7 @@ public class ExceptionActivity extends AppCompatActivity { throwable = ((Throwable) getIntent().getSerializableExtra(KEY_THROWABLE)); throwable.printStackTrace(); setSupportActionBar(toolbar); - Objects.requireNonNull(getSupportActionBar()).setTitle(getString(R.string.error)); + Objects.requireNonNull(getSupportActionBar()).setTitle(title); this.message.setText(throwable.getMessage()); this.stacktrace.setText("Version: " + BuildConfig.VERSION_NAME + "\n\n" + getStacktraceOf(throwable)); } @@ -56,9 +63,9 @@ public class ExceptionActivity extends AppCompatActivity { @OnClick(R.id.copy) void copyStacktraceToClipboard() { final android.content.ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); - ClipData clipData = ClipData.newPlainText(getString(R.string.simple_exception), this.stacktrace.getText()); + ClipData clipData = ClipData.newPlainText(exception, this.stacktrace.getText()); clipboardManager.setPrimaryClip(clipData); - Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show(); + Toast.makeText(this, copiedToClipboard, Toast.LENGTH_SHORT).show(); } @OnClick(R.id.close) diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/helper/dnd/CrossTabDragAndDrop.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/helper/dnd/CrossTabDragAndDrop.java index 002a0e6ae..e8f076cb6 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/helper/dnd/CrossTabDragAndDrop.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/helper/dnd/CrossTabDragAndDrop.java @@ -14,6 +14,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import butterknife.BindInt; +import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.model.full.FullCard; @@ -30,22 +32,28 @@ public class CrossTabDragAndDrop { private final Activity activity; private final float pxToReact; - private final long msToReact; - private final long msToReactOnMove; private long lastSwap = 0; private long lastMove = 0; + @BindInt(R.integer.drag_n_drop_dp_to_react) + int dragAndDropDPtoReact; + @BindInt(R.integer.drag_n_drop_dp_to_react_top_bottom) + int dragAndDropDPtoReactTopBottom; + @BindInt(R.integer.drag_n_drop_ms_to_react) + int msToReact; + @BindInt(R.integer.drag_n_drop_dp_to_react_top_bottom) + int msToReactOnMove; + private final float pxToReactTopBottom; private final Set<CardMovedByDragListener> moveListenerList = new HashSet<>(1); public CrossTabDragAndDrop(Activity activity) { this.activity = activity; + ButterKnife.bind(this, activity); final float density = activity.getResources().getDisplayMetrics().density; - this.pxToReact = activity.getResources().getInteger(R.integer.drag_n_drop_dp_to_react) * density; - this.pxToReactTopBottom = activity.getResources().getInteger(R.integer.drag_n_drop_dp_to_react_top_bottom) * density; - this.msToReact = activity.getResources().getInteger(R.integer.drag_n_drop_ms_to_react); - this.msToReactOnMove = activity.getResources().getInteger(R.integer.drag_n_drop_ms_to_react_on_move); + this.pxToReact = dragAndDropDPtoReact * density; + this.pxToReactTopBottom = dragAndDropDPtoReactTopBottom * density; } public void register(final ViewPager viewPager) { diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/settings/SettingsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/settings/SettingsFragment.java index 120d619bf..bf9e13213 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/settings/SettingsFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/settings/SettingsFragment.java @@ -8,24 +8,35 @@ import android.preference.SwitchPreference; import androidx.annotation.Nullable; +import butterknife.BindString; +import butterknife.ButterKnife; import it.niedermann.nextcloud.deck.Application; import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; public class SettingsFragment extends PreferenceFragment { + + @BindString(R.string.pref_key_wifi_only) + String prefKeyWifiOnly; + @BindString(R.string.pref_key_dark_theme) + String prefKeyDarkTheme; + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + ButterKnife.bind(this, getActivity()); + addPreferencesFromResource(R.xml.settings); - final SwitchPreference wifiOnlyPref = (SwitchPreference) findPreference(getString(R.string.pref_key_wifi_only)); + final SwitchPreference wifiOnlyPref = (SwitchPreference) findPreference(prefKeyWifiOnly); wifiOnlyPref.setOnPreferenceChangeListener((Preference preference, Object newValue) -> { Boolean syncOnWifiOnly = (Boolean) newValue; DeckLog.log("syncOnWifiOnly: " + syncOnWifiOnly); return true; }); - final SwitchPreference themePref = (SwitchPreference) findPreference(getString(R.string.pref_key_dark_theme)); + final SwitchPreference themePref = (SwitchPreference) findPreference(prefKeyDarkTheme); themePref.setOnPreferenceChangeListener((Preference preference, Object newValue) -> { Boolean darkTheme = (Boolean) newValue; DeckLog.log("darkTheme: " + darkTheme); diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 2067b75dc..005a6525c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -22,8 +22,7 @@ android:id="@+id/no_stacks" android:layout_width="match_parent" android:layout_height="match_parent" - android:visibility="gone" - tools:visibility="visible"> + android:visibility="gone"> <androidx.appcompat.widget.AppCompatImageView android:layout_width="match_parent" diff --git a/app/src/main/res/layout/dialog_board_share.xml b/app/src/main/res/layout/dialog_board_share.xml new file mode 100644 index 000000000..fb99d305b --- /dev/null +++ b/app/src/main/res/layout/dialog_board_share.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/peopleList" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="@dimen/standard_padding" + android:scrollbarStyle="outsideOverlay" + android:scrollbars="vertical" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + tools:listitem="@layout/item_access_control" /> +</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_card_edit_tab_activities.xml b/app/src/main/res/layout/fragment_card_edit_tab_activities.xml index 0196b211a..b1f519bfb 100644 --- a/app/src/main/res/layout/fragment_card_edit_tab_activities.xml +++ b/app/src/main/res/layout/fragment_card_edit_tab_activities.xml @@ -3,27 +3,22 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical"> - <ScrollView - android:id="@+id/scrollView" + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/activity_list" android:layout_width="match_parent" - android:layout_height="match_parent" - android:visibility="gone" - tools:visibility="gone"> - - <LinearLayout - android:id="@+id/activity_list" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" /> - </ScrollView> + android:layout_height="wrap_content" + android:scrollbars="vertical" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + tools:listitem="@layout/item_activity" /> - <RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto" + <RelativeLayout android:id="@+id/no_activities" android:layout_width="match_parent" android:layout_height="match_parent" - tools:visibility="visible"> + tools:visibility="gone"> <ImageView android:layout_width="match_parent" diff --git a/app/src/main/res/layout/fragment_card_edit_tab_attachments.xml b/app/src/main/res/layout/fragment_card_edit_tab_attachments.xml index 53a023b23..eb708bbed 100644 --- a/app/src/main/res/layout/fragment_card_edit_tab_attachments.xml +++ b/app/src/main/res/layout/fragment_card_edit_tab_attachments.xml @@ -3,22 +3,26 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:tools="http://schemas.android.com/tools" android:layout_marginTop="@dimen/standard_margin" android:orientation="vertical"> - <LinearLayout + <androidx.recyclerview.widget.RecyclerView android:id="@+id/attachments_list" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" - android:visibility="gone"> - </LinearLayout> + android:scrollbars="vertical" + android:visibility="gone" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + tools:listitem="@layout/item_attachment" + tools:visibility="visible" /> <RelativeLayout android:id="@+id/no_attachments" android:layout_width="match_parent" android:layout_height="match_parent" - android:visibility="gone"> + android:visibility="visible" + tools:visibility="gone"> <ImageView android:layout_width="match_parent" diff --git a/app/src/main/res/layout/fragment_stack.xml b/app/src/main/res/layout/fragment_stack.xml index 528bae8f9..d97653352 100644 --- a/app/src/main/res/layout/fragment_stack.xml +++ b/app/src/main/res/layout/fragment_stack.xml @@ -3,6 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical"> <androidx.swiperefreshlayout.widget.SwipeRefreshLayout @@ -58,7 +59,8 @@ android:paddingTop="@dimen/standard_half_padding" android:paddingBottom="@dimen/standard_half_padding" android:scrollbarStyle="outsideOverlay" - android:scrollbars="vertical" /> + android:scrollbars="vertical" + tools:listitem="@layout/item_card"/> </LinearLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/item_access_control.xml b/app/src/main/res/layout/item_access_control.xml new file mode 100644 index 000000000..291037118 --- /dev/null +++ b/app/src/main/res/layout/item_access_control.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:padding="@dimen/standard_padding"> + + <ImageView + android:layout_width="@dimen/avatar_size" + android:layout_height="match_parent" + android:layout_marginEnd="@dimen/standard_margin" + android:layout_marginRight="@dimen/standard_margin" + android:contentDescription="@null" + app:srcCompat="@drawable/ic_person_grey600_24dp" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <TextView + android:id="@+id/username" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="20sp" + tools:text="Username" /> + + <com.google.android.flexbox.FlexboxLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:flexWrap="wrap" + app:justifyContent="space_between"> + + <androidx.appcompat.widget.SwitchCompat + android:id="@+id/permission_edit" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:checked="true" + android:text="@string/edit" + app:switchPadding="@dimen/standard_half_margin" /> + + <androidx.appcompat.widget.SwitchCompat + android:id="@+id/permission_share" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/simple_share" + app:switchPadding="@dimen/standard_half_margin" /> + + <androidx.appcompat.widget.SwitchCompat + android:id="@+id/permission_manage" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:checked="true" + android:text="@string/simple_manage" + app:switchPadding="@dimen/standard_half_margin" /> + + </com.google.android.flexbox.FlexboxLayout> + </LinearLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_card_edit_tab_activity.xml b/app/src/main/res/layout/item_activity.xml index 09e9e6c38..9655f6a24 100644 --- a/app/src/main/res/layout/fragment_card_edit_tab_activity.xml +++ b/app/src/main/res/layout/item_activity.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:orientation="vertical" android:padding="@dimen/standard_padding"> @@ -23,8 +23,8 @@ <androidx.appcompat.widget.AppCompatImageView android:id="@+id/type" - android:layout_width="36dp" - android:layout_height="36dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_marginEnd="@dimen/standard_margin" android:layout_marginRight="@dimen/standard_margin" app:srcCompat="@drawable/type_change_36dp" /> diff --git a/app/src/main/res/layout/fragment_card_edit_tab_attachment.xml b/app/src/main/res/layout/item_attachment.xml index a2a14a9f9..a2a14a9f9 100644 --- a/app/src/main/res/layout/fragment_card_edit_tab_attachment.xml +++ b/app/src/main/res/layout/item_attachment.xml diff --git a/app/src/main/res/layout/dropdown_item_singleline.xml b/app/src/main/res/layout/item_autocomplete_dropdown.xml index ea2a589c4..fc3e51a7a 100644 --- a/app/src/main/res/layout/dropdown_item_singleline.xml +++ b/app/src/main/res/layout/item_autocomplete_dropdown.xml @@ -11,7 +11,7 @@ android:layout_height="40dp" android:layout_margin="@dimen/standard_margin" android:contentDescription="@null" - tools:src="@drawable/ic_close_circle_grey600" /> + tools:src="@drawable/ic_label_grey600_24dp" /> <TextView android:id="@+id/label" @@ -25,6 +25,6 @@ android:paddingEnd="@dimen/standard_padding" android:paddingRight="@dimen/standard_padding" android:textSize="18sp" - tools:text="TestUser One" /> + tools:text="Label" /> </LinearLayout> diff --git a/app/src/main/res/layout/fragment_card.xml b/app/src/main/res/layout/item_card.xml index 98b37bbce..98b37bbce 100644 --- a/app/src/main/res/layout/fragment_card.xml +++ b/app/src/main/res/layout/item_card.xml diff --git a/app/src/main/res/values/customization.xml b/app/src/main/res/values/customization.xml index 695b0d22d..444c6759e 100644 --- a/app/src/main/res/values/customization.xml +++ b/app/src/main/res/values/customization.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <resources> + <!-- How many avatars should be displayed in the card list view --> + <integer name="max_avatar_count">3</integer> <!-- How many labels are shown in the card list view before "..." --> <integer name="max_labels_shown">3</integer> <!-- How many characters of the labels are displayed at the card list view --> diff --git a/app/src/main/res/values/setup.xml b/app/src/main/res/values/setup.xml index 66aa2cefb..4da70f773 100644 --- a/app/src/main/res/values/setup.xml +++ b/app/src/main/res/values/setup.xml @@ -8,7 +8,7 @@ <!-- To be concatenated with the account id --> <string name="shared_preference_last_board_for_account_" translatable="false">it.niedermann.nextcloud.deck.last_board_for_account_</string> - <string name="shared_preference_last_stack_for_account_and_board" translatable="false">it.niedermann.nextcloud.deck.last_stack_for_board_</string> + <string name="shared_preference_last_stack_for_account_and_board_" translatable="false">it.niedermann.nextcloud.deck.last_stack_for_board_</string> <integer name="minimum_server_app_major" translatable="false">0</integer> <integer name="minimum_server_app_minor" translatable="false">6</integer> <integer name="minimum_server_app_patch" translatable="false">4</integer> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 565744320..576ab9608 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -144,4 +144,6 @@ <string name="rename_column">Rename column</string> <string name="share_board">Share board</string> <string name="you_are_currently_offline">You are currently offline</string> + <string name="simple_manage">manage</string> + <string name="simple_share">share</string> </resources> |