diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 383b88e9d..0ecbf9289 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -54,19 +54,14 @@ + + - - - - - - - serverShares) { - if(isATV()){ - - Intent tvIntent = new Intent(this,MainTVActivity.class); - - - if(serverApps!=null){ - ArrayList serverAppsArrayList = new ArrayList<>(serverApps); - tvIntent.putParcelableArrayListExtra(getString(R.string.intent_apps),serverAppsArrayList); - } - - if(serverShares!=null) { - ArrayList serverShareArrayList = new ArrayList<>(serverShares); - tvIntent.putParcelableArrayListExtra(getString(R.string.intent_shares),serverShareArrayList); - } - - if(servers!=null){ - ArrayList serverArrayList = new ArrayList<>(servers); - tvIntent.putParcelableArrayListExtra(getString(R.string.intent_servers),serverArrayList); - } - startActivity(tvIntent); - } - } - - List serverApps; - List servers; - - @Override - public void passApps(List serverApps) { - if(isATV()) - this.serverApps = serverApps; - } - - @Override - public void passServer(List serverList) { - if(isATV()) - servers = serverList; - } -} \ No newline at end of file +public class NavigationActivity extends AppCompatActivity implements DrawerLayout.DrawerListener { + private static final class State { + private State() { + } + + public static final String NAVIGATION_TITLE = "navigation_title"; + public static final String NAVIGATION_DRAWER_VISIBLE = "navigation_drawer_visible"; + } + + @Inject + ServerClient serverClient; + + private ActionBarDrawerToggle navigationDrawerToggle; + private String navigationTitle; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_navigation); + + if (CheckTV.isATV(this)) { + showTvLoading(); + } + + setUpInjections(); + + setUpHomeNavigation(); + + setUpNavigation(savedInstanceState); + } + + private void showTvLoading() { + + inflateStubs(); + + hideMobileContainers(); + + hideActionBar(); + + setUpNavigationFragment(); + + setUpShares(); + } + + private void inflateStubs(){ + ViewStub tvLoadingStub = (ViewStub)findViewById(R.id.view_stub_tv_loading); + tvLoadingStub.inflate(); + } + + private void hideMobileContainers() { + RelativeLayout tvLoading = (RelativeLayout) findViewById(R.id.tv_loading); + + getContainerContent().setVisibility(View.INVISIBLE); + + getContainerNavigation().setVisibility(View.INVISIBLE); + + displayTvLoading(tvLoading); + } + + private FrameLayout getContainerContent() { + return (FrameLayout) findViewById(R.id.container_content); + } + + private FrameLayout getContainerNavigation() { + return (FrameLayout) findViewById(R.id.container_navigation); + } + + private void displayTvLoading(RelativeLayout tvLoading) { + tvLoading.setVisibility(View.VISIBLE); + } + + private void hideActionBar() { + getSupportActionBar().hide(); + } + + private void setUpInjections() { + AmahiApplication.from(this).inject(this); + } + + private void setUpHomeNavigation() { + getSupportActionBar().setHomeButtonEnabled(isNavigationDrawerAvailable()); + getSupportActionBar().setDisplayHomeAsUpEnabled(isNavigationDrawerAvailable()); + getSupportActionBar().setIcon(R.drawable.ic_launcher); + } + + private boolean isNavigationDrawerAvailable() { + return !Android.isTablet(this); + } + + private void setUpNavigation(Bundle state) { + if (isNavigationDrawerAvailable()) { + setUpNavigationDrawer(); + } + + if (!CheckTV.isATV(this)) setUpNavigationFragment(); + + if (isNavigationDrawerAvailable() && isNavigationDrawerRequired(state)) { + showNavigationDrawer(); + } + + setUpNavigationTitle(state); + } + + private void setUpNavigationDrawer() { + this.navigationDrawerToggle = buildNavigationDrawerToggle(); + + getDrawer().addDrawerListener(this); + getDrawer().setDrawerShadow(R.drawable.bg_shadow_drawer, Gravity.START); + } + + private ActionBarDrawerToggle buildNavigationDrawerToggle() { + return new ActionBarDrawerToggle(this, getDrawer(), R.string.menu_navigation_open, R.string.menu_navigation_close); + } + + private DrawerLayout getDrawer() { + return (DrawerLayout) findViewById(R.id.drawer_content); + } + + @Override + public void onDrawerOpened(View drawer) { + navigationDrawerToggle.onDrawerOpened(drawer); + + setUpTitle(getString(R.string.application_name)); + } + + private void setUpTitle(String title) { + if (isNavigationDrawerAvailable()) { + getSupportActionBar().setTitle(title); + } + } + + @Override + public void onDrawerClosed(View drawer) { + navigationDrawerToggle.onDrawerClosed(drawer); + + setUpTitle(); + } + + @Override + public void onDrawerSlide(View drawer, float slideOffset) { + navigationDrawerToggle.onDrawerSlide(drawer, slideOffset); + } + + @Override + public void onDrawerStateChanged(int state) { + navigationDrawerToggle.onDrawerStateChanged(state); + } + + private void setUpNavigationTitle(Bundle state) { + this.navigationTitle = getNavigationTitle(state); + + if (isNavigationDrawerAvailable() && !isNavigationDrawerOpen()) { + setUpTitle(); + } + } + + private String getNavigationTitle(Bundle state) { + if (isNavigationStateValid(state)) { + return state.getString(State.NAVIGATION_TITLE); + } else { + return getString(R.string.application_name); + } + } + + private boolean isNavigationStateValid(Bundle state) { + return (state != null) && state.containsKey(State.NAVIGATION_TITLE); + } + + private void setUpNavigationFragment() { + Fragments.Operator.at(this).set(buildNavigationFragment(), R.id.container_navigation); + } + + private Fragment buildNavigationFragment() { + return Fragments.Builder.buildNavigationFragment(); + } + + private boolean isNavigationDrawerRequired(Bundle state) { + return (state == null) || state.getBoolean(State.NAVIGATION_DRAWER_VISIBLE); + } + + private void showNavigationDrawer() { + if (!CheckTV.isATV(this)) + getDrawer().openDrawer(findViewById(R.id.container_navigation)); + } + + @Subscribe + public void onSharesSelected(SharesSelectedEvent event) { + this.navigationTitle = getString(R.string.title_shares); + + if (isNavigationDrawerAvailable()) { + setUpTitle(); + } + + setUpShares(); + + if (isNavigationDrawerAvailable()) { + hideNavigationDrawer(); + } + } + + private void setUpTitle() { + setUpTitle(navigationTitle); + } + + private void setUpShares() { + Fragments.Operator.at(this).replace(buildSharesFragment(), R.id.container_content); + } + + private Fragment buildSharesFragment() { + return Fragments.Builder.buildServerSharesFragment(); + } + + private void hideNavigationDrawer() { + getDrawer().closeDrawers(); + } + + @Subscribe + public void onAppsSelected(AppsSelectedEvent event) { + this.navigationTitle = getString(R.string.title_apps); + + if (isNavigationDrawerAvailable()) { + setUpTitle(); + } + + setUpApps(); + + if (isNavigationDrawerAvailable()) { + hideNavigationDrawer(); + } + } + + private void setUpApps() { + Fragments.Operator.at(this).replace(buildAppsFragment(), R.id.container_content); + } + + private Fragment buildAppsFragment() { + return Fragments.Builder.buildServerAppsFragment(); + } + + @Subscribe + public void onShareSelected(ShareSelectedEvent event) { + setUpShare(event.getShare()); + } + + private void setUpShare(ServerShare share) { + Intent intent = Intents.Builder.with(this).buildServerFilesActivity(share); + startActivity(intent); + } + + @Subscribe + public void onAppSelected(AppSelectedEvent event) { + setUpApp(event.getApp()); + } + + private void setUpApp(ServerApp app) { + Intent intent = Intents.Builder.with(this).buildServerAppAcitivity(app); + startActivity(intent); + } + + @Subscribe + public void onSettingsSelected(SettingsSelectedEvent event) { + setUpSettings(); + } + + private void setUpSettings() { + Intent intent = Intents.Builder.with(this).buildSettingsIntent(); + startActivity(intent); + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + + if (isNavigationDrawerAvailable()) { + navigationDrawerToggle.syncState(); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + if (isNavigationDrawerAvailable() && navigationDrawerToggle.onOptionsItemSelected(menuItem)) { + return true; + } + + return super.onOptionsItemSelected(menuItem); + } + + @Override + public void onConfigurationChanged(Configuration configuration) { + super.onConfigurationChanged(configuration); + + if (isNavigationDrawerAvailable()) { + navigationDrawerToggle.onConfigurationChanged(configuration); + } + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + + tearDownNavigationState(outState); + } + + private void tearDownNavigationState(Bundle state) { + state.putString(State.NAVIGATION_TITLE, navigationTitle); + state.putBoolean(State.NAVIGATION_DRAWER_VISIBLE, isNavigationDrawerAvailable() && isNavigationDrawerOpen()); + } + + private boolean isNavigationDrawerOpen() { + return getDrawer().isDrawerOpen(findViewById(R.id.container_navigation)); + } + + @Override + protected void onResume() { + super.onResume(); + + BusProvider.getBus().register(this); + } + + @Override + protected void onPause() { + super.onPause(); + + BusProvider.getBus().unregister(this); + } +} diff --git a/src/main/java/org/amahi/anywhere/activity/RedirectActivity.java b/src/main/java/org/amahi/anywhere/activity/RedirectActivity.java deleted file mode 100644 index 4e9bddf9a..000000000 --- a/src/main/java/org/amahi/anywhere/activity/RedirectActivity.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.amahi.anywhere.activity; - -import android.content.Intent; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; - -import org.amahi.anywhere.R; - -public class RedirectActivity extends AppCompatActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_redirect); - startActivity(new Intent(this, NavigationActivity.class)); - } -} diff --git a/src/main/java/org/amahi/anywhere/activity/ServerFilesActivity.java b/src/main/java/org/amahi/anywhere/activity/ServerFilesActivity.java index 781d21d46..d456f09fd 100644 --- a/src/main/java/org/amahi/anywhere/activity/ServerFilesActivity.java +++ b/src/main/java/org/amahi/anywhere/activity/ServerFilesActivity.java @@ -37,6 +37,7 @@ import org.amahi.anywhere.bus.ServerFileSharingEvent; import org.amahi.anywhere.fragment.ServerFileDownloadingFragment; import org.amahi.anywhere.fragment.GooglePlaySearchFragment; +import org.amahi.anywhere.fragment.ServerFilesFragment; import org.amahi.anywhere.server.client.ServerClient; import org.amahi.anywhere.server.model.ServerFile; import org.amahi.anywhere.server.model.ServerShare; diff --git a/src/main/java/org/amahi/anywhere/bus/ServerConnectedEvent.java b/src/main/java/org/amahi/anywhere/bus/ServerConnectedEvent.java index a757c0412..729a7e734 100644 --- a/src/main/java/org/amahi/anywhere/bus/ServerConnectedEvent.java +++ b/src/main/java/org/amahi/anywhere/bus/ServerConnectedEvent.java @@ -19,5 +19,16 @@ package org.amahi.anywhere.bus; +import org.amahi.anywhere.server.model.Server; + public class ServerConnectedEvent implements BusEvent { + public Server server; + + public ServerConnectedEvent(Server server){ + this.server = server; + } + + public Server getServer() { + return server; + } } diff --git a/src/main/java/org/amahi/anywhere/fragment/NavigationFragment.java b/src/main/java/org/amahi/anywhere/fragment/NavigationFragment.java index 183f2f625..812e0db6a 100644 --- a/src/main/java/org/amahi/anywhere/fragment/NavigationFragment.java +++ b/src/main/java/org/amahi/anywhere/fragment/NavigationFragment.java @@ -26,16 +26,15 @@ import android.accounts.AuthenticatorException; import android.accounts.OnAccountsUpdateListener; import android.accounts.OperationCanceledException; -import android.content.Context; -import android.support.v4.app.Fragment; +import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Parcelable; import android.preference.PreferenceManager; +import android.support.v4.app.Fragment; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -44,6 +43,7 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.Spinner; +import android.widget.Toast; import com.squareup.otto.Subscribe; @@ -63,6 +63,9 @@ import org.amahi.anywhere.server.client.AmahiClient; import org.amahi.anywhere.server.client.ServerClient; import org.amahi.anywhere.server.model.Server; +import org.amahi.anywhere.tv.activity.MainTVActivity; +import org.amahi.anywhere.util.CheckTV; +import org.amahi.anywhere.util.Preferences; import org.amahi.anywhere.util.RecyclerItemClickListener; import org.amahi.anywhere.util.ViewDirector; @@ -89,18 +92,16 @@ private State() { public static final String SERVERS = "servers"; } - public interface passServerEvent{ - void passServer(List serverList); - } - - private passServerEvent passServerEventListener; - @Inject AmahiClient amahiClient; @Inject ServerClient serverClient; + private Intent tvIntent; + + private List mServerList; + @Override public View onCreateView(LayoutInflater layoutInflater, ViewGroup container, Bundle savedInstanceState) { return layoutInflater.inflate(R.layout.fragment_navigation, container, false); @@ -283,25 +284,19 @@ private void setUpServersContent(String authenticationToken) { amahiClient.getServers(authenticationToken); } - @Override - public void onAttach(Context context) { - super.onAttach(context); - try { - passServerEventListener = (passServerEvent)context; - } catch (ClassCastException e) { - throw new ClassCastException(context.toString() + " must implement passServerEventListener"); - } - } - @Subscribe public void onServersLoaded(ServersLoadedEvent event) { setUpServersContent(event.getServers()); - //FRAGMENT CALLBACK - passServerEventListener.passServer(filterActiveServers(event.getServers())); - setUpNavigation(); + showContent(); + + mServerList = event.getServers(); + + tvIntent = new Intent(getContext(), MainTVActivity.class); + + tvIntent.putParcelableArrayListExtra(getString(R.string.intent_servers), new ArrayList<>(event.getServers())); } private SwipeRefreshLayout getRefreshLayout() { @@ -392,6 +387,7 @@ private void setUpServerConnection(Server server) { public void onServerConnected(ServerConnectedEvent event) { setUpServerConnection(); setUpServerNavigation(); + setUpTvServer(event); } private void setUpServerConnection() { @@ -407,6 +403,23 @@ private void setUpServerConnection() { } } + private void setUpTvServer(ServerConnectedEvent event){ + if(CheckTV.isATV(getActivity())) { + String serverName = Preferences.getPreference(getContext()).getString(getString(R.string.pref_server_select_key), mServerList.get(0).getName()); + if (serverName.matches(event.getServer().getName())) { + Toast.makeText(getContext(), serverName, Toast.LENGTH_SHORT).show(); + launchTV(); + } else { + int i = 0; + for (; i < mServerList.size(); i++) + if (mServerList.get(i).getName().matches(serverName)) break; + serverClient.connect(mServerList.get(i)); + } + } + } + + private void launchTV(){startActivity(tvIntent);} + private boolean isConnectionAvailable() { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); diff --git a/src/main/java/org/amahi/anywhere/fragment/ServerAppsFragment.java b/src/main/java/org/amahi/anywhere/fragment/ServerAppsFragment.java index 755c3eeb5..84dd80374 100644 --- a/src/main/java/org/amahi/anywhere/fragment/ServerAppsFragment.java +++ b/src/main/java/org/amahi/anywhere/fragment/ServerAppsFragment.java @@ -62,10 +62,6 @@ private State() { public static final String APPS = "apps"; } - public interface passAppsEvent{ - void passApps(List serverApps); - } - private ServerAppsAdapter mServerAppsAdapter; private RecyclerView mRecyclerView; @@ -74,7 +70,6 @@ public interface passAppsEvent{ private LinearLayout mErrorLinearLayout; - private passAppsEvent passAppsEventListener; @Inject ServerClient serverClient; @@ -163,16 +158,6 @@ private void setUpAppsContent() { } } - @Override - public void onAttach(Context context) { - super.onAttach(context); - try { - passAppsEventListener = (passAppsEvent) context; - } catch (ClassCastException e) { - throw new ClassCastException(context.toString() + " must implement passAppsEventListener"); - } - } - @Subscribe public void onServerConnectionChanged(ServerConnectionChangedEvent event) { serverClient.getApps(); @@ -182,9 +167,6 @@ public void onServerConnectionChanged(ServerConnectionChangedEvent event) { public void onAppsLoaded(ServerAppsLoadedEvent event) { setUpAppsContent(event.getServerApps()); - //FRAGMENT CALLBACK - passAppsEventListener.passApps(event.getServerApps()); - showAppsContent(); } diff --git a/src/main/java/org/amahi/anywhere/fragment/ServerFilesFragment.java b/src/main/java/org/amahi/anywhere/fragment/ServerFilesFragment.java index d17d4ea78..f6148e378 100644 --- a/src/main/java/org/amahi/anywhere/fragment/ServerFilesFragment.java +++ b/src/main/java/org/amahi/anywhere/fragment/ServerFilesFragment.java @@ -21,9 +21,11 @@ import android.Manifest; import android.app.SearchManager; +import android.app.UiModeManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.res.Configuration; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -76,6 +78,7 @@ import javax.inject.Inject; +import static android.content.Context.UI_MODE_SERVICE; import static android.support.v4.content.PermissionChecker.checkSelfPermission; /** diff --git a/src/main/java/org/amahi/anywhere/fragment/ServerSharesFragment.java b/src/main/java/org/amahi/anywhere/fragment/ServerSharesFragment.java index 1528c3697..8835612f2 100644 --- a/src/main/java/org/amahi/anywhere/fragment/ServerSharesFragment.java +++ b/src/main/java/org/amahi/anywhere/fragment/ServerSharesFragment.java @@ -19,7 +19,6 @@ package org.amahi.anywhere.fragment; -import android.content.Context; import android.os.Bundle; import android.os.Parcelable; import android.support.v4.app.Fragment; @@ -54,10 +53,6 @@ */ public class ServerSharesFragment extends Fragment { - public interface passShareEvent{ - void passShare(List serverShares); - } - private static final class State { private State() { @@ -74,7 +69,6 @@ private State() { private LinearLayout mErrorLinearLayout; - private passShareEvent passShareEventListener; @Inject ServerClient serverClient; @@ -169,16 +163,6 @@ private void setUpSharesContent() { } } - @Override - public void onAttach(Context context) { - super.onAttach(context); - try { - passShareEventListener = (passShareEvent) context; - } catch (ClassCastException e) { - throw new ClassCastException(context.toString() + " must implement onSomeEventListener"); - } - } - @Subscribe public void onServerConnectionChanged(ServerConnectionChangedEvent event) { serverClient.getShares(); @@ -187,7 +171,6 @@ public void onServerConnectionChanged(ServerConnectionChangedEvent event) { @Subscribe public void onSharesLoaded(ServerSharesLoadedEvent event) { setUpSharesContent(event.getServerShares()); - passShareEventListener.passShare(event.getServerShares()); showSharesContent(); } diff --git a/src/main/java/org/amahi/anywhere/server/client/ServerClient.java b/src/main/java/org/amahi/anywhere/server/client/ServerClient.java index 446250d71..773644078 100644 --- a/src/main/java/org/amahi/anywhere/server/client/ServerClient.java +++ b/src/main/java/org/amahi/anywhere/server/client/ServerClient.java @@ -166,7 +166,7 @@ public void onServerRouteLoaded(ServerRouteLoadedEvent event) { } private void finishServerConnection() { - BusProvider.getBus().post(new ServerConnectedEvent()); + BusProvider.getBus().post(new ServerConnectedEvent(server)); } public void connectAuto() { @@ -208,7 +208,7 @@ public void getFiles(ServerShare share) { return; } - serverApi.getFiles(server.getSession(), share.getName(), null).enqueue(new ServerFilesResponse(null)); + serverApi.getFiles(server.getSession(), share.getName(), null).enqueue(new ServerFilesResponse(share)); } public void getFiles(ServerShare share, ServerFile directory) { diff --git a/src/main/java/org/amahi/anywhere/server/model/ServerFile.java b/src/main/java/org/amahi/anywhere/server/model/ServerFile.java index 845c0c919..e4087b3c1 100644 --- a/src/main/java/org/amahi/anywhere/server/model/ServerFile.java +++ b/src/main/java/org/amahi/anywhere/server/model/ServerFile.java @@ -33,6 +33,7 @@ public class ServerFile implements Parcelable { private ServerFile parentFile; + private ServerShare parentShare; @SerializedName("name") private String name; @@ -58,6 +59,12 @@ public void setParentFile(ServerFile parentFile) { this.parentFile = parentFile; } + public void setParentShare(ServerShare parentShare){ + this.parentShare = parentShare; + } + + public ServerShare getParentShare(){return parentShare;} + public ServerFile getParentFile() { return parentFile; } diff --git a/src/main/java/org/amahi/anywhere/server/response/ServerFilesResponse.java b/src/main/java/org/amahi/anywhere/server/response/ServerFilesResponse.java index 4cb300128..1fdd44641 100644 --- a/src/main/java/org/amahi/anywhere/server/response/ServerFilesResponse.java +++ b/src/main/java/org/amahi/anywhere/server/response/ServerFilesResponse.java @@ -19,10 +19,13 @@ package org.amahi.anywhere.server.response; +import android.util.Log; + import org.amahi.anywhere.bus.BusProvider; import org.amahi.anywhere.bus.ServerFilesLoadFailedEvent; import org.amahi.anywhere.bus.ServerFilesLoadedEvent; import org.amahi.anywhere.server.model.ServerFile; +import org.amahi.anywhere.server.model.ServerShare; import java.util.Collections; import java.util.List; @@ -39,12 +42,17 @@ */ public class ServerFilesResponse implements Callback> { - private final ServerFile serverDirectory; + private ServerFile serverDirectory; + private ServerShare serverShare; public ServerFilesResponse(ServerFile serverDirectory) { this.serverDirectory = serverDirectory; } + public ServerFilesResponse(ServerShare serverShare){ + this.serverShare = serverShare; + } + @Override public void onResponse(Call> call, Response> response) { if (response.isSuccessful()) { @@ -55,6 +63,7 @@ public void onResponse(Call> call, Response> r for (ServerFile serverFile : serverFiles) { serverFile.setParentFile(serverDirectory); + serverFile.setParentShare(serverShare); } BusProvider.getBus().post(new ServerFilesLoadedEvent(serverFiles)); diff --git a/src/main/java/org/amahi/anywhere/tv/activity/MainTVActivity.java b/src/main/java/org/amahi/anywhere/tv/activity/MainTVActivity.java index 62add1ff6..77f5c49cb 100644 --- a/src/main/java/org/amahi/anywhere/tv/activity/MainTVActivity.java +++ b/src/main/java/org/amahi/anywhere/tv/activity/MainTVActivity.java @@ -24,6 +24,8 @@ import android.os.Bundle; import org.amahi.anywhere.R; +import org.amahi.anywhere.tv.fragment.MainTVFragment; +import org.amahi.anywhere.util.Preferences; public class MainTVActivity extends Activity { @@ -31,6 +33,17 @@ public class MainTVActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_tv); + handleTvFirstRun(); + getFragmentManager().beginTransaction().add(R.id.main_tv_fragment_container, new MainTVFragment()).commit(); + } + + private void handleTvFirstRun() { + Boolean isFirstRun = Preferences.getFirstRun(this); + + if (isFirstRun) { + startActivity(new Intent(MainTVActivity.this, IntroActivity.class)); + Preferences.setFirstRun(this); + } } @@ -38,7 +51,7 @@ protected void onCreate(Bundle savedInstanceState) { public void onBackPressed() { super.onBackPressed(); Intent homeIntent = new Intent(Intent.ACTION_MAIN); - homeIntent.addCategory( Intent.CATEGORY_HOME ); + homeIntent.addCategory(Intent.CATEGORY_HOME); homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(homeIntent); } diff --git a/src/main/java/org/amahi/anywhere/tv/activity/SettingsActivity.java b/src/main/java/org/amahi/anywhere/tv/activity/SettingsActivity.java index 64aee3030..415c36bbd 100644 --- a/src/main/java/org/amahi/anywhere/tv/activity/SettingsActivity.java +++ b/src/main/java/org/amahi/anywhere/tv/activity/SettingsActivity.java @@ -27,6 +27,7 @@ import org.amahi.anywhere.R; import org.amahi.anywhere.tv.fragment.ConnectionFragment; +import org.amahi.anywhere.tv.fragment.ServerSelectFragment; import org.amahi.anywhere.tv.fragment.SignOutFragment; import org.amahi.anywhere.tv.fragment.ThemeFragment; @@ -37,16 +38,38 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { String settingsType = getIntent().getStringExtra(Intent.EXTRA_TEXT); - if(savedInstanceState==null){ + if (settingsType.matches(getString(R.string.pref_title_server_select))) + buildServerSettingsFragment(); - if(settingsType.matches(getString(R.string.pref_title_sign_out))) - GuidedStepFragment.add(getFragmentManager(),new SignOutFragment(this)); + if (settingsType.matches(getString(R.string.pref_title_sign_out))) + buildSignOutSettingsFragment(); - if(settingsType.matches(getString(R.string.pref_title_connection))) - GuidedStepFragment.add(getFragmentManager(),new ConnectionFragment(this)); + if (settingsType.matches(getString(R.string.pref_title_connection))) + buildConnectionSettingsFragment(); - if(settingsType.matches(getString(R.string.pref_title_select_theme))) - GuidedStepFragment.add(getFragmentManager(),new ThemeFragment(this)); - } + if (settingsType.matches(getString(R.string.pref_title_select_theme))) + buildSelectThemeSettingsFragment(); + } + + private void buildServerSettingsFragment() { + GuidedStepFragment.add(getFragmentManager(), new ServerSelectFragment(this)); + } + + private void buildSignOutSettingsFragment() { + GuidedStepFragment.add(getFragmentManager(), new SignOutFragment(this)); + } + + private void buildConnectionSettingsFragment() { + GuidedStepFragment.add(getFragmentManager(), new ConnectionFragment(this)); + } + + private void buildSelectThemeSettingsFragment() { + GuidedStepFragment.add(getFragmentManager(), new ThemeFragment(this)); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + finish(); } } diff --git a/src/main/java/org/amahi/anywhere/tv/fragment/ConnectionFragment.java b/src/main/java/org/amahi/anywhere/tv/fragment/ConnectionFragment.java index a42bfd590..58d45ba93 100644 --- a/src/main/java/org/amahi/anywhere/tv/fragment/ConnectionFragment.java +++ b/src/main/java/org/amahi/anywhere/tv/fragment/ConnectionFragment.java @@ -22,68 +22,72 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; -import android.graphics.drawable.Drawable; +import android.content.SharedPreferences; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v17.leanback.app.GuidedStepFragment; import android.support.v17.leanback.widget.GuidanceStylist; import android.support.v17.leanback.widget.GuidedAction; -import android.widget.Toast; +import android.support.v4.content.ContextCompat; import org.amahi.anywhere.R; -import org.amahi.anywhere.tv.activity.SettingsActivity; +import org.amahi.anywhere.activity.NavigationActivity; +import org.amahi.anywhere.util.Preferences; +import java.util.ArrayList; import java.util.List; -public class ConnectionFragment extends GuidedStepFragment{ +public class ConnectionFragment extends GuidedStepFragment { private static final int OPTION_CHECK_SET_ID = 10; - - private final String[] OPTION_NAMES = { - "Autodetect", - - "Remote", - - "Local area network", - - "Go back" - }; - - private final String[] OPTION_DESCRIPTIONS = {"","","",""}; - - private final int[] OPTION_DRAWABLES = {R.drawable.ic_app_logo}; - - private final boolean[] OPTION_CHECKED = {true, false, false,false}; - + private static final int ACTION_BACK = 1; + private ArrayList OPTION_NAMES = new ArrayList<>(); + private ArrayList OPTION_DESCRIPTIONS = new ArrayList<>(); + private ArrayList OPTION_CHECKED = new ArrayList<>(); private Context mContext; + private SharedPreferences preference; - public ConnectionFragment(){} + public ConnectionFragment() { + } @SuppressLint("ValidFragment") - public ConnectionFragment(Context context){ + public ConnectionFragment(Context context) { mContext = context; + preference = getTVPreference(); + } + + private SharedPreferences getTVPreference() { + return Preferences.getTVPreference(mContext); } @NonNull @Override public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { - String title = getString(R.string.pref_title_connection); + return new GuidanceStylist.Guidance(getString(R.string.pref_title_connection), + getString(R.string.pref_connection_desc), + "", + ContextCompat.getDrawable(getActivity(), R.drawable.ic_app_logo)); + } + - String breadcrumb = ""; + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + setTitle(actions); - String description =getString(R.string.pref_connection_detail); + populateNames(); - Drawable icon = null; + populateDesc(); - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { - icon = getActivity().getDrawable(R.drawable.ic_app_logo); - } + String selected = getServerConnectionStatus(); - return new GuidanceStylist.Guidance(title, description, breadcrumb, icon); + markSelected(selected); + + setCheckedActionButtons(actions); + + setBackButton(actions); } - @Override - public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + private void setTitle(List actions) { String title = getString(R.string.pref_title_connection); String desc = getString(R.string.pref_connection_desc); @@ -95,24 +99,56 @@ public void onCreateActions(@NonNull List actions, Bundle savedIns .infoOnly(true) .enabled(false) .build()); + } - for (int i = 0; i < OPTION_NAMES.length; i++) { + private void populateNames() { + OPTION_NAMES.add(getString(R.string.preference_entry_server_connection_auto)); + OPTION_NAMES.add(getString(R.string.preference_entry_server_connection_remote)); + OPTION_NAMES.add(getString(R.string.preference_entry_server_connection_local)); + } + + private void populateDesc() { + for (int i = 0; i < 3; i++) { + OPTION_DESCRIPTIONS.add(""); + populateChecked(); + } + } + + private void populateChecked() { + OPTION_CHECKED.add(false); + } + + private String getServerConnectionStatus() { + return Preferences.getServerConnection(preference, mContext); + } + + private void markSelected(String selected) { + if (selected.matches(getString(R.string.preference_entry_server_connection_auto))) + OPTION_CHECKED.set(0, true); + if (selected.matches(getString(R.string.preference_entry_server_connection_remote))) + OPTION_CHECKED.set(1, true); + if (selected.matches(getString(R.string.preference_entry_server_connection_local))) + OPTION_CHECKED.set(2, true); + } + + private void setCheckedActionButtons(List actions) { + for (int i = 0; i < OPTION_NAMES.size(); i++) { addCheckedAction(actions, - OPTION_DRAWABLES[0], + R.drawable.ic_app_logo, getActivity(), - OPTION_NAMES[i], + OPTION_NAMES.get(i), - OPTION_DESCRIPTIONS[i], + OPTION_DESCRIPTIONS.get(i), - OPTION_CHECKED[i]); + OPTION_CHECKED.get(i)); } } private void addCheckedAction(List actions, int iconResId, Context context, - String title, String desc, boolean checked) { + String title, String desc, boolean checked) { GuidedAction guidedAction = new GuidedAction.Builder(context) .title(title) @@ -126,14 +162,35 @@ private void addCheckedAction(List actions, int iconResId, Context actions.add(guidedAction); } + private void setBackButton(List actions) { + addAction(actions, ACTION_BACK, getString(R.string.pref_option_go_back), ""); + } + + private void addAction(List actions, long id, String title, String desc) { + actions.add(new GuidedAction.Builder(mContext) + .id(id) + .title(title) + .description(desc) + .build()); + } + @Override public void onGuidedActionClicked(GuidedAction action) { - //This is temporary. - String text = OPTION_NAMES[getSelectedActionPosition() - 1] + " clicked"; - Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show(); - if(text.matches("Go back")){ - startActivity(new Intent(mContext, SettingsActivity.class)); + if (getSelectedActionPosition() <= 3) { + if (OPTION_NAMES.get(getSelectedActionPosition() - 1).matches(getString(R.string.preference_entry_server_connection_auto))) { + Preferences.setPrefAuto(preference, mContext); + } + + if (OPTION_NAMES.get(getSelectedActionPosition() - 1).matches(getString(R.string.preference_entry_server_connection_remote))) { + Preferences.setPrefRemote(preference, mContext); + } + + if (OPTION_NAMES.get(getSelectedActionPosition() - 1).matches(getString(R.string.preference_entry_server_connection_local))) { + Preferences.setPrefLocal(preference, mContext); + } + } else { + startActivity(new Intent(getActivity(), NavigationActivity.class)); } } } diff --git a/src/main/java/org/amahi/anywhere/tv/fragment/IntroFragment.java b/src/main/java/org/amahi/anywhere/tv/fragment/IntroFragment.java index a1b2d12dd..3c995e5cc 100644 --- a/src/main/java/org/amahi/anywhere/tv/fragment/IntroFragment.java +++ b/src/main/java/org/amahi/anywhere/tv/fragment/IntroFragment.java @@ -43,8 +43,6 @@ public class IntroFragment extends OnboardingFragment { - private ArrayList mTitles,mDescriptions; - private static final int[] CONTENT_IMAGES = { R.drawable.ic_app_logo, R.drawable.network, @@ -53,7 +51,7 @@ public class IntroFragment extends OnboardingFragment { R.drawable.movies, R.drawable.tick, }; - + private ArrayList mTitles, mDescriptions; private ArrayList mColors; private View mBackgroundView; @@ -141,6 +139,7 @@ protected View onCreateContentView(LayoutInflater inflater, ViewGroup container) protected View onCreateForegroundView(LayoutInflater inflater, ViewGroup container) { return null; } + @Override protected Animator onCreateEnterAnimation() { ArrayList animators = new ArrayList<>(); @@ -177,7 +176,7 @@ protected void onPageChanged(final int newPage, int previousPage) { public void onAnimationEnd(Animator animation) { Log.d(getClass().getName(), String.valueOf(newPage)); mContentView.setImageResource(CONTENT_IMAGES[newPage]); - switch (newPage){ + switch (newPage) { case 0: mBackgroundView.setBackground(new ColorDrawable(mColors.get(newPage))); break; diff --git a/src/main/java/org/amahi/anywhere/tv/fragment/MainTVFragment.java b/src/main/java/org/amahi/anywhere/tv/fragment/MainTVFragment.java index 3eb43a1c6..05ae396ec 100644 --- a/src/main/java/org/amahi/anywhere/tv/fragment/MainTVFragment.java +++ b/src/main/java/org/amahi/anywhere/tv/fragment/MainTVFragment.java @@ -26,36 +26,58 @@ import android.support.v17.leanback.widget.HeaderItem; import android.support.v17.leanback.widget.ListRow; import android.support.v17.leanback.widget.ListRowPresenter; +import android.widget.Toast; +import com.squareup.otto.Subscribe; + +import org.amahi.anywhere.AmahiApplication; import org.amahi.anywhere.R; -import org.amahi.anywhere.tv.presenter.CardPresenter; -import org.amahi.anywhere.tv.presenter.GridItemPresenter; -import org.amahi.anywhere.tv.presenter.SettingsItemPresenter; +import org.amahi.anywhere.bus.BusProvider; +import org.amahi.anywhere.bus.ServerConnectionChangedEvent; +import org.amahi.anywhere.bus.ServerFilesLoadedEvent; +import org.amahi.anywhere.bus.ServerSharesLoadFailedEvent; +import org.amahi.anywhere.bus.ServerSharesLoadedEvent; +import org.amahi.anywhere.server.client.ServerClient; import org.amahi.anywhere.server.model.Server; -import org.amahi.anywhere.server.model.ServerApp; +import org.amahi.anywhere.server.model.ServerFile; import org.amahi.anywhere.server.model.ServerShare; +import org.amahi.anywhere.tv.presenter.GridItemPresenter; +import org.amahi.anywhere.tv.presenter.SettingsItemPresenter; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import javax.inject.Inject; public class MainTVFragment extends BrowseFragment { - private ArrayList serverAppArrayList; - private ArrayList serverShareArrayList; - private ArrayList serverArrayList; + @Inject + ServerClient serverClient; + List serverShareList; + private FilesSort filesSort = FilesSort.MODIFICATION_TIME; + private ArrayObjectAdapter mRowsAdapter; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - serverAppArrayList = getActivity().getIntent().getParcelableArrayListExtra(getString(R.string.intent_apps)); + setUpInjections(); - serverShareArrayList = getActivity().getIntent().getParcelableArrayListExtra(getString(R.string.intent_shares)); + setupUIElements(); - serverArrayList = getActivity().getIntent().getParcelableArrayListExtra(getString(R.string.intent_servers)); + loadRows(); - setupUIElements(); + loadShares(); + } - loadRows(0); + private void setUpInjections() { + AmahiApplication.from(getActivity()).inject(this); + } + + private ArrayList getServers() { + return getActivity().getIntent().getParcelableArrayListExtra(getString(R.string.intent_servers)); } private void setupUIElements() { @@ -70,52 +92,131 @@ private void setupUIElements() { setSearchAffordanceColor(Color.GREEN); } - private void loadRows(int index) { - ArrayObjectAdapter mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); + private void loadRows() { + mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); + addSettings(mRowsAdapter); + addSeparator(mRowsAdapter); + } - HeaderItem server = new HeaderItem(index, getString(R.string.row_servers)); + private void loadShares() { + if (serverClient.isConnected()) { + serverClient.getShares(); + } + } - HeaderItem shares = new HeaderItem(index, getString(R.string.row_shares)); + @Subscribe + public void onServerConnectionChanged(ServerConnectionChangedEvent event) { + serverClient.getShares(); + } - HeaderItem apps = new HeaderItem(index, getString(R.string.row_apps)); + @Subscribe + public void onSharesLoaded(ServerSharesLoadedEvent event) { + List serverShareList = event.getServerShares(); + this.serverShareList = serverShareList; + for (int i = 0; i < serverShareList.size(); i++) { + serverClient.getFiles(serverShareList.get(i)); + } + } - HeaderItem settings = new HeaderItem(index,getString(R.string.row_preferences)); + @Subscribe + public void onFilesLoaded(ServerFilesLoadedEvent event) { + List serverFiles = sortFiles(event.getServerFiles()); + ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(new GridItemPresenter()); + if (serverFiles.size() != 0) { + String shareName = serverFiles.get(0).getParentShare().getName(); + for (int i = 0; i < serverFiles.size(); i++) { + gridRowAdapter.add(serverFiles.get(i).getName()); + } + int i; + + for (i = 0; i < serverShareList.size(); i++) { + if (shareName.matches(serverShareList.get(i).getName())) { + HeaderItem headerItem = new HeaderItem(shareName); + mRowsAdapter.add(new ListRow(headerItem, gridRowAdapter)); + serverShareList.remove(i); + } + } + } + setAdapter(mRowsAdapter); + } - GridItemPresenter mGridPresenter = new GridItemPresenter(); + private void addSeparator(ArrayObjectAdapter adapter) { + HeaderItem separator = new HeaderItem("-------------------------"); + adapter.add(new ListRow(separator, new ArrayObjectAdapter(new SettingsItemPresenter()))); + } - ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(mGridPresenter); + private void addSettings(ArrayObjectAdapter adapter) { + ArrayObjectAdapter gridRowAdapter; - if(serverArrayList!=null) - for(int i=0;i serverArrayList = getActivity().getIntent().getParcelableArrayListExtra(getString(R.string.intent_servers)); + gridRowAdapter = new ArrayObjectAdapter(new SettingsItemPresenter(serverArrayList)); + gridRowAdapter.add(getString(R.string.pref_title_server_select)); + gridRowAdapter.add(getString(R.string.pref_title_sign_out)); + gridRowAdapter.add(getString(R.string.pref_title_connection)); + gridRowAdapter.add(getString(R.string.pref_title_select_theme)); + adapter.add(new ListRow(settings, gridRowAdapter)); + } - mRowsAdapter.add(new ListRow(server, gridRowAdapter)); + private List sortFiles(List files) { + List sortedFiles = new ArrayList(files); - setAdapter(mRowsAdapter); + Collections.sort(sortedFiles, getFilesComparator()); - gridRowAdapter = new ArrayObjectAdapter(mGridPresenter); + return sortedFiles; + } - if(serverShareArrayList!=null) - for(int i=0;i getFilesComparator() { + switch (filesSort) { + case NAME: + return new FileNameComparator(); - mRowsAdapter.add(new ListRow(shares, gridRowAdapter)); + case MODIFICATION_TIME: + return new FileModificationTimeComparator(); - gridRowAdapter = new ArrayObjectAdapter(new CardPresenter()); + default: + return null; + } + } + + @Subscribe + public void onSharesLoadFailed(ServerSharesLoadFailedEvent event) { + showSharesError(); + } - if(serverAppArrayList!=null) - for(int i=0;i { + @Override + public int compare(ServerFile firstFile, ServerFile secondFile) { + return firstFile.getName().compareTo(secondFile.getName()); + } + } - mRowsAdapter.add(new ListRow(settings,gridRowAdapter)); + private static final class FileModificationTimeComparator implements Comparator { + @Override + public int compare(ServerFile firstFile, ServerFile secondFile) { + return -firstFile.getModificationTime().compareTo(secondFile.getModificationTime()); + } } -} \ No newline at end of file +} diff --git a/src/main/java/org/amahi/anywhere/tv/fragment/ServerSelectFragment.java b/src/main/java/org/amahi/anywhere/tv/fragment/ServerSelectFragment.java new file mode 100644 index 000000000..8218933bb --- /dev/null +++ b/src/main/java/org/amahi/anywhere/tv/fragment/ServerSelectFragment.java @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2014 Amahi + * + * This file is part of Amahi. + * + * Amahi is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Amahi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Amahi. If not, see . + */ + +package org.amahi.anywhere.tv.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v17.leanback.app.GuidedStepFragment; +import android.support.v17.leanback.widget.GuidanceStylist; +import android.support.v17.leanback.widget.GuidedAction; +import android.support.v4.content.ContextCompat; + +import org.amahi.anywhere.R; +import org.amahi.anywhere.activity.NavigationActivity; +import org.amahi.anywhere.server.model.Server; +import org.amahi.anywhere.util.Preferences; + +import java.util.ArrayList; +import java.util.List; + +public class ServerSelectFragment extends GuidedStepFragment { + + private static final int OPTION_CHECK_SET_ID = 10; + private static final int ACTION_BACK = 0; + private Context mContext; + private ArrayList mServerArrayList; + private ArrayList OPTION_NAMES = new ArrayList<>(); + private ArrayList OPTION_DESCRIPTIONS = new ArrayList<>(); + private ArrayList OPTION_CHECKED = new ArrayList<>(); + private SharedPreferences mSharedPref; + + @SuppressLint("ValidFragment") + public ServerSelectFragment(Context context) { + mContext = context; + } + + public ServerSelectFragment() { + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + } + + @NonNull + @Override + public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { + return new GuidanceStylist.Guidance(getString(R.string.pref_title_server_select), + getString(R.string.pref_title_server_select_desc), + "", + ContextCompat.getDrawable(getActivity(), R.drawable.ic_app_logo)); + } + + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + super.onCreateActions(actions, savedInstanceState); + mSharedPref = Preferences.getPreference(mContext); + mServerArrayList = getActivity().getIntent().getParcelableArrayListExtra(getString(R.string.intent_servers)); + setTitle(actions); + populateData(); + String serverName = Preferences.getServerFromPref(mContext, mSharedPref); + if (serverName == null) { + setDefaultChecked(); + } else { + int indexSelected = 0; + for (int i = 0; i < mServerArrayList.size(); i++) { + if (serverName.matches(mServerArrayList.get(i).getName())) { + indexSelected = i; + break; + } + } + setFalseChecked(); + OPTION_CHECKED.set(indexSelected, true); + } + + setCheckedActionButtons(actions); + setBackButton(actions); + } + + private void setTitle(List actions) { + String title = getString(R.string.pref_title_server_active_list); + + String desc = getString(R.string.pref_server_active_list_desc); + + actions.add(new GuidedAction.Builder(mContext) + .title(title) + .description(desc) + .multilineDescription(true) + .infoOnly(true) + .enabled(false) + .build()); + } + + private void populateData() { + for (int i = 0; i < mServerArrayList.size(); i++) { + setName(i); + setDesc(); + } + } + + private void setName(int i) { + OPTION_NAMES.add(mServerArrayList.get(i).getName()); + } + + private void setDesc() { + OPTION_DESCRIPTIONS.add(""); + } + + private void setDefaultChecked() { + OPTION_CHECKED.add(true); + for (int i = 1; i < mServerArrayList.size(); i++) + OPTION_CHECKED.add(false); + } + + private void setFalseChecked() { + if (OPTION_CHECKED != null) { + setFalse(); + } else { + OPTION_CHECKED.clear(); + setFalse(); + } + } + + private void setFalse() { + for (int i = 0; i < mServerArrayList.size(); i++) + OPTION_CHECKED.add(false); + } + + private void setCheckedActionButtons(List actions) { + for (int i = 0; i < OPTION_NAMES.size(); i++) { + addCheckedAction(actions, + + R.drawable.ic_app_logo, + + getActivity(), + + OPTION_NAMES.get(i), + + OPTION_DESCRIPTIONS.get(i), + + OPTION_CHECKED.get(i)); + } + } + + private void addCheckedAction(List actions, int iconResId, Context context, + String title, String desc, boolean checked) { + + GuidedAction guidedAction = new GuidedAction.Builder(context) + .title(title) + .description(desc) + .checkSetId(OPTION_CHECK_SET_ID) + .icon(iconResId) + .build(); + + guidedAction.setChecked(checked); + + actions.add(guidedAction); + } + + private void setBackButton(List actions) { + addAction(actions, ACTION_BACK, getString(R.string.pref_option_go_back), ""); + } + + private void addAction(List actions, long id, String title, String desc) { + actions.add(new GuidedAction.Builder(mContext) + .id(id) + .title(title) + .description(desc) + .build()); + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + if (getSelectedActionPosition() <= mServerArrayList.size()) { + String server = mServerArrayList.get(getSelectedActionPosition() - 1).getName(); + Preferences.setServertoPref(server, mContext, mSharedPref); + } else { + startActivity(new Intent(getActivity(), NavigationActivity.class)); + } + } +} diff --git a/src/main/java/org/amahi/anywhere/tv/fragment/SignOutFragment.java b/src/main/java/org/amahi/anywhere/tv/fragment/SignOutFragment.java index c95ac7d8c..7e534fba7 100644 --- a/src/main/java/org/amahi/anywhere/tv/fragment/SignOutFragment.java +++ b/src/main/java/org/amahi/anywhere/tv/fragment/SignOutFragment.java @@ -49,10 +49,13 @@ public class SignOutFragment extends GuidedStepFragment implements AccountManage private Context mContext; - public SignOutFragment(){} + public SignOutFragment() { + } @SuppressLint("ValidFragment") - public SignOutFragment(Context context){mContext = context;} + public SignOutFragment(Context context) { + mContext = context; + } @NonNull @Override @@ -73,7 +76,7 @@ public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { } @Override - public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { addAction(actions, ACTION_CONTINUE, getString(R.string.pref_title_sign_out), ""); @@ -83,7 +86,7 @@ public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { @Override public void onGuidedActionClicked(GuidedAction action) { - switch ((int) action.getId()){ + switch ((int) action.getId()) { case ACTION_CONTINUE: tearDownAccount(); break; @@ -98,7 +101,7 @@ public void onGuidedActionClicked(GuidedAction action) { } } - private void addAction(List actions, long id, String title, String desc) { + private void addAction(List actions, long id, String title, String desc) { actions.add(new GuidedAction.Builder(mContext) .id(id) .title(title) diff --git a/src/main/java/org/amahi/anywhere/tv/fragment/ThemeFragment.java b/src/main/java/org/amahi/anywhere/tv/fragment/ThemeFragment.java index a66fda47d..45b102fd2 100644 --- a/src/main/java/org/amahi/anywhere/tv/fragment/ThemeFragment.java +++ b/src/main/java/org/amahi/anywhere/tv/fragment/ThemeFragment.java @@ -21,59 +21,68 @@ import android.annotation.SuppressLint; import android.content.Context; -import android.content.Intent; -import android.graphics.drawable.Drawable; +import android.content.SharedPreferences; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v17.leanback.app.GuidedStepFragment; import android.support.v17.leanback.widget.GuidanceStylist; import android.support.v17.leanback.widget.GuidedAction; -import android.widget.Toast; +import android.support.v4.content.ContextCompat; import org.amahi.anywhere.R; -import org.amahi.anywhere.tv.activity.SettingsActivity; +import org.amahi.anywhere.util.Preferences; +import java.util.ArrayList; import java.util.List; public class ThemeFragment extends GuidedStepFragment { private static final int OPTION_CHECK_SET_ID = 10; - - private static final String[] OPTION_NAMES = {"Amahi Light", "Amahi Dark", "Go back"}; - - private static final String[] OPTION_DESCRIPTIONS = {"","",""}; - - private static final int[] OPTION_DRAWABLES = {R.drawable.ic_app_logo}; - - private static final boolean[] OPTION_CHECKED = {false, true, false}; - + private static final int ACTION_BACK = 1; + private ArrayList OPTION_NAMES = new ArrayList<>(); + private ArrayList OPTION_DESCRIPTIONS = new ArrayList<>(); + private ArrayList OPTION_CHECKED = new ArrayList<>(); private Context mContext; + private SharedPreferences mSharedPreferences; - public ThemeFragment(){} + public ThemeFragment() { + } @SuppressLint("ValidFragment") - public ThemeFragment(Context context){mContext=context;} + public ThemeFragment(Context context) { + mContext = context; + } @NonNull @Override public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { - String title = getString(R.string.pref_title_theme); + return new GuidanceStylist.Guidance(getString(R.string.pref_title_select_theme), + getString(R.string.pref_theme_desc), + "", + ContextCompat.getDrawable(getActivity(), R.drawable.ic_app_logo)); + } - String breadcrumb = ""; + @Override + public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { - String description =getString(R.string.pref_theme_desc); + setTitle(actions); - Drawable icon = null; + setPreference(); - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { - icon = getActivity().getDrawable(R.drawable.ic_app_logo); - } + setOPTION_NAMES(); + + setOptionDesc(); + + String prefCheck = mSharedPreferences.getString(getString(R.string.pref_key_theme), getString(R.string.pref_theme_dark)); - return new GuidanceStylist.Guidance(title, description, breadcrumb, icon); + setChecked(prefCheck); + + setCheckedActionButtons(actions); + + setBackButton(actions); } - @Override - public void onCreateActions(@NonNull List actions, Bundle savedInstanceState) { + private void setTitle(List actions) { String title = getString(R.string.pref_title_theme); String desc = getString(R.string.pref_theme_detail_desc); @@ -86,30 +95,48 @@ public void onCreateActions(@NonNull List actions, Bundle savedIns .enabled(false) .build()); - for (int i = 0; i < OPTION_NAMES.length; i++) { + } - addCheckedAction(actions, + private void setPreference() { + mSharedPreferences = Preferences.getPreference(mContext); + } - OPTION_DRAWABLES[0], + private void setOPTION_NAMES() { + OPTION_NAMES.add(getString(R.string.pref_theme_light)); + OPTION_NAMES.add(getString(R.string.pref_theme_dark)); + } - getActivity(), + private void setOptionDesc() { + for (int i = 0; i < 2; i++) { + OPTION_DESCRIPTIONS.add(""); + setOptionCheck(); + } + } - OPTION_NAMES[i], + private void setOptionCheck() { + OPTION_CHECKED.add(false); + } - OPTION_DESCRIPTIONS[i], + private void setChecked(String prefCheck) { + if (prefCheck.matches(getString(R.string.pref_theme_light))) OPTION_CHECKED.set(0, true); - OPTION_CHECKED[i]); - } + if (prefCheck.matches(getString(R.string.pref_theme_dark))) OPTION_CHECKED.set(1, true); } - @Override - public void onGuidedActionClicked(GuidedAction action) { - //This is temporary. - String text = OPTION_NAMES[getSelectedActionPosition() - 1] + " clicked"; - Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show(); + private void setCheckedActionButtons(List actions) { + for (int i = 0; i < OPTION_NAMES.size(); i++) { + addCheckedAction(actions, + + R.drawable.ic_app_logo, + + getActivity(), + + OPTION_NAMES.get(i), - if(text.matches(getString(R.string.pref_option_go_back))) - startActivity(new Intent(mContext, SettingsActivity.class)); + OPTION_DESCRIPTIONS.get(i), + + OPTION_CHECKED.get(i)); + } } private void addCheckedAction(List actions, int iconResId, Context context, @@ -126,4 +153,34 @@ private void addCheckedAction(List actions, int iconResId, Context actions.add(guidedAction); } + + private void setBackButton(List actions) { + addAction(actions, ACTION_BACK, getString(R.string.pref_option_go_back), ""); + } + + private void addAction(List actions, long id, String title, String desc) { + actions.add(new GuidedAction.Builder(mContext) + .id(id) + .title(title) + .description(desc) + .build()); + } + + @Override + public void onGuidedActionClicked(GuidedAction action) { + + if (getSelectedActionPosition() <= 2) { + if (OPTION_NAMES.get(getSelectedActionPosition() - 1).matches("Amahi light")) { + Preferences.setLight(mContext, mSharedPreferences); + } + + if (OPTION_NAMES.get(getSelectedActionPosition() - 1).matches("Amahi dark")) { + Preferences.setDark(mContext, mSharedPreferences); + } + } + + if (getSelectedActionPosition() == 3) { + getActivity().finish(); + } + } } diff --git a/src/main/java/org/amahi/anywhere/tv/presenter/CardPresenter.java b/src/main/java/org/amahi/anywhere/tv/presenter/CardPresenter.java index 4f028b12a..925a5b89e 100644 --- a/src/main/java/org/amahi/anywhere/tv/presenter/CardPresenter.java +++ b/src/main/java/org/amahi/anywhere/tv/presenter/CardPresenter.java @@ -32,20 +32,9 @@ import org.amahi.anywhere.R; import org.amahi.anywhere.server.model.ServerApp; -public class CardPresenter extends Presenter{ +public class CardPresenter extends Presenter { private Context mContext; - private static class ViewHolder extends Presenter.ViewHolder{ - - private ImageCardView mCardView; - - ViewHolder(View view) { - super(view); - mCardView = (ImageCardView) view; - } - - } - @Override public ViewHolder onCreateViewHolder(ViewGroup parent) { mContext = parent.getContext(); @@ -61,13 +50,14 @@ public ViewHolder onCreateViewHolder(ViewGroup parent) { @Override public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) { - if(item!=null) { + if (item != null) { ServerApp serverApp = (ServerApp) item; ((ViewHolder) viewHolder).mCardView.setTitleText(serverApp.getName()); - int CARD_WIDTH = 400;int CARD_HEIGHT = 300; + int CARD_WIDTH = 400; + int CARD_HEIGHT = 300; ((ViewHolder) viewHolder).mCardView.setMainImageDimensions(CARD_WIDTH, CARD_HEIGHT); @@ -83,4 +73,15 @@ public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) { public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) { //Do Nothing } + + private static class ViewHolder extends Presenter.ViewHolder { + + private ImageCardView mCardView; + + ViewHolder(View view) { + super(view); + mCardView = (ImageCardView) view; + } + + } } diff --git a/src/main/java/org/amahi/anywhere/tv/presenter/SettingsItemPresenter.java b/src/main/java/org/amahi/anywhere/tv/presenter/SettingsItemPresenter.java index d51be6faa..ac6a2f6ec 100644 --- a/src/main/java/org/amahi/anywhere/tv/presenter/SettingsItemPresenter.java +++ b/src/main/java/org/amahi/anywhere/tv/presenter/SettingsItemPresenter.java @@ -29,13 +29,24 @@ import android.widget.TextView; import org.amahi.anywhere.R; +import org.amahi.anywhere.server.model.Server; import org.amahi.anywhere.tv.activity.SettingsActivity; +import java.util.ArrayList; + public class SettingsItemPresenter extends Presenter { private static final int SETTINGS_ITEM_WIDTH = 400; private static final int SETTINGS_ITEM_HEIGHT = 200; private Context mContext; + private ArrayList serverArrayList; + + public SettingsItemPresenter() { + } + + public SettingsItemPresenter(ArrayList serverArrayList) { + this.serverArrayList = serverArrayList; + } @Override public ViewHolder onCreateViewHolder(ViewGroup parent) { @@ -43,7 +54,7 @@ public ViewHolder onCreateViewHolder(ViewGroup parent) { TextView view = new TextView(mContext); - view.setLayoutParams(new ViewGroup.LayoutParams(SETTINGS_ITEM_WIDTH,SETTINGS_ITEM_HEIGHT)); + view.setLayoutParams(new ViewGroup.LayoutParams(SETTINGS_ITEM_WIDTH, SETTINGS_ITEM_HEIGHT)); view.setFocusable(true); @@ -62,21 +73,26 @@ public ViewHolder onCreateViewHolder(ViewGroup parent) { public void onBindViewHolder(final ViewHolder viewHolder, Object item) { TextView settingsTv = (TextView) viewHolder.view; - final String settingsText = (String)item; + final String settingsText = (String) item; settingsTv.setText(settingsText); settingsTv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if(settingsText.matches(mContext.getString(R.string.pref_title_sign_out))){ - mContext.startActivity(new Intent(mContext, SettingsActivity.class).putExtra(Intent.EXTRA_TEXT,mContext.getString(R.string.pref_title_sign_out))); - } - else if(settingsText.matches(mContext.getString(R.string.pref_title_connection))){ - mContext.startActivity(new Intent(mContext, SettingsActivity.class).putExtra(Intent.EXTRA_TEXT,mContext.getString(R.string.pref_title_connection))); + if (settingsText.matches(mContext.getString(R.string.pref_title_server_select))) { + Intent intent = new Intent(mContext, SettingsActivity.class); + intent.putExtra(Intent.EXTRA_TEXT, mContext.getString(R.string.pref_title_server_select)); + intent.putParcelableArrayListExtra(mContext.getString(R.string.intent_servers), serverArrayList); + mContext.startActivity(intent); } - else if(settingsText.matches(mContext.getString(R.string.pref_title_select_theme))){ - mContext.startActivity(new Intent(mContext, SettingsActivity.class).putExtra(Intent.EXTRA_TEXT,mContext.getString(R.string.pref_title_select_theme))); + + if (settingsText.matches(mContext.getString(R.string.pref_title_sign_out))) { + mContext.startActivity(new Intent(mContext, SettingsActivity.class).putExtra(Intent.EXTRA_TEXT, mContext.getString(R.string.pref_title_sign_out))); + } else if (settingsText.matches(mContext.getString(R.string.pref_title_connection))) { + mContext.startActivity(new Intent(mContext, SettingsActivity.class).putExtra(Intent.EXTRA_TEXT, mContext.getString(R.string.pref_title_connection))); + } else if (settingsText.matches(mContext.getString(R.string.pref_title_select_theme))) { + mContext.startActivity(new Intent(mContext, SettingsActivity.class).putExtra(Intent.EXTRA_TEXT, mContext.getString(R.string.pref_title_select_theme))); } } }); diff --git a/src/main/java/org/amahi/anywhere/util/CheckTV.java b/src/main/java/org/amahi/anywhere/util/CheckTV.java new file mode 100644 index 000000000..a3caae0cf --- /dev/null +++ b/src/main/java/org/amahi/anywhere/util/CheckTV.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014 Amahi + * + * This file is part of Amahi. + * + * Amahi is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Amahi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Amahi. If not, see . + */ + +package org.amahi.anywhere.util; + +import android.app.UiModeManager; +import android.content.Context; +import android.content.res.Configuration; + +import static android.content.Context.UI_MODE_SERVICE; + +public class CheckTV { + + public static boolean isATV(Context context) { + UiModeManager uiModeManager = (UiModeManager) context.getSystemService(UI_MODE_SERVICE); + return (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION); + } +} diff --git a/src/main/java/org/amahi/anywhere/util/Preferences.java b/src/main/java/org/amahi/anywhere/util/Preferences.java index c4a953685..9089c5891 100644 --- a/src/main/java/org/amahi/anywhere/util/Preferences.java +++ b/src/main/java/org/amahi/anywhere/util/Preferences.java @@ -21,6 +21,11 @@ import android.content.Context; import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import org.amahi.anywhere.R; + +import static android.content.Context.MODE_PRIVATE; /** * Application {@link android.content.SharedPreferences} accessor. @@ -29,7 +34,56 @@ public final class Preferences { private final SharedPreferences preferences; private Preferences(Context context, String location) { - this.preferences = context.getSharedPreferences(location, Context.MODE_PRIVATE); + this.preferences = context.getSharedPreferences(location, MODE_PRIVATE); + } + + public static SharedPreferences getTVPreference(Context context) { + return PreferenceManager.getDefaultSharedPreferences(context); + } + + public static String getServerConnection(SharedPreferences preferences, Context context) { + return preferences.getString(context.getString(R.string.preference_key_server_connection), context.getString(R.string.preference_entry_server_connection_auto)); + } + + + public static void setPrefAuto(SharedPreferences preference, Context context) { + preference.edit().putString(context.getString(R.string.preference_key_server_connection), context.getString(R.string.preference_entry_server_connection_auto)).apply(); + } + + public static void setPrefRemote(SharedPreferences preference, Context context) { + preference.edit().putString(context.getString(R.string.preference_key_server_connection), context.getString(R.string.preference_entry_server_connection_remote)).apply(); + } + + public static void setPrefLocal(SharedPreferences preference, Context context) { + preference.edit().putString(context.getString(R.string.preference_key_server_connection), context.getString(R.string.preference_entry_server_connection_local)).apply(); + } + + public static SharedPreferences getPreference(Context context) { + return context.getSharedPreferences(context.getString(R.string.preference), Context.MODE_PRIVATE); + } + + public static void setLight(Context context, SharedPreferences preferences) { + preferences.edit().putString(context.getString(R.string.pref_key_theme), context.getString(R.string.pref_theme_light)).apply(); + } + + public static void setDark(Context context, SharedPreferences preferences) { + preferences.edit().putString(context.getString(R.string.pref_key_theme), context.getString(R.string.pref_theme_dark)).apply(); + } + + public static void setServertoPref(String server, Context context, SharedPreferences sharedPref) { + sharedPref.edit().putString(context.getString(R.string.pref_server_select_key), server).apply(); + } + + public static String getServerFromPref(Context context, SharedPreferences sharedPreferences) { + return sharedPreferences.getString(context.getString(R.string.pref_server_select_key), null); + } + + public static boolean getFirstRun(Context context) { + return context.getSharedPreferences(context.getString(R.string.preference), MODE_PRIVATE).getBoolean(context.getString(R.string.is_first_run), true); + } + + public static void setFirstRun(Context context) { + context.getSharedPreferences(context.getString(R.string.preference), MODE_PRIVATE).edit().putBoolean(context.getString(R.string.is_first_run), false).apply(); } public static Preferences ofCookie(Context context) { diff --git a/src/main/res/layout/activity_main_tv.xml b/src/main/res/layout/activity_main_tv.xml index e2603fbef..778a0b9ea 100644 --- a/src/main/res/layout/activity_main_tv.xml +++ b/src/main/res/layout/activity_main_tv.xml @@ -2,10 +2,5 @@ - - + android:id="@+id/main_tv_fragment_container" + android:layout_height="match_parent"/> diff --git a/src/main/res/layout/activity_navigation.xml b/src/main/res/layout/activity_navigation.xml index 40aa1517d..4f38298d6 100644 --- a/src/main/res/layout/activity_navigation.xml +++ b/src/main/res/layout/activity_navigation.xml @@ -28,29 +28,11 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> - - - - - - + android:layout_height="match_parent" + android:layout="@layout/tv_loading" + android:id="@+id/view_stub_tv_loading"/> - diff --git a/src/main/res/layout/container_files_dummy.xml b/src/main/res/layout/container_files_dummy.xml new file mode 100644 index 000000000..915c30353 --- /dev/null +++ b/src/main/res/layout/container_files_dummy.xml @@ -0,0 +1,7 @@ + + diff --git a/src/main/res/layout/tv_loading.xml b/src/main/res/layout/tv_loading.xml new file mode 100644 index 000000000..ed048ba83 --- /dev/null +++ b/src/main/res/layout/tv_loading.xml @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/src/main/res/values/preferences.xml b/src/main/res/values/preferences.xml index 92a9cb623..3ad31b746 100644 --- a/src/main/res/values/preferences.xml +++ b/src/main/res/values/preferences.xml @@ -56,4 +56,35 @@ @string/preference_key_server_connection_local + + Select server + Choose the server whose shares you want to access. + List of active servers + Choose the active server whose shares you want to access. + select_server + + + Sign out + Account + Sign out from Amahi TV + Action is not defined + + + theme selected + Select theme + Theme + Select from Light or Dark + Select the type of connection you want. You can set it as Amahi Light or Amahi Dark + Amahi light + Amahi dark + + + Connection + Select from Autodetect, Remote or LAN. + Autodetect + Local area network + Remote + Go back + Select the type of connection you want. You can set it as Auto detect, remote or local area network. + diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 966af3603..8bb909bac 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -77,36 +77,17 @@ Amahi TV - INTENT_APPS + INTENT_FILES INTENT_SHARES INTENT_SERVERS + PREFERENCE + isFirstRun Servers Shares Apps Preferences - - Sign out - Account - Sign out from Amahi TV - Action is not defined - - - Select theme - Theme - Select from Light or Dark - Select the type of connection you want. You can set it as Amahi Light or Amahi Dark - - - Connection - Select from Autodetect, Remote or LAN. - Autodetect - Local area network - Remote - Go back - Select the type of connection you want. You can set it as Auto detect, remote or local area network. - Presenting the all new Amahi TV.