Merge branch 'develop'

This commit is contained in:
tom79 2019-05-31 19:15:15 +02:00
commit 9a218ba5af
126 changed files with 3132 additions and 190 deletions

View File

@ -6,8 +6,8 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 28 targetSdkVersion 28
versionCode 274 versionCode 276
versionName "2.2.0" versionName "2.3.0"
multiDexEnabled true multiDexEnabled true
renderscriptTargetApi 28 as int renderscriptTargetApi 28 as int
renderscriptSupportModeEnabled true renderscriptSupportModeEnabled true
@ -102,4 +102,6 @@ dependencies {
implementation 'com.github.stom79:horizontalbargraph:1.5' implementation 'com.github.stom79:horizontalbargraph:1.5'
implementation 'jp.wasabeef:glide-transformations:4.0.0' implementation 'jp.wasabeef:glide-transformations:4.0.0'
playstoreImplementation "io.github.kobakei:ratethisapp:$ratethisappLibraryVersion" playstoreImplementation "io.github.kobakei:ratethisapp:$ratethisappLibraryVersion"
implementation 'ja.burhanrashid52:photoeditor:0.3.3'
implementation 'com.github.yalantis:ucrop:2.2.3'
} }

View File

@ -161,6 +161,15 @@
android:label="@string/app_name" android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize" android:configChanges="keyboardHidden|orientation|screenSize"
/> />
<activity android:name="app.fedilab.android.activities.PhotoEditorActivity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize"
/>
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
<activity android:name="app.fedilab.android.activities.WebviewActivity" <activity android:name="app.fedilab.android.activities.WebviewActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize" android:configChanges="keyboardHidden|orientation|screenSize"

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

View File

