[new downloader][android] add: Migration UI.

This commit is contained in:
Alexander Marchuk 2016-02-29 13:48:00 +03:00 committed by Sergey Yershov
parent a0d693f3c3
commit 5ced980181
9 changed files with 408 additions and 333 deletions

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mapswithme.maps.widget.HeightLimitedFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:wheel="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:animateLayoutChanges="true"
android:background="?windowBackgroundForced">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
android:padding="@dimen/margin_base">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/img_no_map_light"
android:tag="@string/tag_height_limited"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_base"
android:layout_marginBottom="@dimen/margin_base"
android:gravity="center"
android:text="@string/youve_been_asking"
android:textAppearance="@style/MwmTextAppearance.Title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/migrate_and_split_mwms_message"
android:textAppearance="@style/MwmTextAppearance.Body3"/>
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<TextView
android:id="@+id/error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_base"
android:textAppearance="@style/MwmTextAppearance.Body3"
android:textColor="@color/base_red"
tools:text="Some error occured! Please, be patient, man."/>
<TextView
android:id="@+id/preparation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_base"
android:text="Preparing…"
android:textAppearance="@style/MwmTextAppearance.Body3"/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_base">
<Button
android:id="@+id/button_primary"
android:text="@string/downloader_update_all"
style="@style/MwmWidget.Button.Accent"/>
<com.mapswithme.maps.widget.WheelProgressView
android:id="@+id/progress"
android:layout_width="@dimen/downloader_status_size"
android:layout_height="@dimen/downloader_status_size"
android:layout_gravity="center"
android:visibility="gone"
wheel:wheelProgressColor="?colorAccent"
wheel:wheelSecondaryColor="?dividerHorizontal"
wheel:wheelThickness="@dimen/margin_eighth"
tools:visibility="visible"/>
</FrameLayout>
<Button
android:id="@+id/button_secondary"
style="@style/MwmWidget.Button"
android:text="@string/delete_old_maps"
android:textColor="?colorAccent"/>
</LinearLayout>
</com.mapswithme.maps.widget.HeightLimitedFrameLayout>

View file

@ -1,170 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:wheel="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:animateLayoutChanges="true">
<ScrollView
android:id="@+id/sv__migrate"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="@dimen/margin_double_and_half"
tools:ignore="UnusedAttribute">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Big Update MAPS.ME"
android:textAppearance="@style/MwmTextAppearance.Headline"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_base"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/downloader_download"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginStart="@dimen/margin_base"
android:text="Need your maps take less space"
android:textAppearance="@style/MwmTextAppearance.Body3"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_base"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/downloader_download"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginStart="@dimen/margin_base"
android:text="Don't download routing"
android:textAppearance="@style/MwmTextAppearance.Body3"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_base"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/downloader_download"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginStart="@dimen/margin_base"
android:text="Correct search for the address and postal code"
android:textAppearance="@style/MwmTextAppearance.Body3"/>
</LinearLayout>
<Space
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="To use new features, update downloaded maps"/>
<Button
android:id="@+id/btn__update_all"
style="@style/MwmWidget.Button.Accent"
android:layout_width="match_parent"
android:layout_height="@dimen/height_block_base"
android:layout_marginTop="@dimen/margin_base"
android:text="Update all maps"
android:textAppearance="@style/MwmTextAppearance.Body1"/>
<Button
android:id="@+id/btn__not_now"
android:layout_width="match_parent"
android:layout_height="@dimen/height_block_base"
android:layout_marginTop="@dimen/margin_half"
style="@style/MwmWidget.Button"
android:text="Not now"/>
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="@+id/ll__downloading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="@dimen/margin_base"
android:visibility="gone"
tools:visibility="visible">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingTop="@dimen/margin_double"
android:text="After update maps, you will be able to use all new features of the app"
android:textAppearance="@style/MwmTextAppearance.Body3"/>
<com.mapswithme.maps.widget.WheelProgressView
android:id="@+id/wpv__download_progress"
android:layout_width="@dimen/downloader_status_size"
android:layout_height="@dimen/downloader_status_size"
android:layout_marginTop="@dimen/margin_half_plus"
android:background="?clickableBackground"
wheel:wheelProgressColor="?colorAccent"
wheel:wheelSecondaryColor="?dividerHorizontal"
wheel:wheelThickness="@dimen/margin_quarter"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_base"
android:gravity="center"
android:text="Downloading"
android:textAppearance="@style/MwmTextAppearance.Body1"/>
<TextView
android:id="@+id/tv__progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="After update maps, you will be use all new features of the app"
android:textAppearance="@style/MwmTextAppearance.Body1"
tools:text="47MB / 205MB"/>
</LinearLayout>
</FrameLayout>

View file

