package com.door43.translationstudio.newui.home;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.os.Bundle;
import android.support.v4.content.FileProvider;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;
import android.widget.PopupMenu;
import com.door43.tools.reporting.Logger;
import com.door43.translationstudio.ProfileActivity;
import com.door43.translationstudio.R;
import com.door43.translationstudio.SettingsActivity;
import com.door43.translationstudio.core.Library;
import com.door43.translationstudio.core.Project;
import com.door43.translationstudio.core.TargetLanguage;
import com.door43.translationstudio.core.TargetTranslation;
import com.door43.translationstudio.core.Translator;
import com.door43.translationstudio.dialogs.CustomAlertDialog;
import com.door43.translationstudio.newui.library.ServerLibraryActivity;
import com.door43.translationstudio.newui.BaseActivity;
import com.door43.translationstudio.newui.newtranslation.NewTargetTranslationActivity;
import com.door43.translationstudio.newui.FeedbackDialog;
import com.door43.translationstudio.newui.translate.TargetTranslationActivity;
import com.door43.translationstudio.AppContext;
import com.door43.translationstudio.tasks.ExamineImportsForCollisionsTask;
import com.door43.translationstudio.tasks.ImportProjectsTask;
import com.door43.util.tasks.GenericTaskWatcher;
import com.door43.util.tasks.ManagedTask;
import com.door43.util.tasks.TaskManager;
import com.door43.widget.ViewUtil;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.util.Locale;
public class HomeActivity extends BaseActivity implements GenericTaskWatcher.OnFinishedListener, WelcomeFragment.OnCreateNewTargetTranslation, TargetTranslationListFragment.OnItemClickListener {
private static final int REQUEST_CODE_STORAGE_ACCESS = 42;
private static final int NEW_TARGET_TRANSLATION_REQUEST = 1;
public static final String TAG = HomeActivity.class.getSimpleName();
private Library mLibrary;
private Translator mTranslator;
private Fragment mFragment;
private boolean mUsfmImport = false;
private GenericTaskWatcher taskWatcher;
private ExamineImportsForCollisionsTask mExamineTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
FloatingActionButton addTranslationButton = (FloatingActionButton) findViewById(R.id.addTargetTranslationButton);
addTranslationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onCreateNewTargetTranslation();
}
});
mLibrary = AppContext.getLibrary();
mTranslator = AppContext.getTranslator();
if(findViewById(R.id.fragment_container) != null) {
if(savedInstanceState != null) {
// use current fragment
mFragment = getFragmentManager().findFragmentById(R.id.fragment_container);
} else {
if (mTranslator.getTargetTranslations().length > 0) {
mFragment = new TargetTranslationListFragment();
mFragment.setArguments(getIntent().getExtras());
} else {
mFragment = new WelcomeFragment();
mFragment.setArguments(getIntent().getExtras());
}
getFragmentManager().beginTransaction().add(R.id.fragment_container, mFragment).commit();
}
}
ImageButton moreButton = (ImageButton)findViewById(R.id.action_more);
moreButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PopupMenu moreMenu = new PopupMenu(HomeActivity.this, v);
ViewUtil.forcePopupMenuIcons(moreMenu);
moreMenu.getMenuInflater().inflate(R.menu.menu_home, moreMenu.getMenu());
moreMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_update:
openLibrary();
return true;
case R.id.action_import:
FragmentTransaction backupFt = getFragmentManager().beginTransaction();
Fragment backupPrev = getFragmentManager().findFragmentByTag(ImportDialog.TAG);
if (backupPrev != null) {
backupFt.remove(backupPrev);
}
backupFt.addToBackStack(null);
ImportDialog importDialog = new ImportDialog();
importDialog.show(backupFt, ImportDialog.TAG);
return true;
case R.id.action_feedback:
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("bugDialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
FeedbackDialog dialog = new FeedbackDialog();
dialog.show(ft, "bugDialog");
// CustomAlertDialog.test(HomeActivity.this);
return true;
case R.id.action_share_apk:
try {
PackageInfo pinfo = getPackageManager().getPackageInfo(getPackageName(), 0);
File apkFile = new File(pinfo.applicationInfo.publicSourceDir);
File exportFile = new File(AppContext.getSharingDir(), pinfo.applicationInfo.loadLabel(getPackageManager()) + "_" + pinfo.versionName + ".apk");
FileUtils.copyFile(apkFile, exportFile);
if (exportFile.exists()) {
Uri u = FileProvider.getUriForFile(HomeActivity.this, "com.door43.translationstudio.fileprovider", exportFile);
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("application/zip");
i.putExtra(Intent.EXTRA_STREAM, u);
startActivity(Intent.createChooser(i, getResources().getString(R.string.send_to)));
}
} catch (Exception e) {
e.printStackTrace();
// todo notify user app could not be shared
}
return true;
case R.id.action_log_out:
AppContext.setProfile(null);
Intent logoutIntent = new Intent(HomeActivity.this, ProfileActivity.class);
startActivity(logoutIntent);
finish();
return true;
case R.id.action_settings:
Intent intent = new Intent(HomeActivity.this, SettingsActivity.class);
startActivity(intent);
return true;
}
return false;
}
});
moreMenu.show();
}
});
Intent intent = getIntent(); // check if user is trying to open a tstudio file
if(intent != null) {
String action = intent.getAction();
if(action != null) {
if (action.compareTo(Intent.ACTION_VIEW) == 0 || action.compareTo(Intent.ACTION_DEFAULT) == 0) {
String scheme = intent.getScheme();
ContentResolver resolver = getContentResolver();
Uri contentUri = intent.getData();
Logger.i(TAG,"Opening: " + contentUri.toString());
if (scheme.compareTo(ContentResolver.SCHEME_CONTENT) == 0) {
importFromUri(resolver, contentUri);
return;
} else if (scheme.compareTo(ContentResolver.SCHEME_FILE) == 0) {
importFromUri(resolver, contentUri);
return;
}
}
}
}
// open last project when starting the first time
if (savedInstanceState == null) {
TargetTranslation targetTranslation = getLastOpened();
if (targetTranslation != null) {
onItemClick(targetTranslation);
return;
}
}
}
@Override
public void onFinished(ManagedTask task) {
taskWatcher.stop();
if (task instanceof ExamineImportsForCollisionsTask) {
final ExamineImportsForCollisionsTask examineTask = (ExamineImportsForCollisionsTask) task;
Handler hand = new Handler(Looper.getMainLooper());
hand.post(new Runnable() {
@Override
public void run() {
if (examineTask.mSuccess) {
displayImportVerification();
} else {
Logger.e(TAG, "Could not process content URI: " + examineTask.mContentUri.toString());
showImportResults(mExamineTask.mContentUri.toString(), null, false);
examineTask.cleanup();
}
}
});
} else if (task instanceof ImportProjectsTask) {
final ImportProjectsTask importTask = (ImportProjectsTask) task;
Handler hand = new Handler(Looper.getMainLooper());
hand.post(new Runnable() {
@Override
public void run() {
String[] importedSlugs = importTask.getImportedSlugs();
boolean success = (importedSlugs != null) && (importedSlugs.length > 0);
showImportResults(mExamineTask.mContentUri.toString(), mExamineTask.mProjectsFound, success);
}
});
mExamineTask.cleanup();
}
}
/**
* display the final import Results.
*/
private void showImportResults(String projectPath, String projectNames, boolean success) {
final CustomAlertDialog dlg = CustomAlertDialog.Create(this);
String message;
if(success) {
String format = AppContext.context().getResources().getString(R.string.import_project_success);
message = String.format(format, projectNames, projectPath);
} else {
String format = AppContext.context().getResources().getString(R.string.import_failed);
message = format + "\n" + projectPath;
}
dlg.setTitle(success ? R.string.title_import_Success : R.string.title_import_Failed)
.setMessage(message)
.setPositiveButton(R.string.label_ok, new View.OnClickListener() {
@Override
public void onClick(View v) {
mExamineTask.cleanup();
HomeActivity.this.finish();
}
})
.show("USFMImportResults2");
}
/**
* begin the uri import
* @param resolver
* @param contentUri
* @return
* @throws Exception
*/
private void importFromUri(ContentResolver resolver, Uri contentUri) {
if(null == taskWatcher) {
taskWatcher = new GenericTaskWatcher(this, R.string.import_project);
taskWatcher.setOnFinishedListener(this);
}
mExamineTask = new ExamineImportsForCollisionsTask(resolver, contentUri);
taskWatcher.watch(mExamineTask);
TaskManager.addTask(mExamineTask, ExamineImportsForCollisionsTask.TASK_ID);
}
/**
* show dialog to verify that we want to import, restore or cancel.
*/
private void displayImportVerification() {
final CustomAlertDialog dlg = CustomAlertDialog.Create(this);
dlg.setTitle(R.string.label_import)
.setMessage(String.format(getResources().getString(R.string.confirm_import_target_translation), mExamineTask.mProjectsFound))
.setNegativeButton(R.string.title_cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
mExamineTask.cleanup();
HomeActivity.this.finish();
}
})
.setPositiveButton(R.string.label_restore, new View.OnClickListener() {
@Override
public void onClick(View v) {
doArchiveImport(true);
}
});
if(mExamineTask.mAlreadyPresent) { // add merge option
dlg.setNeutralButton(R.string.label_import, new View.OnClickListener() {
@Override
public void onClick(View v) {
doArchiveImport(false);
dlg.dismiss();
}
});
}
dlg.show("confirm_import");
}
/**
* import specified file
* @param overwrite
*/
private void doArchiveImport(boolean overwrite) {
ImportProjectsTask importTask = new ImportProjectsTask(mExamineTask.mProjectsFolder, overwrite);
taskWatcher.watch(importTask);
TaskManager.addTask(importTask, ImportProjectsTask.TASK_ID);
}
/**
* Triggers the process of opening the server library
*/
private void openLibrary() {
CustomAlertDialog.Create(HomeActivity.this)
.setTitle(R.string.update_projects)
.setIcon(R.drawable.ic_local_library_black_24dp)
.setMessage(R.string.use_internet_confirmation)
.setPositiveButton(R.string.yes, new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(HomeActivity.this, ServerLibraryActivity.class);
startActivity(intent);
}
})
.setNegativeButton(R.string.no, null)
.show("UpdateLib");
}
@Override
public void onResume() {
super.onResume();
AppContext.setLastFocusTargetTranslation(null);
int numTranslations = mTranslator.getTargetTranslations().length;
if(numTranslations > 0 && mFragment instanceof WelcomeFragment) {
// display target translations list
mFragment = new TargetTranslationListFragment();
mFragment.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().replace(R.id.fragment_container, mFragment).commit();
// load list after fragment created
Handler hand = new Handler(Looper.getMainLooper());
hand.post(new Runnable() {
@Override
public void run() {
((TargetTranslationListFragment) mFragment).reloadList();
}
});
} else if(numTranslations == 0 && mFragment instanceof TargetTranslationListFragment) {
// display welcome screen
mFragment = new WelcomeFragment();
mFragment.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().replace(R.id.fragment_container, mFragment).commit();
} else if(numTranslations > 0 && mFragment instanceof TargetTranslationListFragment) {
// reload list
((TargetTranslationListFragment)mFragment).reloadList();
}
}
/**
* get last project opened and make sure it is still present
* @return
*/
@Nullable
private TargetTranslation getLastOpened() {
String lastTarget = AppContext.getLastFocusTargetTranslation();
if (lastTarget != null) {
TargetTranslation targetTranslation = mTranslator.getTargetTranslation(lastTarget);
if (targetTranslation != null) {
return targetTranslation;
}
}
return null;
}
@Override
public void onBackPressed() {
// display confirmation before closing the app
CustomAlertDialog.Create(this)
.setMessage(R.string.exit_confirmation)
.setPositiveButton(R.string.yes, new View.OnClickListener() {
@Override
public void onClick(View v) {
HomeActivity.super.onBackPressed();
}
})
.setNegativeButton(R.string.no, null)
.show("ExitConfirm");
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(NEW_TARGET_TRANSLATION_REQUEST == requestCode ) {
if(RESULT_OK == resultCode ) {
if(mFragment instanceof WelcomeFragment) {
// display target translations list
mFragment = new TargetTranslationListFragment();
mFragment.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().replace(R.id.fragment_container, mFragment).commit();
} else {
((TargetTranslationListFragment) mFragment).reloadList();
}
Intent intent = new Intent(HomeActivity.this, TargetTranslationActivity.class);
intent.putExtra(AppContext.EXTRA_TARGET_TRANSLATION_ID, data.getStringExtra(NewTargetTranslationActivity.EXTRA_TARGET_TRANSLATION_ID));
startActivity(intent);
} else if( NewTargetTranslationActivity.RESULT_DUPLICATE == resultCode ) {
// display duplicate notice to user
String targetTranslationId = data.getStringExtra(NewTargetTranslationActivity.EXTRA_TARGET_TRANSLATION_ID);
TargetTranslation existingTranslation = mTranslator.getTargetTranslation(targetTranslationId);
if(existingTranslation != null) {
Project project = mLibrary.getProject(existingTranslation.getProjectId(), Locale.getDefault().getLanguage());
Snackbar snack = Snackbar.make(findViewById(android.R.id.content), String.format(getResources().getString(R.string.duplicate_target_translation), project.name, existingTranslation.getTargetLanguageName()), Snackbar.LENGTH_LONG);
ViewUtil.setSnackBarTextColor(snack, getResources().getColor(R.color.light_primary_text));
snack.show();
}
} else if( NewTargetTranslationActivity.RESULT_ERROR == resultCode) {
Snackbar snack = Snackbar.make(findViewById(android.R.id.content), getResources().getString(R.string.error), Snackbar.LENGTH_LONG);
ViewUtil.setSnackBarTextColor(snack, getResources().getColor(R.color.light_primary_text));
snack.show();
}
}
}
@Override
public void onCreateNewTargetTranslation() {
Intent intent = new Intent(HomeActivity.this, NewTargetTranslationActivity.class);
startActivityForResult(intent, NEW_TARGET_TRANSLATION_REQUEST);
}
@Override
public void onItemDeleted(String targetTranslationId) {
if(mTranslator.getTargetTranslations().length > 0) {
((TargetTranslationListFragment) mFragment).reloadList();
} else {
// display welcome screen
mFragment = new WelcomeFragment();
mFragment.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().replace(R.id.fragment_container, mFragment).commit();
}
}
@Override
public void onItemClick(TargetTranslation targetTranslation) {
// validate project (make sure it was downloaded)
Project project = AppContext.getLibrary().getProject(targetTranslation.getProjectId(), "en");
TargetLanguage targetLanguage = AppContext.getLibrary().getTargetLanguage(targetTranslation.getTargetLanguageId());
if(project == null || targetLanguage == null || !AppContext.getLibrary().projectHasSource(project.getId())) {
Snackbar snack = Snackbar.make(findViewById(android.R.id.content), R.string.missing_project, Snackbar.LENGTH_LONG);
snack.setAction(R.string.download, new View.OnClickListener() {
@Override
public void onClick(View v) {
openLibrary();
}
});
snack.setActionTextColor(getResources().getColor(R.color.light_primary_text));
ViewUtil.setSnackBarTextColor(snack, getResources().getColor(R.color.light_primary_text));
snack.show();
} else {
Intent intent = new Intent(HomeActivity.this, TargetTranslationActivity.class);
intent.putExtra(AppContext.EXTRA_TARGET_TRANSLATION_ID, targetTranslation.getId());
startActivity(intent);
}
}
public void notifyDatasetChanged() {
onResume();
}
}