@ -1,15 +1,26 @@
package app.fedilab.android.activities; package app.fedilab.android.activities;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import com.franmontiel.localechanger.LocaleChanger; import com.franmontiel.localechanger.LocaleChanger;
import com.vanniktech.emoji.EmojiManager; import com.vanniktech.emoji.EmojiManager;
import com.vanniktech.emoji.one.EmojiOneProvider; import com.vanniktech.emoji.one.EmojiOneProvider;
import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.Helper;
import es.dmoral.toasty.Toasty;
/** /**
* Created by Thomas on 12/12/2017. * Created by Thomas on 12/12/2017.
@ -18,6 +29,11 @@ import app.fedilab.android.helper.Helper;
@SuppressLint("Registered") @SuppressLint("Registered")
public class BaseActivity extends AppCompatActivity { public class BaseActivity extends AppCompatActivity {
public static final int READ_WRITE_STORAGE = 52;
private ProgressDialog mProgressDialog;
static { static {
Helper.installProvider(); Helper.installProvider();
EmojiManager.install(new EmojiOneProvider()); EmojiManager.install(new EmojiOneProvider());
@ -34,4 +50,52 @@ public class BaseActivity extends AppCompatActivity {
newBase = LocaleChanger.configureBaseContext(newBase); newBase = LocaleChanger.configureBaseContext(newBase);
super.attachBaseContext(newBase); super.attachBaseContext(newBase);
} }
public boolean requestPermission(String permission) {
boolean isGranted = ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED;
if (!isGranted) {
ActivityCompat.requestPermissions(
this,
new String[]{permission},
READ_WRITE_STORAGE);
}
return isGranted;
}
public void isPermissionGranted(boolean isGranted, String permission) {
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case READ_WRITE_STORAGE:
isPermissionGranted(grantResults[0] == PackageManager.PERMISSION_GRANTED, permissions[0]);
break;
}
}
protected void showLoading(@NonNull String message) {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage(message);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
protected void hideLoading() {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
}
protected void showSnackbar(@NonNull String message) {
View view = findViewById(android.R.id.content);
if (view != null) {
Snackbar.make(view, message, Snackbar.LENGTH_SHORT).show();
} else {
Toasty.info(this, message, Toast.LENGTH_SHORT).show();
}
}
} }

View File

@ -0,0 +1,516 @@
package app.fedilab.android.activities;
/* Copyright 2017 Thomas Schneider
*
* This file is a part of Fedilab
*
* This program 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.
*
* Fedilab 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 Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.view.Window;
import app.fedilab.android.R;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.imageeditor.EmojiBSFragment;
import app.fedilab.android.imageeditor.PropertiesBSFragment;
import app.fedilab.android.imageeditor.StickerBSFragment;
import app.fedilab.android.imageeditor.TextEditorDialogFragment;
import app.fedilab.android.imageeditor.filters.FilterListener;
import app.fedilab.android.imageeditor.filters.FilterViewAdapter;
import app.fedilab.android.imageeditor.tools.EditingToolsAdapter;
import app.fedilab.android.imageeditor.tools.ToolType;
import ja.burhanrashid52.photoeditor.PhotoEditor;
import ja.burhanrashid52.photoeditor.PhotoEditorView;
import ja.burhanrashid52.photoeditor.PhotoFilter;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.provider.MediaStore;
import android.support.constraint.ConstraintLayout;
import android.support.constraint.ConstraintSet;
import android.support.transition.ChangeBounds;
import android.support.transition.TransitionManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.animation.AnticipateOvershootInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.yalantis.ucrop.UCrop;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import ja.burhanrashid52.photoeditor.OnPhotoEditorListener;
import ja.burhanrashid52.photoeditor.SaveSettings;
import ja.burhanrashid52.photoeditor.ViewType;
public class PhotoEditorActivity extends BaseActivity implements OnPhotoEditorListener,
View.OnClickListener,
PropertiesBSFragment.Properties,
EmojiBSFragment.EmojiListener,
StickerBSFragment.StickerListener, EditingToolsAdapter.OnItemSelected, FilterListener {
private static final int CAMERA_REQUEST = 52;
private static final int PICK_REQUEST = 53;
private PhotoEditor mPhotoEditor;
private PhotoEditorView mPhotoEditorView;
private PropertiesBSFragment mPropertiesBSFragment;
private EmojiBSFragment mEmojiBSFragment;
private StickerBSFragment mStickerBSFragment;
private TextView mTxtCurrentTool;
private RecyclerView mRvTools, mRvFilters;
private EditingToolsAdapter mEditingToolsAdapter = new EditingToolsAdapter(this);
private FilterViewAdapter mFilterViewAdapter = new FilterViewAdapter(this);
private ConstraintLayout mRootView;
private ConstraintSet mConstraintSet = new ConstraintSet();
private boolean mIsFilterVisible;
private Uri uri;
private String tempname;
private boolean exit;
@SuppressLint("MissingPermission")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
switch (theme){
case Helper.THEME_LIGHT:
setTheme(R.style.AppTheme);
break;
case Helper.THEME_DARK:
setTheme(R.style.AppThemeDark);
break;
case Helper.THEME_BLACK:
setTheme(R.style.AppThemeBlack);
break;
default:
setTheme(R.style.AppThemeDark);
}
Bundle b = getIntent().getExtras();
if( getSupportActionBar() != null)
getSupportActionBar().hide();
String path = null;
if(b != null)
path = b.getString("imageUri", null);
if( path == null) {
finish();
}
uri = Uri.parse(path);
exit = false;
setContentView(R.layout.activity_photoeditor);
initViews();
mPropertiesBSFragment = new PropertiesBSFragment();
mEmojiBSFragment = new EmojiBSFragment();
mStickerBSFragment = new StickerBSFragment();
mStickerBSFragment.setStickerListener(this);
mEmojiBSFragment.setEmojiListener(this);
mPropertiesBSFragment.setPropertiesChangeListener(this);
LinearLayoutManager llmTools = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
mRvTools.setLayoutManager(llmTools);
mRvTools.setAdapter(mEditingToolsAdapter);
LinearLayoutManager llmFilters = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
mRvFilters.setLayoutManager(llmFilters);
mRvFilters.setAdapter(mFilterViewAdapter);
Typeface mEmojiTypeFace = Typeface.createFromAsset(getAssets(), "emojione-android.ttf");
mPhotoEditor = new PhotoEditor.Builder(this, mPhotoEditorView)
.setPinchTextScalable(true) // set flag to make text scalable when pinch
.setDefaultEmojiTypeface(mEmojiTypeFace)
.build(); // build photo editor sdk
mPhotoEditor.setOnPhotoEditorListener(this);
//Set Image Dynamically
mPhotoEditorView.getSource().setImageURI(uri);
Button send = findViewById(R.id.send);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
exit = true;
saveImage();
}
});
}
private void initViews() {
ImageView imgUndo;
ImageView imgRedo;
ImageView imgCamera;
ImageView imgGallery;
ImageView imgSave;
ImageView imgClose;
mPhotoEditorView = findViewById(R.id.photoEditorView);
mTxtCurrentTool = findViewById(R.id.txtCurrentTool);
mRvTools = findViewById(R.id.rvConstraintTools);
mRvFilters = findViewById(R.id.rvFilterView);
mRootView = findViewById(R.id.rootView);
imgUndo = findViewById(R.id.imgUndo);
imgUndo.setOnClickListener(this);
imgRedo = findViewById(R.id.imgRedo);
imgRedo.setOnClickListener(this);
imgCamera = findViewById(R.id.imgCamera);
imgCamera.setOnClickListener(this);
imgGallery = findViewById(R.id.imgGallery);
imgGallery.setOnClickListener(this);
imgSave = findViewById(R.id.imgSave);
imgSave.setOnClickListener(this);
imgClose = findViewById(R.id.imgClose);
imgClose.setOnClickListener(this);
}
@Override
public void onEditTextChangeListener(final View rootView, String text, int colorCode) {
TextEditorDialogFragment textEditorDialogFragment =
TextEditorDialogFragment.show(this, text, colorCode);
textEditorDialogFragment.setOnTextEditorListener(new TextEditorDialogFragment.TextEditor() {
@Override
public void onDone(String inputText, int colorCode) {
mPhotoEditor.editText(rootView, inputText, colorCode);
mTxtCurrentTool.setText(R.string.label_text);
}
});
}
@Override
public void onAddViewListener(ViewType viewType, int numberOfAddedViews) {
}
@Override
public void onRemoveViewListener(int numberOfAddedViews) {
}
@Override
public void onRemoveViewListener(ViewType viewType, int numberOfAddedViews) {
}
@Override
public void onStartViewChangeListener(ViewType viewType) {
}
@Override
public void onStopViewChangeListener(ViewType viewType) {
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.imgUndo:
mPhotoEditor.undo();
break;
case R.id.imgRedo:
mPhotoEditor.redo();
break;
case R.id.imgSave:
saveImage();
break;
case R.id.imgClose:
onBackPressed();
break;
case R.id.imgCamera:
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
break;
case R.id.imgGallery:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, getString(R.string.toot_select_image)), PICK_REQUEST);
break;
}
}
@SuppressLint("MissingPermission")
private void saveImage() {
if (requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showLoading(getString(R.string.saving));
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
String myDir = sharedpreferences.getString(Helper.SET_FOLDER_RECORD, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath());
String filename = System.currentTimeMillis()+"_"+Helper.getFileName(PhotoEditorActivity.this, uri);
File file = new File(myDir+"/"+filename);
try {
file.createNewFile();
SaveSettings saveSettings = new SaveSettings.Builder()
.setClearViewsEnabled(true)
.setTransparencyEnabled(true)
.build();
mPhotoEditor.saveAsFile(file.getAbsolutePath(), saveSettings, new PhotoEditor.OnSaveListener() {
@Override
public void onSuccess(@NonNull String imagePath) {
hideLoading();
showSnackbar(getString(R.string.image_saved));
mPhotoEditorView.getSource().setImageURI(Uri.fromFile(new File(imagePath)));
if( exit ){
Intent intentImage = new Intent(Helper.INTENT_SEND_MODIFIED_IMAGE);
intentImage.putExtra("imgpath", imagePath);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intentImage);
finish();
}
}
@Override
public void onFailure(@NonNull Exception exception) {
hideLoading();
showSnackbar(getString(R.string.save_image_failed));
}
});
} catch (IOException e) {
e.printStackTrace();
hideLoading();
showSnackbar(e.getMessage());
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case CAMERA_REQUEST:
mPhotoEditor.clearAllViews();
Bitmap photo = (Bitmap) data.getExtras().get("data");
mPhotoEditorView.getSource().setImageBitmap(photo);
break;
case PICK_REQUEST:
try {
mPhotoEditor.clearAllViews();
Uri uri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
mPhotoEditorView.getSource().setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
break;
case UCrop.REQUEST_CROP:
final Uri resultUri = UCrop.getOutput(data);
if( resultUri != null) {
mPhotoEditorView.getSource().setImageURI(resultUri);
File fdelete = new File(uri.getPath());
if (fdelete.exists()) {
fdelete.delete();
}
uri = resultUri;
String filename = System.currentTimeMillis()+"_"+Helper.getFileName(PhotoEditorActivity.this, uri);
tempname = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(new Date()) + filename;
}
break;
}
}
}
@Override
public void onColorChanged(int colorCode) {
mPhotoEditor.setBrushColor(colorCode);
mTxtCurrentTool.setText(R.string.label_brush);
}
@Override
public void onOpacityChanged(int opacity) {
mPhotoEditor.setOpacity(opacity);
mTxtCurrentTool.setText(R.string.label_brush);
}
@Override
public void onBrushSizeChanged(int brushSize) {
mPhotoEditor.setBrushSize(brushSize);
mTxtCurrentTool.setText(R.string.label_brush);
}
@Override
public void onEmojiClick(String emojiUnicode) {
mPhotoEditor.addEmoji(emojiUnicode);
mTxtCurrentTool.setText(R.string.label_emoji);
}
@Override
public void onStickerClick(Bitmap bitmap) {
mPhotoEditor.addImage(bitmap);
mTxtCurrentTool.setText(R.string.label_sticker);
}
@Override
public void isPermissionGranted(boolean isGranted, String permission) {
if (isGranted) {
saveImage();
}
}
private void showSaveDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage( getString(R.string.confirm_exit_editing));
builder.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
saveImage();
}
});
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.setNeutralButton(R.string.discard, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.create().show();
}
@Override
public void onFilterSelected(PhotoFilter photoFilter) {
mPhotoEditor.setFilterEffect(photoFilter);
}
@Override
public void onToolSelected(ToolType toolType) {
switch (toolType) {
case BRUSH:
mPhotoEditor.setBrushDrawingMode(true);
mTxtCurrentTool.setText(R.string.label_brush);
mPropertiesBSFragment.show(getSupportFragmentManager(), mPropertiesBSFragment.getTag());
break;
case TEXT:
TextEditorDialogFragment textEditorDialogFragment = TextEditorDialogFragment.show(this);
textEditorDialogFragment.setOnTextEditorListener(new TextEditorDialogFragment.TextEditor() {
@Override
public void onDone(String inputText, int colorCode) {
mPhotoEditor.addText(inputText, colorCode);
mTxtCurrentTool.setText(R.string.label_text);
}
});
break;
case ERASER:
mPhotoEditor.brushEraser();
mTxtCurrentTool.setText(R.string.label_eraser);
break;
case FILTER:
mTxtCurrentTool.setText(R.string.label_filter);
showFilter(true);
break;
case EMOJI:
mEmojiBSFragment.show(getSupportFragmentManager(), mEmojiBSFragment.getTag());
break;
case STICKER:
mStickerBSFragment.show(getSupportFragmentManager(), mStickerBSFragment.getTag());
break;
case CROP:
String filename = System.currentTimeMillis()+"_"+Helper.getFileName(PhotoEditorActivity.this, uri);
tempname = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(new Date()) + filename;
UCrop.of(uri, Uri.fromFile(new File(getCacheDir(),tempname)))
.start(PhotoEditorActivity.this);
break;
}
}
void showFilter(boolean isVisible) {
mIsFilterVisible = isVisible;
mConstraintSet.clone(mRootView);
if (isVisible) {
mConstraintSet.clear(mRvFilters.getId(), ConstraintSet.START);
mConstraintSet.connect(mRvFilters.getId(), ConstraintSet.START,
ConstraintSet.PARENT_ID, ConstraintSet.START);
mConstraintSet.connect(mRvFilters.getId(), ConstraintSet.END,
ConstraintSet.PARENT_ID, ConstraintSet.END);
} else {
mConstraintSet.connect(mRvFilters.getId(), ConstraintSet.START,
ConstraintSet.PARENT_ID, ConstraintSet.END);
mConstraintSet.clear(mRvFilters.getId(), ConstraintSet.END);
}
ChangeBounds changeBounds = new ChangeBounds();
changeBounds.setDuration(350);
changeBounds.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
TransitionManager.beginDelayedTransition(mRootView, changeBounds);
mConstraintSet.applyTo(mRootView);
}
@Override
public void onBackPressed() {
if (mIsFilterVisible) {
showFilter(false);
mTxtCurrentTool.setText(R.string.app_name);
} else if (!mPhotoEditor.isCacheEmpty()) {
showSaveDialog();
} else {
super.onBackPressed();
}
}
}

View File

@ -18,15 +18,19 @@ import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ClipData; import android.content.ClipData;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
@ -39,6 +43,7 @@ import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider; import android.support.v4.content.FileProvider;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
@ -107,6 +112,7 @@ import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import app.fedilab.android.BuildConfig;
import app.fedilab.android.client.API; import app.fedilab.android.client.API;
import app.fedilab.android.client.APIResponse; import app.fedilab.android.client.APIResponse;
import app.fedilab.android.client.Entities.Account; import app.fedilab.android.client.Entities.Account;
@ -154,6 +160,7 @@ import app.fedilab.android.interfaces.OnRetrieveAttachmentInterface;
import app.fedilab.android.interfaces.OnRetrieveEmojiInterface; import app.fedilab.android.interfaces.OnRetrieveEmojiInterface;
import app.fedilab.android.interfaces.OnRetrieveSearcAccountshInterface; import app.fedilab.android.interfaces.OnRetrieveSearcAccountshInterface;
import app.fedilab.android.interfaces.OnRetrieveSearchInterface; import app.fedilab.android.interfaces.OnRetrieveSearchInterface;
import static app.fedilab.android.helper.Helper.changeDrawableColor; import static app.fedilab.android.helper.Helper.changeDrawableColor;
import static app.fedilab.android.helper.Helper.countWithEmoji; import static app.fedilab.android.helper.Helper.countWithEmoji;
@ -231,7 +238,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(getApplicationContext())); instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(getApplicationContext()));
final int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); final int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
switch (theme){ switch (theme) {
case Helper.THEME_LIGHT: case Helper.THEME_LIGHT:
setTheme(R.style.AppTheme); setTheme(R.style.AppTheme);
break; break;
@ -246,21 +253,21 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
} }
if (theme == Helper.THEME_DARK) { if (theme == Helper.THEME_DARK) {
style = R.style.DialogDark; style = R.style.DialogDark;
} else if (theme == Helper.THEME_BLACK){ } else if (theme == Helper.THEME_BLACK) {
style = R.style.DialogBlack; style = R.style.DialogBlack;
}else { } else {
style = R.style.Dialog; style = R.style.Dialog;
} }
filesMap = new HashMap<>(); filesMap = new HashMap<>();
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA){ if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) {
max_media_count = 9999; max_media_count = 9999;
}else{ } else {
max_media_count = 4; max_media_count = 4;
} }
autocomplete = false; autocomplete = false;
setContentView(R.layout.activity_toot); setContentView(R.layout.activity_toot);
ActionBar actionBar = getSupportActionBar(); ActionBar actionBar = getSupportActionBar();
if( actionBar != null ) { if (actionBar != null) {
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE); LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
assert inflater != null; assert inflater != null;
@SuppressLint("InflateParams") View view = inflater.inflate(R.layout.toot_action_bar, null); @SuppressLint("InflateParams") View view = inflater.inflate(R.layout.toot_action_bar, null);
@ -277,7 +284,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
finish(); finish();
} }
}); });
if (theme == Helper.THEME_LIGHT){ if (theme == Helper.THEME_LIGHT) {
Toolbar toolbar = actionBar.getCustomView().findViewById(R.id.toolbar); Toolbar toolbar = actionBar.getCustomView().findViewById(R.id.toolbar);
Helper.colorizeToolbar(toolbar, R.color.black, TootActivity.this); Helper.colorizeToolbar(toolbar, R.color.black, TootActivity.this);
} }
@ -297,7 +304,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
Button toot_cw = findViewById(R.id.toot_cw); Button toot_cw = findViewById(R.id.toot_cw);
toot_space_left = findViewById(R.id.toot_space_left); toot_space_left = findViewById(R.id.toot_space_left);
toot_visibility = findViewById(R.id.toot_visibility); toot_visibility = findViewById(R.id.toot_visibility);
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA) if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA)
toot_visibility.setVisibility(View.GONE); toot_visibility.setVisibility(View.GONE);
toot_picture = findViewById(R.id.toot_picture); toot_picture = findViewById(R.id.toot_picture);
toot_picture_container = findViewById(R.id.toot_picture_container); toot_picture_container = findViewById(R.id.toot_picture_container);
@ -311,7 +318,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
ImageButton toot_emoji = findViewById(R.id.toot_emoji); ImageButton toot_emoji = findViewById(R.id.toot_emoji);
poll_action = findViewById(R.id.poll_action); poll_action = findViewById(R.id.poll_action);
isScheduled = false; isScheduled = false;
if( sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, true)) { if (sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, true)) {
final EmojiPopup emojiPopup = EmojiPopup.Builder.fromRootView(drawer_layout).build(toot_content); final EmojiPopup emojiPopup = EmojiPopup.Builder.fromRootView(drawer_layout).build(toot_content);
toot_emoji.setOnClickListener(new View.OnClickListener() { toot_emoji.setOnClickListener(new View.OnClickListener() {
@ -320,7 +327,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
emojiPopup.toggle(); // Toggles visibility of the Popup. emojiPopup.toggle(); // Toggles visibility of the Popup.
} }
}); });
}else { } else {
toot_emoji.setVisibility(View.GONE); toot_emoji.setVisibility(View.GONE);
} }
@ -334,7 +341,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
params.height = (int) Helper.convertDpToPixel(50, getApplicationContext()); params.height = (int) Helper.convertDpToPixel(50, getApplicationContext());
params.width = (int) Helper.convertDpToPixel(50, getApplicationContext()); params.width = (int) Helper.convertDpToPixel(50, getApplicationContext());
toot_picture_container.setLayoutParams(params); toot_picture_container.setLayoutParams(params);
}else { } else {
ViewGroup.LayoutParams params = toot_picture_container.getLayoutParams(); ViewGroup.LayoutParams params = toot_picture_container.getLayoutParams();
params.height = (int) Helper.convertDpToPixel(100, getApplicationContext()); params.height = (int) Helper.convertDpToPixel(100, getApplicationContext());
params.width = (int) Helper.convertDpToPixel(100, getApplicationContext()); params.width = (int) Helper.convertDpToPixel(100, getApplicationContext());
@ -347,13 +354,13 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
ArrayList<Uri> sharedUri = new ArrayList<>(); ArrayList<Uri> sharedUri = new ArrayList<>();
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
restored = -1; restored = -1;
if(b != null) { if (b != null) {
tootReply = b.getParcelable("tootReply"); tootReply = b.getParcelable("tootReply");
scheduledstatus = b.getParcelable("storedStatus"); scheduledstatus = b.getParcelable("storedStatus");
String accountReplyToken = b.getString("accountReplyToken", null); String accountReplyToken = b.getString("accountReplyToken", null);
accountReply = null; accountReply = null;
if( accountReplyToken != null){ if (accountReplyToken != null) {
accountReply = new AccountDAO(getApplicationContext(),db).getAccountByToken(accountReplyToken); accountReply = new AccountDAO(getApplicationContext(), db).getAccountByToken(accountReplyToken);
} }
tootMention = b.getString("tootMention", null); tootMention = b.getString("tootMention", null);
urlMention = b.getString("urlMention", null); urlMention = b.getString("urlMention", null);
@ -374,7 +381,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
} }
} }
// ACTION_SEND_MULTIPLE route // ACTION_SEND_MULTIPLE route
else if( b.getInt("uriNumberMast", 0) > 1) { else if (b.getInt("uriNumberMast", 0) > 1) {
ArrayList<Uri> fileUri = b.getParcelableArrayList("sharedUri"); ArrayList<Uri> fileUri = b.getParcelableArrayList("sharedUri");
if (fileUri != null) { if (fileUri != null) {
@ -383,42 +390,42 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
} }
restored = b.getLong("restored", -1); restored = b.getLong("restored", -1);
} }
if( scheduledstatus != null) if (scheduledstatus != null)
toot_it.setText(R.string.modify); toot_it.setText(R.string.modify);
if(restoredScheduled){ if (restoredScheduled) {
toot_it.setVisibility(View.GONE); toot_it.setVisibility(View.GONE);
invalidateOptionsMenu(); invalidateOptionsMenu();
} }
String userIdReply; String userIdReply;
if( accountReply == null) if (accountReply == null)
userIdReply = sharedpreferences.getString(Helper.PREF_KEY_ID, null); userIdReply = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
else else
userIdReply = accountReply.getId(); userIdReply = accountReply.getId();
if( accountReply == null) if (accountReply == null)
account = new AccountDAO(getApplicationContext(),db).getAccountByID(userIdReply); account = new AccountDAO(getApplicationContext(), db).getAccountByID(userIdReply);
else else
account = accountReply; account = accountReply;
if( MainActivity.social == null){ if (MainActivity.social == null) {
//Update the static variable which manages account type //Update the static variable which manages account type
if( account.getSocial() == null || account.getSocial().equals("MASTODON")) if (account.getSocial() == null || account.getSocial().equals("MASTODON"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.MASTODON; MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.MASTODON;
else if( account.getSocial().equals("PEERTUBE")) else if (account.getSocial().equals("PEERTUBE"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE; MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE;
else if( account.getSocial().equals("PIXELFED")) else if (account.getSocial().equals("PIXELFED"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED; MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED;
else if( account.getSocial().equals("PLEROMA")) else if (account.getSocial().equals("PLEROMA"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA; MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA;
else if( account.getSocial().equals("GNU")) else if (account.getSocial().equals("GNU"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.GNU; MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.GNU;
else if( account.getSocial().equals("FRIENDICA")) else if (account.getSocial().equals("FRIENDICA"))
MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA; MainActivity.social = UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA;
} }
switch (MainActivity.social){ switch (MainActivity.social) {
case GNU: case GNU:
toot_it.setText(getText(R.string.queet_it)); toot_it.setText(getText(R.string.queet_it));
break; break;
@ -432,18 +439,17 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
toot_it.setText(getText(R.string.toot_it)); toot_it.setText(getText(R.string.toot_it));
} }
if( tootReply != null) { if (tootReply != null) {
tootReply(); tootReply();
}else { } else {
if( title != null) { if (title != null) {
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU) if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU)
title.setText(getString(R.string.queet_title)); title.setText(getString(R.string.queet_title));
else else
title.setText(getString(R.string.toot_title)); title.setText(getString(R.string.toot_title));
} } else {
else { if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU)
if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU)
setTitle(R.string.queet_title); setTitle(R.string.queet_title);
else else
setTitle(R.string.toot_title); setTitle(R.string.toot_title);
@ -451,12 +457,12 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
} }
toot_content.requestFocus(); toot_content.requestFocus();
if( mentionAccount != null){ if (mentionAccount != null) {
toot_content.setText(String.format("@%s\n", mentionAccount)); toot_content.setText(String.format("@%s\n", mentionAccount));
toot_content.setSelection(toot_content.getText().length()); toot_content.setSelection(toot_content.getText().length());
toot_space_left.setText(String.valueOf(countLength())); toot_space_left.setText(String.valueOf(countLength()));
} }
if( tootMention != null && urlMention != null) { if (tootMention != null && urlMention != null) {
if (fileMention != null) { if (fileMention != null) {
Bitmap pictureMention = BitmapFactory.decodeFile(getCacheDir() + "/" + fileMention); Bitmap pictureMention = BitmapFactory.decodeFile(getCacheDir() + "/" + fileMention);
AsyncTask.execute(new Runnable() { AsyncTask.execute(new Runnable() {
@ -488,20 +494,19 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
initialContent = toot_content.getText().toString(); initialContent = toot_content.getText().toString();
String url = account.getAvatar(); String url = account.getAvatar();
if( url.startsWith("/") ){ if (url.startsWith("/")) {
url = Helper.getLiveInstanceWithProtocol(getApplicationContext()) + account.getAvatar(); url = Helper.getLiveInstanceWithProtocol(getApplicationContext()) + account.getAvatar();
} }
Helper.loadGiF(getApplicationContext(), url, pp_actionBar); Helper.loadGiF(getApplicationContext(), url, pp_actionBar);
if( sharedContent != null ){ //Shared content if (sharedContent != null) { //Shared content
if( sharedSubject != null){ if (sharedSubject != null) {
sharedContent = sharedSubject + "\n\n" + sharedContent; sharedContent = sharedSubject + "\n\n" + sharedContent;
} }
if( b != null) { if (b != null) {
final String image = b.getString("image"); final String image = b.getString("image");
String title = b.getString("title"); String title = b.getString("title");
String description = b.getString("description"); String description = b.getString("description");
@ -537,8 +542,8 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
} }
if( tootReply == null) { if (tootReply == null) {
if( visibility == null) { if (visibility == null) {
String defaultVisibility = account.isLocked() ? "private" : "public"; String defaultVisibility = account.isLocked() ? "private" : "public";
visibility = sharedpreferences.getString(Helper.SET_TOOT_VISIBILITY + "@" + account.getAcct() + "@" + account.getInstance(), defaultVisibility); visibility = sharedpreferences.getString(Helper.SET_TOOT_VISIBILITY + "@" + account.getAcct() + "@" + account.getInstance(), defaultVisibility);
} }
@ -568,10 +573,10 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
toot_cw.setOnClickListener(new View.OnClickListener() { toot_cw.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if(toot_cw_content.getVisibility() == View.GONE) { if (toot_cw_content.getVisibility() == View.GONE) {
toot_cw_content.setVisibility(View.VISIBLE); toot_cw_content.setVisibility(View.VISIBLE);
toot_cw_content.requestFocus(); toot_cw_content.requestFocus();
}else { } else {
toot_cw_content.setVisibility(View.GONE); toot_cw_content.setVisibility(View.GONE);
toot_cw_content.setText(""); toot_cw_content.setText("");
toot_content.requestFocus(); toot_content.requestFocus();
@ -593,7 +598,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
} }
}); });
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA)
toot_it.setOnLongClickListener(new View.OnLongClickListener() { toot_it.setOnLongClickListener(new View.OnLongClickListener() {
@Override @Override
public boolean onLongClick(View v) { public boolean onLongClick(View v) {
@ -602,7 +607,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
.inflate(R.menu.main_content_type, popup.getMenu()); .inflate(R.menu.main_content_type, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){ switch (item.getItemId()) {
case R.id.action_plain_text: case R.id.action_plain_text:
contentType = "text/plain"; contentType = "text/plain";
break; break;
@ -648,14 +653,14 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
String[] mimetypes = {"image/*", "video/*"}; String[] mimetypes = {"image/*", "video/*"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes); intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
startActivityForResult(intent, PICK_IMAGE); startActivityForResult(intent, PICK_IMAGE);
}else { } else {
intent.setType("image/* video/*"); intent.setType("image/* video/*");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
} }
Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent chooserIntent = Intent.createChooser(intent, getString(R.string.toot_select_image)); Intent chooserIntent = Intent.createChooser(intent, getString(R.string.toot_select_image));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {pickIntent}); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent});
startActivityForResult(chooserIntent, PICK_IMAGE); startActivityForResult(chooserIntent, PICK_IMAGE);
} }
@ -672,9 +677,13 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
toot_cw_content.addTextChangedListener(new TextWatcher() { toot_cw_content.addTextChangedListener(new TextWatcher() {
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {} public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override @Override
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
toot_space_left.setText(String.valueOf(countLength())); toot_space_left.setText(String.valueOf(countLength()));
@ -788,15 +797,14 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
toot_space_left.setText(String.valueOf(totalChar)); toot_space_left.setText(String.valueOf(totalChar));
} }
}; };
if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA)
toot_content.addTextChangedListener(textWatcher); toot_content.addTextChangedListener(textWatcher);
if (scheduledstatus != null)
if( scheduledstatus != null)
restoreServerSchedule(scheduledstatus.getStatus()); restoreServerSchedule(scheduledstatus.getStatus());
if( restored != -1 ){ if (restored != -1) {
restoreToot(restored); restoreToot(restored);
} }
@ -808,11 +816,26 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
}); });
toot_space_left.setText(String.valueOf(countLength())); toot_space_left.setText(String.valueOf(countLength()));
LocalBroadcastManager.getInstance(this)
.registerReceiver(imageReceiver,
new IntentFilter(Helper.INTENT_SEND_MODIFIED_IMAGE));
} }
private BroadcastReceiver imageReceiver = new BroadcastReceiver() {
@Override @Override
public void onDestroy(){ public void onReceive(Context context, Intent intent) {
String imgpath = intent.getStringExtra("imgpath");
if( imgpath != null)
new asyncPicture(TootActivity.this, account, Uri.fromFile(new File(imgpath))).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
};
@Override
public void onDestroy() {
super.onDestroy(); super.onDestroy();
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(imageReceiver);
} }
@ -831,7 +854,8 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
} }
} }
} }
public void showAToast (String message){
public void showAToast(String message) {
if (mToast != null) { if (mToast != null) {
mToast.cancel(); mToast.cancel();
} }
@ -844,7 +868,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
public void uploadSharedImage(ArrayList<Uri> uri) { public void uploadSharedImage(ArrayList<Uri> uri) {
if (!uri.isEmpty()) { if (!uri.isEmpty()) {
int count = 0; int count = 0;
for(Uri fileUri: uri) { for (Uri fileUri : uri) {
if (fileUri != null) { if (fileUri != null) {
if (count == max_media_count) { if (count == max_media_count) {
break; break;
@ -855,12 +879,12 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
count++; count++;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show(); Toasty.error(getApplicationContext(), getString(R.string.toot_select_image_error), Toast.LENGTH_LONG).show();
toot_picture.setEnabled(true); toot_picture.setEnabled(true);
toot_it.setEnabled(true); toot_it.setEnabled(true);
} }
} else { } else {
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show(); Toasty.error(getApplicationContext(), getString(R.string.toot_select_image_error), Toast.LENGTH_LONG).show();
} }
} }
} }
@ -878,12 +902,19 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
try { try {
photoFile = createImageFile(); photoFile = createImageFile();
} catch (IOException ignored) { } catch (IOException ignored) {
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show();} Toasty.error(getApplicationContext(), getString(R.string.toot_select_image_error), Toast.LENGTH_LONG).show();
}
// Continue only if the File was successfully created // Continue only if the File was successfully created
if (photoFile != null) { if (photoFile != null) {
if (!BuildConfig.DONATIONS) {
photoFileUri = FileProvider.getUriForFile(this, photoFileUri = FileProvider.getUriForFile(this,
"app.fedilab.android.fileProvider", "app.fedilab.android.fileProvider",
photoFile); photoFile);
}else {
photoFileUri = FileProvider.getUriForFile(this,
"fr.gouv.etalab.mastodon.fileProvider",
photoFile);
}
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoFileUri); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoFileUri);
startActivityForResult(takePictureIntent, TAKE_PHOTO); startActivityForResult(takePictureIntent, TAKE_PHOTO);
} }
@ -909,19 +940,21 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
boolean photo_editor = sharedpreferences.getBoolean(Helper.SET_PHOTO_EDITOR, true);
if (requestCode == PICK_IMAGE && resultCode == RESULT_OK) { if (requestCode == PICK_IMAGE && resultCode == RESULT_OK) {
picture_scrollview.setVisibility(View.VISIBLE); picture_scrollview.setVisibility(View.VISIBLE);
if (data == null){ if (data == null) {
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show(); Toasty.error(getApplicationContext(), getString(R.string.toot_select_image_error), Toast.LENGTH_LONG).show();
return; return;
} }
ClipData clipData = data.getClipData(); ClipData clipData = data.getClipData();
if (data.getData() == null && clipData == null) { if (data.getData() == null && clipData == null) {
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show(); Toasty.error(getApplicationContext(), getString(R.string.toot_select_image_error), Toast.LENGTH_LONG).show();
return; return;
} }
if( clipData != null ){ if (clipData != null) {
ArrayList<Uri> mArrayUri = new ArrayList<>(); ArrayList<Uri> mArrayUri = new ArrayList<>();
for (int i = 0; i < clipData.getItemCount(); i++) { for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i); ClipData.Item item = clipData.getItemAt(i);
@ -929,16 +962,24 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
mArrayUri.add(uri); mArrayUri.add(uri);
} }
uploadSharedImage(mArrayUri); uploadSharedImage(mArrayUri);
}else{ } else {
try { try {
String filename = Helper.getFileName(TootActivity.this, data.getData()); String filename = Helper.getFileName(TootActivity.this, data.getData());
ContentResolver cr = getContentResolver(); ContentResolver cr = getContentResolver();
String mime = cr.getType(data.getData()); String mime = cr.getType(data.getData());
if(mime != null && (mime.toLowerCase().contains("video") || mime.toLowerCase().contains("gif")) ) { if (mime != null && (mime.toLowerCase().contains("video") || mime.toLowerCase().contains("gif"))) {
InputStream inputStream = getContentResolver().openInputStream(data.getData()); InputStream inputStream = getContentResolver().openInputStream(data.getData());
new HttpsConnection(TootActivity.this, instance).upload(inputStream, filename, account, TootActivity.this); new HttpsConnection(TootActivity.this, instance).upload(inputStream, filename, account, TootActivity.this);
} else if(mime != null && mime.toLowerCase().contains("image")) { } else if (mime != null && mime.toLowerCase().contains("image")) {
if( photo_editor) {
Intent intent = new Intent(TootActivity.this, PhotoEditorActivity.class);
Bundle b = new Bundle();
intent.putExtra("imageUri", data.getData().toString());
intent.putExtras(b);
startActivity(intent);
}else{
new asyncPicture(TootActivity.this, account, data.getData()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new asyncPicture(TootActivity.this, account, data.getData()).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}else { }else {
Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show(); Toasty.error(getApplicationContext(),getString(R.string.toot_select_image_error),Toast.LENGTH_LONG).show();
} }
@ -957,9 +998,17 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
toot_content.setSelection(toot_content.getText().length()); toot_content.setSelection(toot_content.getText().length());
} }
}else if (requestCode == TAKE_PHOTO && resultCode == RESULT_OK) { }else if (requestCode == TAKE_PHOTO && resultCode == RESULT_OK) {
if( photo_editor) {
Intent intent = new Intent(TootActivity.this, PhotoEditorActivity.class);
Bundle b = new Bundle();
intent.putExtra("imageUri", photoFileUri.toString());
intent.putExtras(b);
startActivity(intent);
}else {
new asyncPicture(TootActivity.this, account, photoFileUri).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new asyncPicture(TootActivity.this, account, photoFileUri).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
} }
}
@Override @Override
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) { public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
@ -3065,7 +3114,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface,
int matchEnd = matcherALink.end(); int matchEnd = matcherALink.end();
final String url = content.substring(matcherALink.start(1), matcherALink.end(1)); final String url = content.substring(matcherALink.start(1), matcherALink.end(1));
if( matchEnd <= content.length() && matchEnd >= matchStart){ if( matchEnd <= content.length() && matchEnd >= matchStart){
content = content.replaceFirst(url,"abcdefghijklmnopkrstuvw"); content = content.replaceAll(Pattern.quote(url),"abcdefghijklmnopkrstuvw");
} }
} }
} }

View File

@ -819,7 +819,8 @@ public class API {
String response = httpsConnection.get(getAbsoluteUrl(String.format("/statuses/%s", statusId)), 60, null, prefKeyOauthTokenT); String response = httpsConnection.get(getAbsoluteUrl(String.format("/statuses/%s", statusId)), 60, null, prefKeyOauthTokenT);
Status status = parseStatuses(context, new JSONObject(response)); Status status = parseStatuses(context, new JSONObject(response));
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
new TimelineCacheDAO(context, db).update(status.getId(), response); Account account = new AccountDAO(context, db).getAccountByToken(prefKeyOauthTokenT);
new TimelineCacheDAO(context, db).update(status.getId(), response, account.getId(), account.getInstance());
statuses.add(status); statuses.add(status);
} catch (HttpsConnection.HttpsConnectionException e) { } catch (HttpsConnection.HttpsConnectionException e) {
setError(e.getStatusCode(), e); setError(e.getStatusCode(), e);
@ -1078,7 +1079,7 @@ public class API {
String response = httpsConnection.get(getAbsoluteUrl("/timelines/home"), 60, params, prefKeyOauthTokenT); String response = httpsConnection.get(getAbsoluteUrl("/timelines/home"), 60, params, prefKeyOauthTokenT);
apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setSince_id(httpsConnection.getSince_id());
apiResponse.setMax_id(httpsConnection.getMax_id()); apiResponse.setMax_id(httpsConnection.getMax_id());
statuses = parseStatuses(context, new JSONArray(response), true); statuses = parseStatusesForCache(context, new JSONArray(response));
} catch (HttpsConnection.HttpsConnectionException e) { } catch (HttpsConnection.HttpsConnectionException e) {
setError(e.getStatusCode(), e); setError(e.getStatusCode(), e);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
@ -2203,7 +2204,8 @@ public class API {
intentBC.putExtras(b); intentBC.putExtras(b);
LocalBroadcastManager.getInstance(context).sendBroadcast(intentBC); LocalBroadcastManager.getInstance(context).sendBroadcast(intentBC);
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
new TimelineCacheDAO(context, db).update(targetedId, resp); Account account = new AccountDAO(context, db).getAccountByToken(prefKeyOauthTokenT);
new TimelineCacheDAO(context, db).update(targetedId, resp, account.getId(), account.getInstance());
} }
} catch (HttpsConnection.HttpsConnectionException e) { } catch (HttpsConnection.HttpsConnectionException e) {
setError(e.getStatusCode(), e); setError(e.getStatusCode(), e);
@ -2366,8 +2368,9 @@ public class API {
intentBC.putExtras(b); intentBC.putExtras(b);
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
Status alreadyCached = new TimelineCacheDAO(context, db).getSingle(status.getId()); Status alreadyCached = new TimelineCacheDAO(context, db).getSingle(status.getId());
Account account = new AccountDAO(context, db).getAccountByToken(prefKeyOauthTokenT);
if (alreadyCached != null) { if (alreadyCached != null) {
new TimelineCacheDAO(context, db).update(status.getId(), response); new TimelineCacheDAO(context, db).update(status.getId(), response, account.getId(), account.getInstance());
} }
LocalBroadcastManager.getInstance(context).sendBroadcast(intentBC); LocalBroadcastManager.getInstance(context).sendBroadcast(intentBC);
return parsePoll(context, new JSONObject(response)); return parsePoll(context, new JSONObject(response));
@ -3856,7 +3859,7 @@ public class API {
* @param jsonArray JSONArray * @param jsonArray JSONArray
* @return List<Status> * @return List<Status>
*/ */
private static List<Status> parseStatuses(Context context, JSONArray jsonArray, boolean cached){ private List<Status> parseStatusesForCache(Context context, JSONArray jsonArray){
List<Status> statuses = new ArrayList<>(); List<Status> statuses = new ArrayList<>();
try { try {
@ -3865,12 +3868,11 @@ public class API {
JSONObject resobj = jsonArray.getJSONObject(i); JSONObject resobj = jsonArray.getJSONObject(i);
Status status = parseStatuses(context, resobj); Status status = parseStatuses(context, resobj);
if( cached) {
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
Status alreadyCached = new TimelineCacheDAO(context, db).getSingle(status.getId()); Status alreadyCached = new TimelineCacheDAO(context, db).getSingle(status.getId());
if (alreadyCached == null) { if (alreadyCached == null) {
new TimelineCacheDAO(context, db).insert(status.getId(), resobj.toString()); Account account = new AccountDAO(context, db).getAccountByToken(prefKeyOauthTokenT);
} new TimelineCacheDAO(context, db).insert(status.getId(), resobj.toString(), account.getId(), account.getInstance());
} }
i++; i++;
statuses.add(status); statuses.add(status);

View File

@ -1395,7 +1395,8 @@ public class GNUAPI {
intentBC.putExtras(b); intentBC.putExtras(b);
LocalBroadcastManager.getInstance(context).sendBroadcast(intentBC); LocalBroadcastManager.getInstance(context).sendBroadcast(intentBC);
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
new TimelineCacheDAO(context, db).update(targetedId, resp); Account account = new AccountDAO(context, db).getAccountByToken(prefKeyOauthTokenT);
new TimelineCacheDAO(context, db).update(targetedId, resp, account.getId(), account.getToken());
}else if( statusAction == API.StatusAction.UNSTATUS){ }else if( statusAction == API.StatusAction.UNSTATUS){
SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
new TimelineCacheDAO(context, db).remove(targetedId); new TimelineCacheDAO(context, db).remove(targetedId);

View File

@ -464,6 +464,20 @@ public class SettingsFragment extends Fragment {
} }
}); });
boolean photo_editor = sharedpreferences.getBoolean(Helper.SET_PHOTO_EDITOR, true);
final CheckBox set_photo_editor = rootView.findViewById(R.id.set_photo_editor);
set_photo_editor.setChecked(photo_editor);
set_photo_editor.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean(Helper.SET_PHOTO_EDITOR, set_photo_editor.isChecked());
editor.apply();
}
});
boolean remember_position_home = sharedpreferences.getBoolean(Helper.SET_REMEMBER_POSITION_HOME, true); boolean remember_position_home = sharedpreferences.getBoolean(Helper.SET_REMEMBER_POSITION_HOME, true);
final CheckBox set_remember_position = rootView.findViewById(R.id.set_remember_position); final CheckBox set_remember_position = rootView.findViewById(R.id.set_remember_position);
set_remember_position.setChecked(remember_position_home); set_remember_position.setChecked(remember_position_home);

