Implement intro screen for offline app sharing

This commit is contained in:
Torsten Grote
2021-05-06 17:34:40 -03:00
committed by Sebastian Kürten
parent 40865425c5
commit a86ba50dec
11 changed files with 292 additions and 0 deletions

View File

@@ -441,6 +441,11 @@
android:label="@string/pending_contact_requests"
android:theme="@style/BriarTheme" />
<activity
android:name=".android.hotspot.HotspotActivity"
android:label="@string/hotspot_title"
android:theme="@style/BriarTheme" />
</application>
<queries>

View File

@@ -35,6 +35,7 @@ import org.briarproject.briar.BriarCoreModule;
import org.briarproject.briar.android.attachment.AttachmentModule;
import org.briarproject.briar.android.attachment.media.MediaModule;
import org.briarproject.briar.android.conversation.glide.BriarModelLoader;
import org.briarproject.briar.android.hotspot.HotspotIntroFragment;
import org.briarproject.briar.android.logging.CachingLogHandler;
import org.briarproject.briar.android.login.SignInReminderReceiver;
import org.briarproject.briar.android.settings.ConnectionsFragment;
@@ -210,4 +211,6 @@ public interface AndroidComponent
void inject(SecurityFragment securityFragment);
void inject(NotificationsFragment notificationsFragment);
void inject(HotspotIntroFragment hotspotIntroFragment);
}

View File

@@ -35,6 +35,7 @@ import org.briarproject.briar.android.blog.BlogModule;
import org.briarproject.briar.android.contact.ContactListModule;
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactModule;
import org.briarproject.briar.android.forum.ForumModule;
import org.briarproject.briar.android.hotspot.HotspotModule;
import org.briarproject.briar.android.introduction.IntroductionModule;
import org.briarproject.briar.android.logging.LoggingModule;
import org.briarproject.briar.android.login.LoginModule;
@@ -92,6 +93,7 @@ import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
GroupListModule.class,
GroupConversationModule.class,
SharingModule.class,
HotspotModule.class
})
public class AppModule {

View File

@@ -38,6 +38,7 @@ import org.briarproject.briar.android.forum.CreateForumActivity;
import org.briarproject.briar.android.forum.ForumActivity;
import org.briarproject.briar.android.forum.ForumListFragment;
import org.briarproject.briar.android.fragment.ScreenFilterDialogFragment;
import org.briarproject.briar.android.hotspot.HotspotActivity;
import org.briarproject.briar.android.introduction.ContactChooserFragment;
import org.briarproject.briar.android.introduction.IntroductionActivity;
import org.briarproject.briar.android.introduction.IntroductionMessageFragment;
@@ -176,6 +177,8 @@ public interface ActivityComponent {
void inject(CrashReportActivity crashReportActivity);
void inject(HotspotActivity hotspotActivity);
// Fragments
void inject(SetupFragment fragment);

View File

@@ -0,0 +1,62 @@
package org.briarproject.briar.android.hotspot;
import android.os.Bundle;
import android.view.MenuItem;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity;
import javax.annotation.Nullable;
import javax.inject.Inject;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.lifecycle.ViewModelProvider;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class HotspotActivity extends BriarActivity {
@Inject
ViewModelProvider.Factory viewModelFactory;
private HotspotViewModel viewModel;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
viewModel = new ViewModelProvider(this, viewModelFactory)
.get(HotspotViewModel.class);
}
@Override
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
setContentView(R.layout.activity_fragment_container);
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setDisplayHomeAsUpEnabled(true);
}
if (state == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragmentContainer, new HotspotIntroFragment(),
HotspotIntroFragment.TAG)
.commit();
}
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@@ -0,0 +1,67 @@
package org.briarproject.briar.android.hotspot;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static androidx.transition.TransitionManager.beginDelayedTransition;
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class HotspotIntroFragment extends Fragment {
public final static String TAG = HotspotIntroFragment.class.getName();
@Inject
ViewModelProvider.Factory viewModelFactory;
private HotspotViewModel viewModel;
@Override
public void onAttach(Context context) {
super.onAttach(context);
getAndroidComponent(requireContext()).inject(this);
viewModel = new ViewModelProvider(requireActivity(), viewModelFactory)
.get(HotspotViewModel.class);
}
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View v = inflater
.inflate(R.layout.fragment_hotspot_intro, container, false);
Button startButton = v.findViewById(R.id.startButton);
ProgressBar progressBar = v.findViewById(R.id.progressBar);
TextView progressTextView = v.findViewById(R.id.progressTextView);
startButton.setOnClickListener(button -> {
beginDelayedTransition((ViewGroup) v);
startButton.setVisibility(INVISIBLE);
progressBar.setVisibility(VISIBLE);
progressTextView.setVisibility(VISIBLE);
});
return v;
}
}