@ -1,7 +1,6 @@
package com.mapswithme.maps;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@ -283,37 +282,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
.show();
}
void showMigrateDialog()
{
Statistics.INSTANCE.trackEvent(Statistics.EventName.DOWNLOADER_MIGRATE_DIALOG_SEEN);
new AlertDialog.Builder(MwmActivity.this)
.setTitle(R.string.youve_been_asking)
.setMessage(R.string.migrate_and_split_mwms_message)
.setNegativeButton(R.string.not_now, null)
.setPositiveButton(R.string.delete_all, new Dialog.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
Statistics.INSTANCE.trackEvent(Statistics.EventName.DOWNLOADER_MIGRATE_PERFORMED);
RoutingController.get().cancel();
MapManager.nativeMigrate();
showDownloader(false);
}
}).show();
}
@Override
public void showDownloader(boolean openDownloaded)
{
if (MapManager.nativeIsLegacyMode())
{
showMigrateDialog();
return;
}
final Bundle args = new Bundle();
args.putBoolean(DownloaderActivity.EXTRA_OPEN_DOWNLOADED, openDownloaded);
if (mIsFragmentContainer)

View file

@ -150,7 +150,7 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl
mTvActiveCountry = (TextView) view.findViewById(R.id.tv__active_country_name);
UiUtils.updateAccentButton(mBtnDownloadMap);
UiUtils.updateButton(selectMap);
UiUtils.updateAccentButton(selectMap);
}
private void refreshViews()

View file

@ -12,7 +12,8 @@ public class DownloaderActivity extends BaseMwmFragmentActivity
@Override
protected Class<? extends Fragment> getFragmentClass()
{
return DownloaderFragment.class;
return (MapManager.nativeIsLegacyMode() ? MigrationFragment.class
: DownloaderFragment.class);
}
@Override

View file

@ -3,7 +3,6 @@ package com.mapswithme.maps.downloader;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
@ -125,15 +124,6 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment
UiUtils.showIf(showBottom, mBottomPanel);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
if (MapManager.nativeIsLegacyMode())
getMwmActivity().replaceFragment(MigrateSmallMwmFragment.class, null, null);
}
@Override
public void onAttach(Activity activity)
{

View file

@ -1,122 +0,0 @@
package com.mapswithme.maps.downloader;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmFragment;
import com.mapswithme.maps.widget.WheelProgressView;
import com.mapswithme.util.StringUtils;
import com.mapswithme.util.UiUtils;
public class MigrateSmallMwmFragment extends BaseMwmFragment
implements View.OnClickListener
{
private WheelProgressView mWheelProgress;
private View mMigrate;
private View mMigrating;
private TextView mTvProgress;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_migrate_small_mwm, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
// TODO listen to map actions callbacks
initViews(view);
refreshViews();
}
@Override
public void onResume()
{
super.onResume();
refreshViews();
}
private void initViews(View view)
{
mMigrate = view.findViewById(R.id.sv__migrate);
mMigrating = view.findViewById(R.id.ll__downloading);
Button updateAll = (Button)view.findViewById(R.id.btn__update_all);
updateAll.setOnClickListener(this);
UiUtils.updateAccentButton(updateAll);
view.findViewById(R.id.btn__select_map).setOnClickListener(this);
view.findViewById(R.id.btn__not_now).setOnClickListener(this);
mWheelProgress = (WheelProgressView) view.findViewById(R.id.wpv__download_progress);
mWheelProgress.setCenterDrawable(ContextCompat.getDrawable(getActivity(), R.drawable.ic_close));
mWheelProgress.setOnClickListener(this);
mTvProgress = (TextView) view.findViewById(R.id.tv__progress);
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.btn__update_all:
updateAll();
break;
case R.id.btn__select_map:
selectMaps();
break;
case R.id.btn__not_now:
openDownloader();
break;
case R.id.wpv__download_progress:
cancelUpdate();
break;
}
}
private void selectMaps()
{
getMwmActivity().replaceFragment(SelectMigrationFragment.class, null, null);
}
private void updateAll()
{
// TODO start map migration
UiUtils.hide(mMigrate);
UiUtils.show(mMigrating);
}
private void cancelUpdate()
{
// TODO cancel migration
UiUtils.show(mMigrate);
UiUtils.hide(mMigrating);
}
private void openDownloader()
{
getMwmActivity().replaceFragment(DownloaderFragment.class, null, null);
}
private void refreshViews()
{
// TODO show migration UI if maps are migrating
}
private void refreshProgress(long[] sizes)
{
final int percent = (int) (sizes[0] * 100 / sizes[1]);
mWheelProgress.setProgress(percent);
// TODO localize formatting ?
mTvProgress.setText(StringUtils.getFileSizeString(sizes[0]) + "/" + StringUtils.getFileSizeString(sizes[1]));
}
}

View file