View File

@ -384,6 +384,7 @@ public class Helper {
public static final String SET_NOTIF_SILENT = "set_notif_silent"; public static final String SET_NOTIF_SILENT = "set_notif_silent";
public static final String SET_EXPAND_CW = "set_expand_cw"; public static final String SET_EXPAND_CW = "set_expand_cw";
public static final String SET_EXPAND_MEDIA = "set_expand_media"; public static final String SET_EXPAND_MEDIA = "set_expand_media";
public static final String SET_PHOTO_EDITOR = "set_photo_editor";
public static final String SET_DISPLAY_FOLLOW_INSTANCE = "set_display_follow_instance"; public static final String SET_DISPLAY_FOLLOW_INSTANCE = "set_display_follow_instance";
public static final String SET_DISPLAY_NEW_BADGE = "set_display_new_badge"; public static final String SET_DISPLAY_NEW_BADGE = "set_display_new_badge";
public static final String SET_DISPLAY_BOT_ICON = "set_display_bot_icon"; public static final String SET_DISPLAY_BOT_ICON = "set_display_bot_icon";
@ -408,6 +409,7 @@ public class Helper {
public static final String EP_AUTHORIZE = "/oauth/authorize"; public static final String EP_AUTHORIZE = "/oauth/authorize";
//Proxy //Proxy
public static final String SET_PROXY_ENABLED = "set_proxy_enabled"; public static final String SET_PROXY_ENABLED = "set_proxy_enabled";
public static final String SET_PROXY_TYPE = "set_proxy_type"; public static final String SET_PROXY_TYPE = "set_proxy_type";
@ -427,6 +429,7 @@ public class Helper {
public static final String INTENT_ACTION = "intent_action"; public static final String INTENT_ACTION = "intent_action";
public static final String INTENT_TARGETED_ACCOUNT = "intent_targeted_account"; public static final String INTENT_TARGETED_ACCOUNT = "intent_targeted_account";
public static final String INTENT_BACKUP_FINISH = "intent_backup_finish"; public static final String INTENT_BACKUP_FINISH = "intent_backup_finish";
public static final String INTENT_SEND_MODIFIED_IMAGE = "intent_send_modified_image";
//Receiver //Receiver
public static final String RECEIVE_DATA = "receive_data"; public static final String RECEIVE_DATA = "receive_data";
public static final String RECEIVE_ACTION = "receive_action"; public static final String RECEIVE_ACTION = "receive_action";

View File

@ -0,0 +1,123 @@
package app.fedilab.android.imageeditor;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.android.R;
/**
* Created by Ahmed Adel on 5/8/17.
*/
public class ColorPickerAdapter extends RecyclerView.Adapter<ColorPickerAdapter.ViewHolder> {
private Context context;
private LayoutInflater inflater;
private List<Integer> colorPickerColors;
private OnColorPickerClickListener onColorPickerClickListener;
ColorPickerAdapter(@NonNull Context context, @NonNull List<Integer> colorPickerColors) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.colorPickerColors = colorPickerColors;
}
ColorPickerAdapter(@NonNull Context context) {
this(context, getDefaultColors(context));
this.context = context;
this.inflater = LayoutInflater.from(context);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.color_picker_item_list, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.colorPickerView.setBackgroundColor(colorPickerColors.get(position));
}
@Override
public int getItemCount() {
return colorPickerColors.size();
}
private void buildColorPickerView(View view, int colorCode) {
view.setVisibility(View.VISIBLE);
ShapeDrawable biggerCircle = new ShapeDrawable(new OvalShape());
biggerCircle.setIntrinsicHeight(20);
biggerCircle.setIntrinsicWidth(20);
biggerCircle.setBounds(new Rect(0, 0, 20, 20));
biggerCircle.getPaint().setColor(colorCode);
ShapeDrawable smallerCircle = new ShapeDrawable(new OvalShape());
smallerCircle.setIntrinsicHeight(5);
smallerCircle.setIntrinsicWidth(5);
smallerCircle.setBounds(new Rect(0, 0, 5, 5));
smallerCircle.getPaint().setColor(Color.WHITE);
smallerCircle.setPadding(10, 10, 10, 10);
Drawable[] drawables = {smallerCircle, biggerCircle};
LayerDrawable layerDrawable = new LayerDrawable(drawables);
view.setBackgroundDrawable(layerDrawable);
}
public void setOnColorPickerClickListener(OnColorPickerClickListener onColorPickerClickListener) {
this.onColorPickerClickListener = onColorPickerClickListener;
}
class ViewHolder extends RecyclerView.ViewHolder {
View colorPickerView;
public ViewHolder(View itemView) {
super(itemView);
colorPickerView = itemView.findViewById(R.id.color_picker_view);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onColorPickerClickListener != null)
onColorPickerClickListener.onColorPickerClickListener(colorPickerColors.get(getAdapterPosition()));
}
});
}
}
public interface OnColorPickerClickListener {
void onColorPickerClickListener(int colorCode);
}
public static List<Integer> getDefaultColors(Context context) {
ArrayList<Integer> colorPickerColors = new ArrayList<>();
colorPickerColors.add(ContextCompat.getColor(context, R.color.blue_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.brown_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.green_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.orange_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.red_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.black));
colorPickerColors.add(ContextCompat.getColor(context, R.color.red_orange_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.sky_blue_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.violet_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.white));
colorPickerColors.add(ContextCompat.getColor(context, R.color.yellow_color_picker));
colorPickerColors.add(ContextCompat.getColor(context, R.color.yellow_green_color_picker));
return colorPickerColors;
}
}

