Onboarding & signup
This commit is contained in:
@@ -44,7 +44,8 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration{
|
||||
View child=parent.getChildAt(i);
|
||||
int pos=parent.getChildAdapterPosition(child);
|
||||
if(pos<totalItems-1 && (drawDividerPredicate==null || drawDividerPredicate.test(parent.getChildViewHolder(child)))){
|
||||
float y=Math.round(child.getY()+child.getHeight()-paint.getStrokeWidth()/2f);
|
||||
float y=Math.round(child.getY()+child.getHeight());
|
||||
y-=(y-paint.getStrokeWidth()/2f)%1f; // Make sure the line aligns with the pixel grid
|
||||
paint.setAlpha(Math.round(255f*child.getAlpha()));
|
||||
c.drawLine(padLeft+child.getX(), y, child.getX()+child.getWidth()-padRight, y, paint);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
package org.joinmastodon.android.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class InterpolatingMotionEffect implements SensorEventListener{
|
||||
|
||||
private SensorManager sm;
|
||||
private WindowManager wm;
|
||||
private float[] rollBuffer = new float[9], pitchBuffer = new float[9];
|
||||
private int bufferOffset;
|
||||
private Sensor accelerometer;
|
||||
private boolean accelerometerEnabled;
|
||||
private ArrayList<ViewEffect> views=new ArrayList<>();
|
||||
|
||||
public InterpolatingMotionEffect(Context context){
|
||||
sm=context.getSystemService(SensorManager.class);
|
||||
wm=context.getSystemService(WindowManager.class);
|
||||
accelerometer=sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||
}
|
||||
|
||||
public void activate(){
|
||||
if(accelerometer==null || accelerometerEnabled)
|
||||
return;
|
||||
sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
|
||||
accelerometerEnabled=true;
|
||||
}
|
||||
|
||||
public void deactivate(){
|
||||
if(accelerometer==null || !accelerometerEnabled)
|
||||
return;
|
||||
sm.unregisterListener(this);
|
||||
accelerometerEnabled=false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event){
|
||||
int rotation=wm.getDefaultDisplay().getRotation();
|
||||
|
||||
float x=event.values[0]/SensorManager.GRAVITY_EARTH;
|
||||
float y=event.values[1]/SensorManager.GRAVITY_EARTH;
|
||||
float z=event.values[2]/SensorManager.GRAVITY_EARTH;
|
||||
|
||||
|
||||
float pitch=(float) (Math.atan2(x, Math.sqrt(y*y+z*z))/Math.PI*2.0);
|
||||
float roll=(float) (Math.atan2(y, Math.sqrt(x*x+z*z))/Math.PI*2.0);
|
||||
|
||||
switch(rotation){
|
||||
case Surface.ROTATION_0:
|
||||
break;
|
||||
case Surface.ROTATION_90:{
|
||||
float tmp=pitch;
|
||||
pitch=roll;
|
||||
roll=tmp;
|
||||
break;
|
||||
}
|
||||
case Surface.ROTATION_180:
|
||||
roll=-roll;
|
||||
pitch=-pitch;
|
||||
break;
|
||||
case Surface.ROTATION_270:{
|
||||
float tmp=-pitch;
|
||||
pitch=roll;
|
||||
roll=tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rollBuffer[bufferOffset]=roll;
|
||||
pitchBuffer[bufferOffset]=pitch;
|
||||
bufferOffset=(bufferOffset+1)%rollBuffer.length;
|
||||
roll=pitch=0;
|
||||
for(int i=0; i<rollBuffer.length; i++){
|
||||
roll+=rollBuffer[i];
|
||||
pitch+=pitchBuffer[i];
|
||||
}
|
||||
roll/=rollBuffer.length;
|
||||
pitch/=rollBuffer.length;
|
||||
if(roll>1f){
|
||||
roll=2f-roll;
|
||||
}else if(roll<-1f){
|
||||
roll=-2f-roll;
|
||||
}
|
||||
for(ViewEffect view:views){
|
||||
view.update(pitch, roll);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy){
|
||||
|
||||
}
|
||||
|
||||
public void addViewEffect(ViewEffect effect){
|
||||
views.add(effect);
|
||||
}
|
||||
|
||||
public void removeViewEffect(ViewEffect effect){
|
||||
views.remove(effect);
|
||||
}
|
||||
|
||||
public void removeAllViewEffects(){
|
||||
views.clear();
|
||||
}
|
||||
|
||||
public static class ViewEffect{
|
||||
private View view;
|
||||
private float minX, maxX, minY, maxY;
|
||||
|
||||
public ViewEffect(View view, float minX, float maxX, float minY, float maxY){
|
||||
this.view=view;
|
||||
this.minX=minX;
|
||||
this.maxX=maxX;
|
||||
this.minY=minY;
|
||||
this.maxY=maxY;
|
||||
}
|
||||
|
||||
private void update(float x, float y){
|
||||
view.setTranslationX(lerp(maxX, minX, (x+1f)/2f));
|
||||
view.setTranslationY(lerp(minY, maxY, (y+1f)/2f));
|
||||
}
|
||||
|
||||
private static float lerp(float startValue, float endValue, float fraction) {
|
||||
return startValue + (fraction * (endValue - startValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||
import org.joinmastodon.android.fragments.ReportReasonChoiceFragment;
|
||||
import org.joinmastodon.android.fragments.report.ReportReasonChoiceFragment;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.Attachment;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
@@ -13,6 +13,7 @@ import android.os.Looper;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.text.Spanned;
|
||||
import android.view.View;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
@@ -33,6 +34,7 @@ import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.text.CustomEmojiSpan;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -49,6 +51,7 @@ import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.imageloader.ViewImageLoader;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.V;
|
||||
import okhttp3.MediaType;
|
||||
|
||||
public class UiUtils{
|
||||
private static Handler mainHandler=new Handler(Looper.getMainLooper());
|
||||
@@ -143,6 +146,11 @@ public class UiUtils{
|
||||
return uri.getLastPathSegment();
|
||||
}
|
||||
|
||||
public static MediaType getFileMediaType(File file){
|
||||
String name=file.getName();
|
||||
return MediaType.parse(MimeTypeMap.getSingleton().getMimeTypeFromExtension(name.substring(name.lastIndexOf('.')+1)));
|
||||
}
|
||||
|
||||
public static void loadCustomEmojiInTextView(TextView view){
|
||||
CharSequence _text=view.getText();
|
||||
if(!(_text instanceof Spanned))
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.joinmastodon.android.ui.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class SizeListenerFrameLayout extends FrameLayout{
|
||||
private OnSizeChangedListener sizeListener;
|
||||
|
||||
public SizeListenerFrameLayout(Context context){
|
||||
super(context);
|
||||
}
|
||||
|
||||
public SizeListenerFrameLayout(Context context, @Nullable AttributeSet attrs){
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public SizeListenerFrameLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr){
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh){
|
||||
if(sizeListener!=null)
|
||||
sizeListener.onSizeChanged(w, h, oldw, oldh);
|
||||
}
|
||||
|
||||
public void setSizeListener(OnSizeChangedListener sizeListener){
|
||||
this.sizeListener=sizeListener;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface OnSizeChangedListener{
|
||||
void onSizeChanged(int w, int h, int oldw, int oldh);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@ package org.joinmastodon.android.ui.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -32,13 +30,6 @@ public class SizeListenerLinearLayout extends LinearLayout{
|
||||
public void setSizeListener(OnSizeChangedListener sizeListener){
|
||||
this.sizeListener=sizeListener;
|
||||
}
|
||||
//
|
||||
// @Override
|
||||
// public View findFocus(){
|
||||
// View v=super.findFocus();
|
||||
// Log.w("11", "findFocus() "+v);
|
||||
// return v;
|
||||
// }
|
||||
|
||||
@FunctionalInterface
|
||||
public interface OnSizeChangedListener{
|
||||
|
||||
Reference in New Issue
Block a user