@ -0,0 +1,168 @@
package com.mapswithme.maps.downloader;
import android.location.Location;
import com.mapswithme.maps.location.LocationHelper;
@android.support.annotation.UiThread
final class MigrationController
{
enum State
{
NOT_NECESSARY,
READY,
PROGRESS,
ERROR
}
interface Container
{
void setReadyState();
void setProgressState();
void setErrorState(int code);
void onComplete();
void setProgress(int percents);
}
private static final MigrationController sInstance = new MigrationController();
private Container mContainer;
private State mState;
private int mProgress;
private int mError;
private final MapManager.MigrationListener mListener = new MapManager.MigrationListener()
{
@Override
public void onComplete()
{
mState = State.NOT_NECESSARY;
callOnComplete();
}
@Override
public void onProgress(int percent)
{
mProgress = percent;
callUpdateProgress();
}
@Override
public void onError(int code)
{
mState = State.ERROR;
mError = code;
callStateError();
}
};
static MigrationController get()
{
return sInstance;
}
private MigrationController()
{
if (!MapManager.nativeIsLegacyMode())
{
mState = State.NOT_NECESSARY;
return;
}
mState = State.READY;
if (!MapManager.nativeHasSpaceForMigration())
{
mState = State.ERROR;
mError = CountryItem.ERROR_OOM;
}
}
private void callStateReady()
{
if (mContainer != null)
mContainer.setReadyState();
}
private void callStateProgress()
{
if (mContainer != null)
mContainer.setProgressState();
}
private void callStateError()
{
if (mContainer != null)
mContainer.setErrorState(mError);
}
private void callUpdateProgress()
{
if (mContainer != null)
mContainer.setProgress(mProgress);
}
private void callOnComplete()
{
if (mContainer != null)
mContainer.onComplete();
}
void attach(Container container)
{
if (mContainer != null)
throw new IllegalStateException("Must be detached before attach()");
mContainer = container;
}
void detach()
{
mContainer = null;
}
void restore()
{
switch (mState)
{
case READY:
callStateReady();
break;
case PROGRESS:
callStateProgress();
callUpdateProgress();
break;
case ERROR:
callStateError();
break;
}
}
void start(boolean keepOld)
{
if (mState == State.PROGRESS)
return;
Location loc = LocationHelper.INSTANCE.getLastLocation();
double lat = (loc == null ? 0.0 : loc.getLatitude());
double lon = (loc == null ? 0.0 : loc.getLongitude());
if (!MapManager.nativeMigrate(mListener, lat, lon, (loc != null), keepOld))
return;
mState = State.PROGRESS;
mProgress = 0;
callStateProgress();
callUpdateProgress();
}
void cancel()
{
mState = State.READY;
callStateReady();
MapManager.nativeCancelMigration();
}
}

View file

@ -0,0 +1,150 @@
package com.mapswithme.maps.downloader;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.mapswithme.maps.R;
import com.mapswithme.maps.base.BaseMwmFragment;
import com.mapswithme.maps.base.OnBackPressListener;
import com.mapswithme.maps.location.LocationHelper;
import com.mapswithme.maps.widget.WheelProgressView;
import com.mapswithme.util.UiUtils;
public class MigrationFragment extends BaseMwmFragment
implements OnBackPressListener,
MigrationController.Container
{
private TextView mError;
private View mPrepare;
private WheelProgressView mProgress;
private Button mButtonPrimary;
private Button mButtonSecondary;
private final View.OnClickListener mButtonClickListener = new View.OnClickListener()
{
@Override
public void onClick(View v)
{
MigrationController.get().start(v == mButtonPrimary);
}
};
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_migrate, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
mError = (TextView) view.findViewById(R.id.error);
mPrepare = view.findViewById(R.id.preparation);
mProgress = (WheelProgressView) view.findViewById(R.id.progress);
mButtonPrimary = (Button) view.findViewById(R.id.button_primary);
mButtonSecondary = (Button) view.findViewById(R.id.button_secondary);
mButtonPrimary.setOnClickListener(mButtonClickListener);
mButtonSecondary.setOnClickListener(mButtonClickListener);
mProgress.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
MigrationController.get().cancel();
}
});
MigrationController.get().attach(this);
}
@Override
public void onDestroyView()
{
super.onDestroyView();
MigrationController.get().detach();
}
@Override
public void onResume()
{
super.onResume();
MigrationController.get().restore();
}
@Override
public void setReadyState()
{
UiUtils.show(mButtonPrimary, mButtonSecondary);
UiUtils.hide(mPrepare, mProgress, mError);
Location loc = LocationHelper.INSTANCE.getLastLocation();
if (loc == null)
UiUtils.setTextAndShow(mError, getString(R.string.undefined_location));
mButtonPrimary.setEnabled(loc != null);
UiUtils.updateAccentButton(mButtonPrimary);
}
@Override
public void setProgressState()
{
UiUtils.show(mPrepare, mProgress);
UiUtils.hide(mError, mButtonPrimary, mButtonSecondary);
}
@Override
public void setErrorState(int code)
{
setReadyState();
UiUtils.show(mError);
@StringRes int text;
switch (code)
{
case CountryItem.ERROR_OOM:
text = R.string.not_enough_disk_space;
break;
case CountryItem.ERROR_NO_INTERNET:
text = R.string.no_internet_connection_detected;
break;
default:
text = R.string.country_status_download_failed;
}
mError.setText(text);
}
@Override
public void onComplete()
{
}
@Override
public void setProgress(int percents)
{
mProgress.setProgress(percents);
}
@Override
public boolean onBackPressed()
{
// TODO
return false;
}
}