View File

@ -0,0 +1,116 @@
package app.fedilab.android.imageeditor;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.BottomSheetDialogFragment;
import android.support.design.widget.CoordinatorLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import app.fedilab.android.R;
import ja.burhanrashid52.photoeditor.PhotoEditor;
public class EmojiBSFragment extends BottomSheetDialogFragment {
public EmojiBSFragment() {
// Required empty public constructor
}
private EmojiListener mEmojiListener;
public interface EmojiListener {
void onEmojiClick(String emojiUnicode);
}
private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss();
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
};
@SuppressLint("RestrictedApi")
@Override
public void setupDialog(Dialog dialog, int style) {
super.setupDialog(dialog, style);
View contentView = View.inflate(getContext(), R.layout.fragment_bottom_sticker_emoji_dialog, null);
dialog.setContentView(contentView);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
CoordinatorLayout.Behavior behavior = params.getBehavior();
if (behavior instanceof BottomSheetBehavior) {
((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
}
((View) contentView.getParent()).setBackgroundColor(getResources().getColor(android.R.color.transparent));
RecyclerView rvEmoji = contentView.findViewById(R.id.rvEmoji);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 5);
rvEmoji.setLayoutManager(gridLayoutManager);
EmojiAdapter emojiAdapter = new EmojiAdapter();
rvEmoji.setAdapter(emojiAdapter);
}
public void setEmojiListener(EmojiListener emojiListener) {
mEmojiListener = emojiListener;
}
public class EmojiAdapter extends RecyclerView.Adapter<EmojiAdapter.ViewHolder> {
ArrayList<String> emojisList = PhotoEditor.getEmojis(getActivity());
@NotNull
@Override
public ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_emoji, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NotNull ViewHolder holder, int position) {
holder.txtEmoji.setText(emojisList.get(position));
}
@Override
public int getItemCount() {
return emojisList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView txtEmoji;
ViewHolder(View itemView) {
super(itemView);
txtEmoji = itemView.findViewById(R.id.txtEmoji);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mEmojiListener != null) {
mEmojiListener.onEmojiClick(emojisList.get(getLayoutPosition()));
}
dismiss();
}
});
}
}
}
}