View File

@@ -0,0 +1,18 @@
package org.briarproject.briar.android.hotspot;
import org.briarproject.briar.android.viewmodel.ViewModelKey;
import androidx.lifecycle.ViewModel;
import dagger.Binds;
import dagger.Module;
import dagger.multibindings.IntoMap;
@Module
public interface HotspotModule {
@Binds
@IntoMap
@ViewModelKey(HotspotViewModel.class)
ViewModel bindHotspotViewModel(HotspotViewModel hotspotViewModel);
}

View File

@@ -0,0 +1,28 @@
package org.briarproject.briar.android.hotspot;
import android.app.Application;
import org.briarproject.bramble.api.db.DatabaseExecutor;
import org.briarproject.bramble.api.db.TransactionManager;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.system.AndroidExecutor;
import org.briarproject.briar.android.viewmodel.DbViewModel;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@NotNullByDefault
class HotspotViewModel extends DbViewModel {
@Inject
HotspotViewModel(Application application,
@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
TransactionManager db,
AndroidExecutor androidExecutor) {
super(application, dbExecutor, lifecycleManager, db, androidExecutor);
}
}

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,11c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,13c0,-3.31 -2.69,-6 -6,-6s-6,2.69 -6,6c0,2.22 1.21,4.15 3,5.19l1,-1.74c-1.19,-0.7 -2,-1.97 -2,-3.45 0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,1.48 -0.81,2.75 -2,3.45l1,1.74c1.79,-1.04 3,-2.97 3,-5.19zM12,3C6.48,3 2,7.48 2,13c0,3.7 2.01,6.92 4.99,8.65l1,-1.73C5.61,18.53 4,15.96 4,13c0,-4.42 3.58,-8 8,-8s8,3.58 8,8c0,2.96 -1.61,5.53 -4,6.92l1,1.73c2.99,-1.73 5,-4.95 5,-8.65 0,-5.52 -4.48,-10 -10,-10z" />
</vector>

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".android.hotspot.HotspotIntroFragment">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="64dp"
android:layout_marginLeft="64dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="64dp"
android:layout_marginRight="64dp"
android:layout_marginBottom="32dp"
app:layout_constraintBottom_toTopOf="@+id/introView"
app:layout_constraintDimensionRatio="1,1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="spread_inside"
app:srcCompat="@drawable/ic_nickname"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/introView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="@string/hotspot_intro"
app:layout_constraintBottom_toTopOf="@+id/startButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<Button
android:id="@+id/startButton"
style="@style/BriarButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:drawablePadding="6dp"
android:text="@string/hotspot_button_start_sharing"
app:drawableLeftCompat="@drawable/ic_wifi_tethering"
app:drawableStartCompat="@drawable/ic_wifi_tethering"
app:drawableTint="@color/button_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.812"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/introView"
app:layout_constraintVertical_bias="1.0"
tools:visibility="visible" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/startButton"
app:layout_constraintEnd_toStartOf="@+id/progressTextView"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="@+id/startButton"
app:layout_constraintTop_toTopOf="@+id/startButton"
tools:visibility="visible" />
<TextView
android:id="@+id/progressTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:text="@string/hotspot_progress_text_start"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/startButton"
app:layout_constraintEnd_toEndOf="@+id/startButton"
app:layout_constraintStart_toEndOf="@+id/progressBar"
app:layout_constraintTop_toTopOf="@+id/startButton"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -689,6 +689,14 @@
<!-- Connections Screen -->
<string name="transports_help_text">Briar can connect to your contacts via the Internet, Wi-Fi or Bluetooth.\n\nAll Internet connections go through the Tor network for privacy.\n\nIf a contact can be reached by multiple methods, Briar uses them in parallel.</string>
<!-- Share app offline -->
<string name="hotspot_title">Share Briar offline</string>
<string name="hotspot_intro">Share this app with someone nearby without internet connection
by using your phone\'s Wi-Fi.
\n\nYour phone will open a local hotspot and provide a small website with a download of this app.</string>
<string name="hotspot_button_start_sharing">Start sharing</string>
<string name="hotspot_progress_text_start">Setting up hotspot…</string>
<!-- Screenshots -->
<!-- This is a name to be used in screenshots. Feel free to change it to a local name. -->