View File

@ -0,0 +1,101 @@
package app.fedilab.android.imageeditor;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetDialogFragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import app.fedilab.android.R;
public class PropertiesBSFragment extends BottomSheetDialogFragment implements SeekBar.OnSeekBarChangeListener {
public PropertiesBSFragment() {
// Required empty public constructor
}
private Properties mProperties;
public interface Properties {
void onColorChanged(int colorCode);
void onOpacityChanged(int opacity);
void onBrushSizeChanged(int brushSize);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_bottom_properties_dialog, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
RecyclerView rvColor = view.findViewById(R.id.rvColors);
SeekBar sbOpacity = view.findViewById(R.id.sbOpacity);
SeekBar sbBrushSize = view.findViewById(R.id.sbSize);
sbOpacity.setOnSeekBarChangeListener(this);
sbBrushSize.setOnSeekBarChangeListener(this);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
rvColor.setLayoutManager(layoutManager);
rvColor.setHasFixedSize(true);
ColorPickerAdapter colorPickerAdapter = new ColorPickerAdapter(Objects.requireNonNull(getActivity()));
colorPickerAdapter.setOnColorPickerClickListener(new ColorPickerAdapter.OnColorPickerClickListener() {
@Override
public void onColorPickerClickListener(int colorCode) {
if (mProperties != null) {
dismiss();
mProperties.onColorChanged(colorCode);
}
}
});
rvColor.setAdapter(colorPickerAdapter);
}
public void setPropertiesChangeListener(Properties properties) {
mProperties = properties;
}
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
switch (seekBar.getId()) {
case R.id.sbOpacity:
if (mProperties != null) {
mProperties.onOpacityChanged(i);
}
break;
case R.id.sbSize:
if (mProperties != null) {
mProperties.onBrushSizeChanged(i);
}
break;
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}

View File

@ -0,0 +1,154 @@
package app.fedilab.android.imageeditor;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.BottomSheetDialogFragment;
import android.support.design.widget.CoordinatorLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import org.jetbrains.annotations.NotNull;
import app.fedilab.android.R;
public class StickerBSFragment extends BottomSheetDialogFragment {
public StickerBSFragment() {
// Required empty public constructor
}
private StickerListener mStickerListener;
public void setStickerListener(StickerListener stickerListener) {
mStickerListener = stickerListener;
}
public interface StickerListener {
void onStickerClick(Bitmap bitmap);
}
private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss();
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
};
@SuppressLint("RestrictedApi")
@Override
public void setupDialog(Dialog dialog, int style) {
super.setupDialog(dialog, style);
View contentView = View.inflate(getContext(), R.layout.fragment_bottom_sticker_emoji_dialog, null);
dialog.setContentView(contentView);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
CoordinatorLayout.Behavior behavior = params.getBehavior();
if (behavior instanceof BottomSheetBehavior) {
((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
}
((View) contentView.getParent()).setBackgroundColor(getResources().getColor(android.R.color.transparent));
RecyclerView rvEmoji = contentView.findViewById(R.id.rvEmoji);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
rvEmoji.setLayoutManager(gridLayoutManager);
StickerAdapter stickerAdapter = new StickerAdapter();
rvEmoji.setAdapter(stickerAdapter);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
public class StickerAdapter extends RecyclerView.Adapter<StickerAdapter.ViewHolder> {
int[] stickerList = new int[]{
R.drawable.bubble1,
R.drawable.cat1,
R.drawable.cat2,
R.drawable.cat3,
R.drawable.cat4,
R.drawable.cat5,
R.drawable.dog1,
R.drawable.dog2,
R.drawable.flower1,
R.drawable.flower2,
R.drawable.sun,
R.drawable.tux1,
};
@NotNull
@Override
public ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_sticker, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NotNull ViewHolder holder, int position) {
holder.imgSticker.setImageResource(stickerList[position]);
}
@Override
public int getItemCount() {
return stickerList.length;
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView imgSticker;
ViewHolder(View itemView) {
super(itemView);
imgSticker = itemView.findViewById(R.id.imgSticker);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mStickerListener != null) {
mStickerListener.onStickerClick(
BitmapFactory.decodeResource(getResources(),
stickerList[getLayoutPosition()]));
}
dismiss();
}
});
}
}
}
private String convertEmoji(String emoji) {
String returnedEmoji = "";
try {
int convertEmojiToInt = Integer.parseInt(emoji.substring(2), 16);
returnedEmoji = getEmojiByUnicode(convertEmojiToInt);
} catch (NumberFormatException e) {
returnedEmoji = "";
}
return returnedEmoji;
}
private String getEmojiByUnicode(int unicode) {
return new String(Character.toChars(unicode));
}
}

View File

@ -0,0 +1,132 @@
package app.fedilab.android.imageeditor;
import android.app.Dialog;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import org.jetbrains.annotations.NotNull;
import app.fedilab.android.R;
/**
* Created by Burhanuddin Rashid on 1/16/2018.
*/
public class TextEditorDialogFragment extends DialogFragment {
public static final String TAG = TextEditorDialogFragment.class.getSimpleName();
public static final String EXTRA_INPUT_TEXT = "extra_input_text";
public static final String EXTRA_COLOR_CODE = "extra_color_code";
private EditText mAddTextEditText;
private TextView mAddTextDoneTextView;
private InputMethodManager mInputMethodManager;
private int mColorCode;
private TextEditor mTextEditor;
public interface TextEditor {
void onDone(String inputText, int colorCode);
}
//Show dialog with provide text and text color
public static TextEditorDialogFragment show(@NonNull AppCompatActivity appCompatActivity,
@NonNull String inputText,
@ColorInt int colorCode) {
Bundle args = new Bundle();
args.putString(EXTRA_INPUT_TEXT, inputText);
args.putInt(EXTRA_COLOR_CODE, colorCode);
TextEditorDialogFragment fragment = new TextEditorDialogFragment();
fragment.setArguments(args);
fragment.show(appCompatActivity.getSupportFragmentManager(), TAG);
return fragment;
}
//Show dialog with default text input as empty and text color white
public static TextEditorDialogFragment show(@NonNull AppCompatActivity appCompatActivity) {
return show(appCompatActivity,
"", ContextCompat.getColor(appCompatActivity, R.color.white));
}
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
//Make dialog full screen with transparent background
if (dialog != null) {
int width = ViewGroup.LayoutParams.MATCH_PARENT;
int height = ViewGroup.LayoutParams.MATCH_PARENT;
dialog.getWindow().setLayout(width, height);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
}
}
@Nullable
@Override
public View onCreateView(@NotNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.add_text_dialog, container, false);
}
@Override
public void onViewCreated(@NotNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mAddTextEditText = view.findViewById(R.id.add_text_edit_text);
mInputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
mAddTextDoneTextView = view.findViewById(R.id.add_text_done_tv);
//Setup the color picker for text color
RecyclerView addTextColorPickerRecyclerView = view.findViewById(R.id.add_text_color_picker_recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
addTextColorPickerRecyclerView.setLayoutManager(layoutManager);
addTextColorPickerRecyclerView.setHasFixedSize(true);
ColorPickerAdapter colorPickerAdapter = new ColorPickerAdapter(getActivity());
//This listener will change the text color when clicked on any color from picker
colorPickerAdapter.setOnColorPickerClickListener(new ColorPickerAdapter.OnColorPickerClickListener() {
@Override
public void onColorPickerClickListener(int colorCode) {
mColorCode = colorCode;
mAddTextEditText.setTextColor(colorCode);
}
});
addTextColorPickerRecyclerView.setAdapter(colorPickerAdapter);
mAddTextEditText.setText(getArguments().getString(EXTRA_INPUT_TEXT));
mColorCode = getArguments().getInt(EXTRA_COLOR_CODE);
mAddTextEditText.setTextColor(mColorCode);
mInputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
//Make a callback on activity when user is done with text editing
mAddTextDoneTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mInputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
dismiss();
String inputText = mAddTextEditText.getText().toString();
if (!TextUtils.isEmpty(inputText) && mTextEditor != null) {
mTextEditor.onDone(inputText, mColorCode);
}
}
});
}
//Callback to listener if user is done with text editing
public void setOnTextEditorListener(TextEditor textEditor) {
mTextEditor = textEditor;
}
}

View File

@ -0,0 +1,7 @@
package app.fedilab.android.imageeditor.filters;
import ja.burhanrashid52.photoeditor.PhotoFilter;
public interface FilterListener {
void onFilterSelected(PhotoFilter photoFilter);
}

View File

@ -0,0 +1,115 @@
package app.fedilab.android.imageeditor.filters;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.android.R;
import ja.burhanrashid52.photoeditor.PhotoFilter;
/**
* @author <a href="https://github.com/burhanrashid52">Burhanuddin Rashid</a>
* @version 0.1.2
* @since 5/23/2018
*/
public class FilterViewAdapter extends RecyclerView.Adapter<FilterViewAdapter.ViewHolder> {
private FilterListener mFilterListener;
private List<Pair<String, PhotoFilter>> mPairList = new ArrayList<>();
public FilterViewAdapter(FilterListener filterListener) {
mFilterListener = filterListener;
setupFilters();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_filter_view, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Pair<String, PhotoFilter> filterPair = mPairList.get(position);
Bitmap fromAsset = getBitmapFromAsset(holder.itemView.getContext(), filterPair.first);
holder.mImageFilterView.setImageBitmap(fromAsset);
holder.mTxtFilterName.setText(filterPair.second.name().replace("_", " "));
}
@Override
public int getItemCount() {
return mPairList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView mImageFilterView;
TextView mTxtFilterName;
ViewHolder(View itemView) {
super(itemView);
mImageFilterView = itemView.findViewById(R.id.imgFilterView);
mTxtFilterName = itemView.findViewById(R.id.txtFilterName);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mFilterListener.onFilterSelected(mPairList.get(getLayoutPosition()).second);
}
});
}
}
private Bitmap getBitmapFromAsset(Context context, String strName) {
AssetManager assetManager = context.getAssets();
InputStream istr = null;
try {
istr = assetManager.open(strName);
return BitmapFactory.decodeStream(istr);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private void setupFilters() {
mPairList.add(new Pair<>("filters/original.jpg", PhotoFilter.NONE));
mPairList.add(new Pair<>("filters/auto_fix.png", PhotoFilter.AUTO_FIX));
mPairList.add(new Pair<>("filters/brightness.png", PhotoFilter.BRIGHTNESS));
mPairList.add(new Pair<>("filters/contrast.png", PhotoFilter.CONTRAST));
mPairList.add(new Pair<>("filters/documentary.png", PhotoFilter.DOCUMENTARY));
mPairList.add(new Pair<>("filters/dual_tone.png", PhotoFilter.DUE_TONE));
mPairList.add(new Pair<>("filters/fill_light.png", PhotoFilter.FILL_LIGHT));
mPairList.add(new Pair<>("filters/fish_eye.png", PhotoFilter.FISH_EYE));
mPairList.add(new Pair<>("filters/grain.png", PhotoFilter.GRAIN));
mPairList.add(new Pair<>("filters/gray_scale.png", PhotoFilter.GRAY_SCALE));
mPairList.add(new Pair<>("filters/lomish.png", PhotoFilter.LOMISH));
mPairList.add(new Pair<>("filters/negative.png", PhotoFilter.NEGATIVE));
mPairList.add(new Pair<>("filters/posterize.png", PhotoFilter.POSTERIZE));
mPairList.add(new Pair<>("filters/saturate.png", PhotoFilter.SATURATE));
mPairList.add(new Pair<>("filters/sepia.png", PhotoFilter.SEPIA));
mPairList.add(new Pair<>("filters/sharpen.png", PhotoFilter.SHARPEN));
mPairList.add(new Pair<>("filters/temprature.png", PhotoFilter.TEMPERATURE));
mPairList.add(new Pair<>("filters/tint.png", PhotoFilter.TINT));
mPairList.add(new Pair<>("filters/vignette.png", PhotoFilter.VIGNETTE));
mPairList.add(new Pair<>("filters/cross_process.png", PhotoFilter.CROSS_PROCESS));
mPairList.add(new Pair<>("filters/b_n_w.png", PhotoFilter.BLACK_WHITE));
mPairList.add(new Pair<>("filters/flip_horizental.png", PhotoFilter.FLIP_HORIZONTAL));
mPairList.add(new Pair<>("filters/flip_vertical.png", PhotoFilter.FLIP_VERTICAL));
mPairList.add(new Pair<>("filters/rotate.png", PhotoFilter.ROTATE));
}
}

View File

@ -0,0 +1,91 @@
package app.fedilab.android.imageeditor.tools;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.android.R;
/**
* @author <a href="https://github.com/burhanrashid52">Burhanuddin Rashid</a>
* @version 0.1.2
* @since 5/23/2018
*/
public class EditingToolsAdapter extends RecyclerView.Adapter<EditingToolsAdapter.ViewHolder> {
private List<ToolModel> mToolList = new ArrayList<>();
private OnItemSelected mOnItemSelected;
public EditingToolsAdapter(OnItemSelected onItemSelected) {
mOnItemSelected = onItemSelected;
mToolList.add(new ToolModel("Brush", R.drawable.ic_brush_edit, ToolType.BRUSH));
mToolList.add(new ToolModel("Text", R.drawable.ic_text, ToolType.TEXT));
// mToolList.add(new ToolModel("Eraser", R.drawable.ic_eraser, ToolType.ERASER));
mToolList.add(new ToolModel("Filter", R.drawable.ic_photo_filter, ToolType.FILTER));
mToolList.add(new ToolModel("Crop", R.drawable.ic_crop, ToolType.CROP));
mToolList.add(new ToolModel("Emoji", R.drawable.ic_insert_emoticon_media, ToolType.EMOJI));
mToolList.add(new ToolModel("Sticker", R.drawable.ic_sticker, ToolType.STICKER));
}
public interface OnItemSelected {
void onToolSelected(ToolType toolType);
}
class ToolModel {
private String mToolName;
private int mToolIcon;
private ToolType mToolType;
ToolModel(String toolName, int toolIcon, ToolType toolType) {
mToolName = toolName;
mToolIcon = toolIcon;
mToolType = toolType;
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_editing_tools, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
ToolModel item = mToolList.get(position);
holder.txtTool.setText(item.mToolName);
holder.imgToolIcon.setImageResource(item.mToolIcon);
}
@Override
public int getItemCount() {
return mToolList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView imgToolIcon;
TextView txtTool;
ViewHolder(View itemView) {
super(itemView);
imgToolIcon = itemView.findViewById(R.id.imgToolIcon);
txtTool = itemView.findViewById(R.id.txtTool);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnItemSelected.onToolSelected(mToolList.get(getLayoutPosition()).mToolType);
}
});
}
}
}

View File

@ -0,0 +1,16 @@
package app.fedilab.android.imageeditor.tools;
/**
* @author <a href="https://github.com/burhanrashid52">Burhanuddin Rashid</a>
* @version 0.1.2
* @since 5/23/2018
*/
public enum ToolType {
BRUSH,
TEXT,
ERASER,
FILTER,
EMOJI,
STICKER,
CROP
}

View File

@ -53,10 +53,7 @@ public class TimelineCacheDAO {
* Insert a status in database * Insert a status in database
* @return boolean * @return boolean
*/ */
public long insert(String statusId, String jsonString) { public long insert(String statusId, String jsonString, String userId, String instance) {
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
String instance = Helper.getLiveInstance(context);
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(Sqlite.COL_INSTANCE, instance); values.put(Sqlite.COL_INSTANCE, instance);
values.put(Sqlite.COL_STATUS_ID, statusId); values.put(Sqlite.COL_STATUS_ID, statusId);
@ -78,10 +75,7 @@ public class TimelineCacheDAO {
/** /**
* Update a status in database * Update a status in database
*/ */
public void update(String statusId, String jsonString) { public void update(String statusId, String jsonString, String userId, String instance) {
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
String instance = Helper.getLiveInstance(context);
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(Sqlite.COL_DATE, Helper.dateToString(new Date())); values.put(Sqlite.COL_DATE, Helper.dateToString(new Date()));
values.put(Sqlite.COL_CACHE, jsonString); values.put(Sqlite.COL_CACHE, jsonString);

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M7,14c-1.66,0 -3,1.34 -3,3 0,1.31 -1.16,2 -2,2 0.92,1.22 2.49,2 4,2 2.21,0 4,-1.79 4,-4 0,-1.66 -1.34,-3 -3,-3zM20.71,4.63l-1.34,-1.34c-0.39,-0.39 -1.02,-0.39 -1.41,0L9,12.25 11.75,15l8.96,-8.96c0.39,-0.39 0.39,-1.02 0,-1.41z"/>
</vector>

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
<path
android:fillColor="#606984"
android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M17,15h2V7c0,-1.1 -0.9,-2 -2,-2H9v2h8v8zM7,17V1H5v4H1v2h4v10c0,1.1 0.9,2 2,2h10v4h2v-4h4v-2H7z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM15.5,11c0.83,0 1.5,-0.67 1.5,-1.5S16.33,8 15.5,8 14,8.67 14,9.5s0.67,1.5 1.5,1.5zM8.5,11c0.83,0 1.5,-0.67 1.5,-1.5S9.33,8 8.5,8 7,8.67 7,9.5 7.67,11 8.5,11zM12,17.5c2.33,0 4.31,-1.46 5.11,-3.5L6.89,14c0.8,2.04 2.78,3.5 5.11,3.5z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M19.02,10v9L5,19L5,5h9L14,3L5.02,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2v-9h-2zM17,10l0.94,-2.06L20,7l-2.06,-0.94L17,4l-0.94,2.06L14,7l2.06,0.94zM13.25,10.75L12,8l-1.25,2.75L8,12l2.75,1.25L12,16l1.25,-2.75L16,12z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M18.4,10.6C16.55,8.99 14.15,8 11.5,8c-4.65,0 -8.58,3.03 -9.96,7.22L3.9,16c1.05,-3.19 4.05,-5.5 7.6,-5.5 1.95,0 3.73,0.72 5.12,1.88L13,16h9V7l-3.6,3.6z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M17.63,5.84C17.27,5.33 16.67,5 16,5L5,5.01C3.9,5.01 3,5.9 3,7v10c0,1.1 0.9,1.99 2,1.99L16,19c0.67,0 1.27,-0.33 1.63,-0.84L22,12l-4.37,-6.16z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M2.5,4v3h5v12h3L10.5,7h5L15.5,4h-13zM21.5,9h-9v3h3v7h3v-7h3L21.5,9z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#606984"
android:pathData="M12.5,8c-2.65,0 -5.05,0.99 -6.9,2.6L2,7v9h9l-3.62,-3.62c1.39,-1.16 3.16,-1.88 5.12,-1.88 3.54,0 6.55,2.31 7.6,5.5l2.37,-0.78C21.08,11.03 17.15,8 12.5,8z"/>
</vector>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="2dp"
android:color="#FFFFFF" />
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<corners android:radius="50dp" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -432,12 +432,21 @@
android:text="@string/set_forward_tags" android:text="@string/set_forward_tags"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<EditText <EditText
android:hint="@string/settings_custom_sharing_url" android:hint="@string/settings_custom_sharing_url"
android:id="@+id/custom_sharing_url" android:id="@+id/custom_sharing_url"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/set_photo_editor"
android:layout_width="wrap_content"
android:layout_marginTop="@dimen/settings_checkbox_margin"
android:layout_marginBottom="@dimen/settings_checkbox_margin"
android:text="@string/set_photo_editor"
android:layout_height="wrap_content" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 Thomas Schneider
This file is a part of Fedilab
This program 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.
Fedilab 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 Fedilab; if not,
see <http://www.gnu.org/licenses>.
-->
<android.support.constraint.ConstraintLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_end="?attr/actionBarSize" />
<ja.burhanrashid52.photoeditor.PhotoEditorView
android:id="@+id/photoEditorView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<ImageView
android:id="@+id/imgUndo"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:src="@drawable/ic_undo"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintEnd_toStartOf="@+id/imgRedo"
android:contentDescription="@string/undo" />
<ImageView
android:id="@+id/imgRedo"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:src="@drawable/ic_redo"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintEnd_toEndOf="parent"
android:contentDescription="@string/redo" />
<ImageView
android:id="@+id/imgGallery"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:src="@drawable/ic_gallery"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintStart_toStartOf="parent"
android:contentDescription="@string/gallery"/>
<ImageView
android:id="@+id/imgCamera"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:src="@drawable/ic_camera"
app:layout_constraintBottom_toTopOf="@+id/rvConstraintTools"
app:layout_constraintStart_toEndOf="@id/imgGallery"
android:contentDescription="@string/camera"
/>
<ImageView
android:id="@+id/imgClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_margin="8dp"
android:src="@drawable/ic_close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:contentDescription="@string/close"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rvConstraintTools"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="4dp"
android:paddingTop="4dp"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:listitem="@layout/row_editing_tools" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rvFilterView"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="@+id/rvConstraintTools"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/rvConstraintTools"
tools:listitem="@layout/row_filter_view" />
<TextView
android:id="@+id/txtCurrentTool"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:singleLine="true"
android:text="@string/app_name"
android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
<Button
android:id="@+id/send"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:layout_gravity="end"
android:gravity="center"
android:padding="0dp"
android:layout_margin="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imgSave"
app:layout_constraintTop_toBottomOf="@+id/guideline"
android:text="@string/validate" />
<ImageView
android:id="@+id/imgSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:src="@drawable/ic_save_gallery"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:contentDescription="@string/save"
app:layout_constraintTop_toBottomOf="@+id/guideline" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:background="#B3000000"
android:orientation="vertical">
<TextView
android:id="@+id/add_text_done_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_margin="20dp"
android:background="@drawable/rounded_border_text_view"
android:padding="10dp"
android:text="@string/done"
android:textAllCaps="false"
android:textColor="@color/white"
android:textSize="15sp" />
<EditText
android:id="@+id/add_text_edit_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/add_text_color_picker_relative_layout"
android:layout_below="@+id/add_text_done_tv"
android:background="@null"
android:gravity="center"
android:inputType="textMultiLine"
android:textSize="40sp" />
<RelativeLayout
android:id="@+id/add_text_color_picker_relative_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<android.support.v7.widget.RecyclerView
android:id="@+id/add_text_color_picker_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:background="@android:color/black"
tools:listitem="@layout/color_picker_item_list" />
</RelativeLayout>
</RelativeLayout>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<View
android:id="@+id/color_picker_view"
android:layout_width="40dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:background="@android:color/white"
tools:text="" />
</RelativeLayout>

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:background="@android:color/black"
android:orientation="vertical">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvColors"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="32dp"
android:orientation="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sbOpacity"
tools:listitem="@layout/color_picker_item_list"
android:layout_alignParentRight="true" />
<SeekBar
android:id="@+id/sbOpacity"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:progress="100"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtOpacity" />
<TextView
android:id="@+id/txtOpacity"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="32dp"
android:text="@string/opacity"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sbSize" />
<SeekBar
android:id="@+id/sbSize"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:progress="25"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtBrushSize" />
<TextView
android:id="@+id/txtBrushSize"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/label_brush"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</LinearLayout>

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:background="@android:color/transparent"
android:orientation="vertical">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp">
<TextView
android:id="@+id/txtClose"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:layout_marginStart="8dp"
android:gravity="center"
android:text="@string/close"
android:textAppearance="@style/TextAppearance.AppCompat.Large.Inverse"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="8dp" />
<View
android:id="@+id/lineView"
android:layout_width="match_parent"
android:layout_height="2px"
android:background="@android:color/white"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/txtClose"
tools:ignore="PxUsage" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rvEmoji"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_behavior="@string/bottom_sheet_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/lineView" />
<TextView
android:id="@+id/txtDone"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:layout_marginEnd="8dp"
android:gravity="center"
android:text="@string/done"
android:textAppearance="@style/TextAppearance.AppCompat.Large.Inverse"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginRight="8dp" />
</android.support.constraint.ConstraintLayout>
</LinearLayout>

View File

@ -443,6 +443,15 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/set_photo_editor"
android:layout_width="wrap_content"
android:layout_marginTop="@dimen/settings_checkbox_margin"
android:layout_marginBottom="@dimen/settings_checkbox_margin"
android:text="@string/set_photo_editor"
android:layout_height="wrap_content" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 Thomas Schneider
This file is a part of Fedilab
This program 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.
Fedilab 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 Fedilab; if not,
see <http://www.gnu.org/licenses>.
-->
<ja.burhanrashid52.photoeditor.PhotoEditorView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/photoEditorView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="4dp"
tools:background="@android:color/black">
<ImageView
android:id="@+id/imgToolIcon"
android:layout_width="@dimen/editor_size"
android:layout_height="@dimen/editor_size"
android:layout_margin="4dp"
android:layout_marginBottom="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:src="@drawable/ic_brush_edit"
android:contentDescription="@string/label_brush" />
<TextView
android:id="@+id/txtTool"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@android:color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imgToolIcon"
tools:text="@string/label_brush" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txtEmoji"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:padding="2dp"
android:textColor="#FFFFFF"
android:textSize="35sp"
tools:android="Burhanuddin" />
</LinearLayout>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="wrap_content"
android:layout_height="match_parent"
android:layout_margin="2dp">
<ImageView
android:id="@+id/imgFilterView"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@tools:sample/backgrounds/scenic" />
<TextView
android:id="@+id/txtFilterName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#606984"
android:gravity="center"
android:padding="4dp"
android:textColor="@android:color/white"
android:textSize="8sp"
app:layout_constraintBottom_toBottomOf="@+id/imgFilterView"
app:layout_constraintEnd_toEndOf="@+id/imgFilterView"
app:layout_constraintStart_toStartOf="@+id/imgFilterView"
tools:text="@tools:sample/full_names" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp">
<ImageView
android:id="@+id/imgSticker"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

View File

@ -856,6 +856,24 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d vote</item> <item quantity="one">%d vote</item>
<item quantity="other">%d votes</item> <item quantity="other">%d votes</item>

View File

@ -858,7 +858,7 @@
<string name="set_blur_sensitive">تعتيم الوسائط الحساسة</string> <string name="set_blur_sensitive">تعتيم الوسائط الحساسة</string>
<string name="set_display_timeline_in_list">عرض الخيوط الزمنية في قائمة</string> <string name="set_display_timeline_in_list">عرض الخيوط الزمنية في قائمة</string>
<string name="display_timeline">عرض الخيوط الزمنية</string> <string name="display_timeline">عرض الخيوط الزمنية</string>
<string name="set_display_bot_icon">Mark bot accounts in toots</string> <string name="set_display_bot_icon">ضع إشارة على حسابات الروبوتات في التبويقات</string>
<string name="add_tags">إدارة الوسوم</string> <string name="add_tags">إدارة الوسوم</string>
<string name="set_remember_position">تذكّر وضعيتي على الخيط الرئيسي</string> <string name="set_remember_position">تذكّر وضعيتي على الخيط الرئيسي</string>
<string name="history">التاريخ</string> <string name="history">التاريخ</string>
@ -871,6 +871,24 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">إنشاء قائمة تشغيل</string> <string name="action_playlist_create">إنشاء قائمة تشغيل</string>
<string name="action_playlist_empty_content">قائمة التشغيل هذه فارغة حاليا.</string> <string name="action_playlist_empty_content">قائمة التشغيل هذه فارغة حاليا.</string>
<string name="edit_media">تحرير الوسائط</string>
<string name="redo">إعادة</string>
<string name="gallery">المعرض</string>
<string name="label_emoji">إيموجي</string>
<string name="label_sticker">ملصق</string>
<string name="label_eraser">مِمْحاة</string>
<string name="label_text">نص</string>
<string name="label_filter">فلتر</string>
<string name="label_adjust">ضبط</string>
<string name="label_brush">فرشاة</string>
<string name="confirm_exit_editing">هل أنت متأكد من الخروج دون حفظ الصورة؟</string>
<string name="discard">تجاهل</string>
<string name="saving">جاري الحفظ…</string>
<string name="image_saved">تم حفظ الصورة بنجاح!</string>
<string name="save_image_failed">فشل في حفظ الصورة</string>
<string name="opacity">الشفافيّة</string>
<string name="label_crop">اقتصاص</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="zero">لا صوت</item> <item quantity="zero">لا صوت</item>
<item quantity="one">صوت واحد</item> <item quantity="one">صوت واحد</item>

View File

@ -838,16 +838,34 @@ Quan s\'esborra l\'aplicació s\'eliminen les dades immediatament.\n
<string name="set_display_bot_icon">Marcar els brams fets per bots</string> <string name="set_display_bot_icon">Marcar els brams fets per bots</string>
<string name="add_tags">Gestionar etiquetes</string> <string name="add_tags">Gestionar etiquetes</string>
<string name="set_remember_position">Recordar la posició en la pissarra principal</string> <string name="set_remember_position">Recordar la posició en la pissarra principal</string>
<string name="history">History</string> <string name="history">Historial</string>
<string name="playlists">Playlists</string> <string name="playlists">Llistes de reproducció</string>
<string name="display_name">Display name</string> <string name="display_name">Nom que es mostrarà</string>
<string name="privacy">Privacy</string> <string name="privacy">Privacitat</string>
<string name="create">Create</string> <string name="create">Crea</string>
<string name="action_playlist_add">You don\'t have any playlists. Click on the \"+\" icon to add a new playlist</string> <string name="action_playlist_add">No tens llistes de reproducció. Clica la icona \"+\" per afegir-ne de noves</string>
<string name="error_display_name">You must provide a display name!</string> <string name="error_display_name">Cal que et mostris amb algun nom!</string>
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">Aquest canal és obligat quan la llista és pública.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Crea una llista de reproducció</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">La llista encara és buida.</string>
<string name="edit_media">Editar document multimèdia</string>
<string name="redo">tornar-hi</string>
<string name="gallery">Galeria</string>
<string name="label_emoji">Emoticones</string>
<string name="label_sticker">Enganxina</string>
<string name="label_eraser">Goma d\'esborrar</string>
<string name="label_text">Text</string>
<string name="label_filter">Filtre</string>
<string name="label_adjust">Ajustar</string>
<string name="label_brush">Pinzell</string>
<string name="confirm_exit_editing">Esteu segur per sortir sense desar la imatge?</string>
<string name="discard">Descarta</string>
<string name="saving">Desant…</string>
<string name="image_saved">Imatge desada amb èxit!</string>
<string name="save_image_failed">No s\'ha pogut desar la imatge</string>
<string name="opacity">Opacitat</string>
<string name="label_crop">Retalla</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d vot</item> <item quantity="one">%d vot</item>
<item quantity="other">%d vots</item> <item quantity="other">%d vots</item>

View File

@ -861,6 +861,24 @@ Uživatelské jméno a heslo nejsou nikdy ukládány. Jsou použity pouze během
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d hlas</item> <item quantity="one">%d hlas</item>
<item quantity="few">%d hlasy</item> <item quantity="few">%d hlasy</item>

View File

@ -871,6 +871,24 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="zero">%d votes</item> <item quantity="zero">%d votes</item>
<item quantity="one">%d vote</item> <item quantity="one">%d vote</item>

View File

@ -856,6 +856,24 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d vote</item> <item quantity="one">%d vote</item>
<item quantity="other">%d votes</item> <item quantity="other">%d votes</item>

View File

@ -836,17 +836,35 @@ Sobald Sie die ersten Buchstaben eintippen, werden Namensvorschläge angezeigt\n
<string name="display_timeline">Zeitleisten anzeigen</string> <string name="display_timeline">Zeitleisten anzeigen</string>
<string name="set_display_bot_icon">Toots von Bot-Konten kennzeichnen</string> <string name="set_display_bot_icon">Toots von Bot-Konten kennzeichnen</string>
<string name="add_tags">Schlagwörter verwalten</string> <string name="add_tags">Schlagwörter verwalten</string>
<string name="set_remember_position">Position der Startseiten-Zeitleiste merken</string> <string name="set_remember_position">Position innerhalb der Startleiste merken</string>
<string name="history">Verlauf</string> <string name="history">Verlauf</string>
<string name="playlists">Wiedergabelisten</string> <string name="playlists">Wiedergabelisten</string>
<string name="display_name">Anzeigenamen</string> <string name="display_name">Anzeigename</string>
<string name="privacy">Datenschutz</string> <string name="privacy">Datenschutz</string>
<string name="create">Erstellen</string> <string name="create">Erstellen</string>
<string name="action_playlist_add">Sie haben noch keine Wiedergabelisten. Klicken Sie auf das Symbol „➕”, um eine neue Wiedergabeliste hinzuzufügen.</string> <string name="action_playlist_add">Sie haben noch keine Wiedergabelisten. Klicken Sie auf das Symbol „➕”, um eine neue Wiedergabeliste hinzuzufügen.</string>
<string name="error_display_name">Sie müssen einen Anzeigenamen angeben!</string> <string name="error_display_name">Sie müssen einen Anzeigenamen angeben!</string>
<string name="error_channel_mandatory">Der Kanal wird benötigt, wenn es sich um eine öffentliche Wiedergabeliste handelt.</string> <string name="error_channel_mandatory">Ein Kanal wird benötigt, wenn es sich um eine öffentliche Wiedergabeliste handelt.</string>
<string name="action_playlist_create">Wiedergabeliste erstellen</string> <string name="action_playlist_create">Wiedergabeliste erstellen</string>
<string name="action_playlist_empty_content">Diese Wiedergabeliste ist leer.</string> <string name="action_playlist_empty_content">Diese Wiedergabeliste ist leer.</string>
<string name="edit_media">Medien bearbeiten</string>
<string name="redo">Wiederherstellen</string>
<string name="gallery">Galerie</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Radierer</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Anpassen</string>
<string name="label_brush">Pinsel</string>
<string name="confirm_exit_editing">Möchten Sie die Grafik wirklich verlassen, ohne sie zu speichern?</string>
<string name="discard">Verwerfen</string>
<string name="saving">Speichern …</string>
<string name="image_saved">Grafik erfolgreich gespeichert!</string>
<string name="save_image_failed">Grafik konnte nicht gespeichert werden</string>
<string name="opacity">Deckkraft</string>
<string name="label_crop">Zuschneiden</string>
<string name="set_photo_editor">Fotobearbeitung aktivieren</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d Stimme</item> <item quantity="one">%d Stimme</item>
<item quantity="other">%d Stimmen</item> <item quantity="other">%d Stimmen</item>

View File

@ -856,6 +856,24 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d vote</item> <item quantity="one">%d vote</item>
<item quantity="other">%d ψήφοι</item> <item quantity="other">%d ψήφοι</item>

View File

@ -850,6 +850,24 @@ https://yandex.ru/legal/confidential/?lang=en </string>
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d vote</item> <item quantity="one">%d vote</item>
<item quantity="other">%d votes</item> <item quantity="other">%d votes</item>

View File

@ -844,17 +844,35 @@
<string name="display_timeline">Bistaratu denbora-lerroak</string> <string name="display_timeline">Bistaratu denbora-lerroak</string>
<string name="set_display_bot_icon">Markatu bot kontuak toot-etan</string> <string name="set_display_bot_icon">Markatu bot kontuak toot-etan</string>
<string name="add_tags">Kudeatu etiketak</string> <string name="add_tags">Kudeatu etiketak</string>
<string name="set_remember_position">Remember the position in Home timeline</string> <string name="set_remember_position">Gogoratu posizioa hasiera debora-lerroan</string>
<string name="history">History</string> <string name="history">Historiala</string>
<string name="playlists">Playlists</string> <string name="playlists">Erreprodukzio-zerrendak</string>
<string name="display_name">Display name</string> <string name="display_name">Pantaila-izena</string>
<string name="privacy">Privacy</string> <string name="privacy">Pribatutasuna</string>
<string name="create">Create</string> <string name="create">Sortu</string>
<string name="action_playlist_add">You don\'t have any playlists. Click on the \"+\" icon to add a new playlist</string> <string name="action_playlist_add">Ez duzu erreprodukzio-zerrendarik. Sakatu \'+\' ikonoa erreprodukzio-zerrenda berria gehitzeko</string>
<string name="error_display_name">You must provide a display name!</string> <string name="error_display_name">Pantaila-izen bat eman behar duzu!</string>
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">Kanala beharrezkoa da erreprodukzio-zerrenda publikoa bada.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Sortu erreprodukzio-zerrenda</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">Ez dago ezer erreprodukzio-zerrenda honetan oraindik.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">boto %d</item> <item quantity="one">boto %d</item>
<item quantity="other">%d boto</item> <item quantity="other">%d boto</item>

View File

@ -856,6 +856,24 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d vote</item> <item quantity="one">%d vote</item>
<item quantity="other">%d votes</item> <item quantity="other">%d votes</item>

View File

@ -856,6 +856,24 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d vote</item> <item quantity="one">%d vote</item>
<item quantity="other">%d votes</item> <item quantity="other">%d votes</item>

View File

@ -853,6 +853,24 @@ Le bouton de connexion sactivera une fois quun domaine valide sera renseig
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Galerie</string>
<string name="label_emoji">Émoji</string>
<string name="label_sticker">Autocollant</string>
<string name="label_eraser">Gomme</string>
<string name="label_text">Texte</string>
<string name="label_filter">Filtre</string>
<string name="label_adjust">Ajuster</string>
<string name="label_brush">Pinceau</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Annuler</string>
<string name="saving">Enregistrement …</string>
<string name="image_saved">Image enregistrée avec succès !</string>
<string name="save_image_failed">Échec de l\'enregistrement de l\'image</string>
<string name="opacity">Transparence</string>
<string name="label_crop">Rogner</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d voix</item> <item quantity="one">%d voix</item>
<item quantity="other">%d voix</item> <item quantity="other">%d voix</item>

View File

@ -857,6 +857,24 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d voto</item> <item quantity="one">%d voto</item>
<item quantity="other">%d votos</item> <item quantity="other">%d votos</item>

View File

@ -864,6 +864,24 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d vote</item> <item quantity="one">%d vote</item>
<item quantity="two">%d votes</item> <item quantity="two">%d votes</item>

View File

@ -846,6 +846,24 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d vote</item> <item quantity="one">%d vote</item>
<item quantity="other">%d votes</item> <item quantity="other">%d votes</item>

View File

@ -696,7 +696,7 @@ A Yandexnek megvan a saját adatvédelmi szabályzata, ami itt található: http
<string name="some_words_any">Bármelyik a következő szavakból (szóközzel elválasztva)</string> <string name="some_words_any">Bármelyik a következő szavakból (szóközzel elválasztva)</string>
<string name="some_words_all">Minden szó (szóközzel elválasztva)</string> <string name="some_words_all">Minden szó (szóközzel elválasztva)</string>
<string name="some_words_none">Egyik szó sem (szóközzel elválasztva)</string> <string name="some_words_none">Egyik szó sem (szóközzel elválasztva)</string>
<string name="some_tags">Add some words to filter (space-separated)</string> <string name="some_tags">Néhány szűrő szó hozzáadása (szóközzel elválasztva)</string>
<string name="change_tag_column">Oszlop nevének megváltoztatása</string> <string name="change_tag_column">Oszlop nevének megváltoztatása</string>
<string name="no_misskey_instance">Nincs Misskey szerver</string> <string name="no_misskey_instance">Nincs Misskey szerver</string>
<string name="misskey_instance">Misskey szerver</string> <string name="misskey_instance">Misskey szerver</string>
@ -835,25 +835,43 @@ A Yandexnek megvan a saját adatvédelmi szabályzata, ami itt található: http
<string name="add_timeline">Idővonal hozzáadása</string> <string name="add_timeline">Idővonal hozzáadása</string>
<string name="set_sensitive_content">Minden médiát jelölj meg érzékenynek</string> <string name="set_sensitive_content">Minden médiát jelölj meg érzékenynek</string>
<string name="gnu_instance">GNU szerver</string> <string name="gnu_instance">GNU szerver</string>
<string name="cached_status">Cached status</string> <string name="cached_status">Gyorsítótárazott üzenet</string>
<string name="set_forward_tags">Címkék továbbítasa a válaszokban</string> <string name="set_forward_tags">Címkék továbbítasa a válaszokban</string>
<string name="set_long_press_media">Nyomd meg hosszan a média tárolásához</string> <string name="set_long_press_media">Nyomd meg hosszan a média tárolásához</string>
<string name="set_blur_sensitive">Érzékeny média homályosítása</string> <string name="set_blur_sensitive">Érzékeny média homályosítása</string>
<string name="set_display_timeline_in_list">Idővonalak megjelenítése listában</string> <string name="set_display_timeline_in_list">Idővonalak megjelenítése listában</string>
<string name="display_timeline">Idővonalak megjelenítése</string> <string name="display_timeline">Idővonalak megjelenítése</string>
<string name="set_display_bot_icon">Mark bot accounts in toots</string> <string name="set_display_bot_icon">Bot-fiókok megjelölése a tootokban</string>
<string name="add_tags">Manage tags</string> <string name="add_tags">Címkék kezelése</string>
<string name="set_remember_position">Remember the position in Home timeline</string> <string name="set_remember_position">Remember the position in Home timeline</string>
<string name="history">History</string> <string name="history">Előzmények</string>
<string name="playlists">Playlists</string> <string name="playlists">Lejátszási listák</string>
<string name="display_name">Display name</string> <string name="display_name">Megjelenítendő név</string>
<string name="privacy">Privacy</string> <string name="privacy">Adatvédelem</string>
<string name="create">Create</string> <string name="create">Létrehoz</string>
<string name="action_playlist_add">You don\'t have any playlists. Click on the \"+\" icon to add a new playlist</string> <string name="action_playlist_add">Nincs még lejátszási listád. Klikkelj a \'+\' jelre új lejátszási lista hozzáadásához</string>
<string name="error_display_name">You must provide a display name!</string> <string name="error_display_name">Meg kell adnod egy megjelenítési nevet!</string>
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">Csatorna kiválasztása szükséges, ha a lejátszási lista nyilvános.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Lejátszási lista létrehozása</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">Ez a lejátszási list még üres.</string>
<string name="edit_media">Média szerkesztése</string>
<string name="redo">Ismétlés</string>
<string name="gallery">Galéria</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Matrica</string>
<string name="label_eraser">Radír</string>
<string name="label_text">Szöveg</string>
<string name="label_filter">Szűrő</string>
<string name="label_adjust">Beállítás</string>
<string name="label_brush">Ecset</string>
<string name="confirm_exit_editing">Biztos, hogy a kép mentése nélkül kilép?</string>
<string name="discard">Elvet</string>
<string name="saving">Mentés folyamatban…</string>
<string name="image_saved">A kép sikeresen elmentve!</string>
<string name="save_image_failed">Nem sikerült elmenteni a képet</string>
<string name="opacity">Áttetszőség</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d szavazat</item> <item quantity="one">%d szavazat</item>
<item quantity="other">%d szavazat</item> <item quantity="other">%d szavazat</item>

View File

@ -855,6 +855,24 @@
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="one">%d vote</item> <item quantity="one">%d vote</item>
<item quantity="other">%d votes</item> <item quantity="other">%d votes</item>

View File

@ -854,6 +854,24 @@ https://yandex.ru/legal/confidential/?lang=en
<string name="error_channel_mandatory">The channel is required when the playlist is public.</string> <string name="error_channel_mandatory">The channel is required when the playlist is public.</string>
<string name="action_playlist_create">Create a playlist</string> <string name="action_playlist_create">Create a playlist</string>
<string name="action_playlist_empty_content">There is nothing in this playlist yet.</string> <string name="action_playlist_empty_content">There is nothing in this playlist yet.</string>
<string name="edit_media">Edit media</string>
<string name="redo">redo</string>
<string name="gallery">Gallery</string>
<string name="label_emoji">Emoji</string>
<string name="label_sticker">Sticker</string>
<string name="label_eraser">Eraser</string>
<string name="label_text">Text</string>
<string name="label_filter">Filter</string>
<string name="label_adjust">Adjust</string>
<string name="label_brush">Brush</string>
<string name="confirm_exit_editing">Are you sure to exit without saving the image?</string>
<string name="discard">Discard</string>
<string name="saving">Saving…</string>
<string name="image_saved">Image Saved Successfully!</string>
<string name="save_image_failed">Failed to save Image</string>
<string name="opacity">Opacity</string>
<string name="label_crop">Crop</string>
<string name="set_photo_editor">Enable photo editor</string>
<plurals name="number_of_vote"> <plurals name="number_of_vote">
<item quantity="other">%d votes</item> <item quantity="other">%d votes</item>
</plurals> </plurals>

Some files were not shown because too many files have changed in this diff Show More