multiAccount functionnality (#168)

* multiAccount functionnality

* remove sharedpreferences usages

* start fixing tests to work with changes

* remove test of removed functionality

* more fiddling with tests

* fix instance insert being broken

* clean up some more preferences usage

* close db

* try to fix a bunch of issues

* move db close

* add instance to user drawer item

* remove rule that is no longer needed

* correct mock server to fix test

* removed unused stuff

* fix domains not being validated correctly

* update test

* Delete q

* Move image filter application to a thread

* remove unused imports

* remove unused strings

* remove unused strings

* fix buttons (sometimes)

* solve some linter issues, fix saturation brightness contrast not being shown properly

* remove unused strings

* add tests for drawer

* remove unused imports, other linter suggestions

* fix broken auto linter fix
This commit is contained in:
Wv5twkFEKh54vo4tta9yu7dHa3 2020-05-19 09:49:34 +02:00 committed by GitHub
parent d4c026ab44
commit ca307abcde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
76 changed files with 715 additions and 928 deletions

View File

@ -113,6 +113,19 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0" implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
implementation "com.mikepenz:materialdrawer:8.0.3"
//required support lib modules
implementation "androidx.annotation:annotation:1.1.0"
// Add for NavController support
implementation "com.mikepenz:materialdrawer-nav:8.0.3"
//iconics
implementation "com.mikepenz:materialdrawer-iconics:8.0.3"
implementation 'com.mikepenz:google-material-typeface:3.0.1.4.original-kotlin@aar'
androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0' androidTestImplementation 'androidx.test:rules:1.2.0'
@ -129,7 +142,7 @@ dependencies {
// CameraX View class // CameraX View class
implementation 'androidx.camera:camera-view:1.0.0-alpha10' implementation 'androidx.camera:camera-view:1.0.0-alpha10'
implementation 'com.karumi:dexter:6.1.0' implementation 'com.karumi:dexter:6.1.2'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0' androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'

View File

@ -1,14 +1,12 @@
package com.h.pixeldroid package com.h.pixeldroid
import android.Manifest import android.Manifest
import android.content.ContentValues
import android.content.Intent import android.content.Intent
import android.content.Intent.ACTION_CHOOSER import android.content.Intent.ACTION_CHOOSER
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Color import android.graphics.Color
import android.media.MediaScannerConnection import android.media.MediaScannerConnection
import android.os.Environment import android.os.Environment
import android.provider.MediaStore
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import androidx.fragment.app.testing.launchFragmentInContainer import androidx.fragment.app.testing.launchFragmentInContainer
import androidx.test.espresso.intent.Intents import androidx.test.espresso.intent.Intents
@ -24,7 +22,6 @@ import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import java.io.File import java.io.File
import java.io.OutputStream
class CameraTest { class CameraTest {
@ -51,7 +48,7 @@ class CameraTest {
fun takePictureButton() { fun takePictureButton() {
var scenario = launchFragmentInContainer<CameraFragment>() var scenario = launchFragmentInContainer<CameraFragment>()
scenario.onFragment { _ -> scenario.onFragment {
val image = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888) val image = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888)
image.eraseColor(Color.GREEN) image.eraseColor(Color.GREEN)
val folder = val folder =

View File

@ -1,22 +1,22 @@
package com.h.pixeldroid package com.h.pixeldroid
import android.content.Context import android.content.Context
import android.view.Gravity
import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.DrawerActions import androidx.test.espresso.contrib.DrawerActions
import androidx.test.espresso.contrib.DrawerMatchers import androidx.test.espresso.contrib.DrawerMatchers
import androidx.test.espresso.contrib.NavigationViewActions
import androidx.test.espresso.matcher.ViewMatchers.* import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.InstanceDatabaseEntity
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.testUtility.MockServer import com.h.pixeldroid.testUtility.MockServer
import com.h.pixeldroid.utils.DBUtils
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -27,21 +27,41 @@ import org.junit.runner.RunWith
class DrawerMenuTest { class DrawerMenuTest {
private val mockServer = MockServer() private val mockServer = MockServer()
private lateinit var db: AppDatabase
private lateinit var context: Context
@get:Rule @get:Rule
var globalTimeout: Timeout = Timeout.seconds(30) var globalTimeout: Timeout = Timeout.seconds(30)
@get:Rule
var activityRule: ActivityScenarioRule<MainActivity>
= ActivityScenarioRule(MainActivity::class.java)
@Before @Before
fun before(){ fun before(){
mockServer.start() mockServer.start()
val baseUrl = mockServer.getUrl() val baseUrl = mockServer.getUrl()
val preferences = InstrumentationRegistry.getInstrumentation()
.targetContext.getSharedPreferences("com.h.pixeldroid.pref", Context.MODE_PRIVATE) context = ApplicationProvider.getApplicationContext()
preferences.edit().putString("accessToken", "azerty").apply() db = DBUtils.initDB(context)
preferences.edit().putString("domain", baseUrl.toString()).apply() db.clearAllTables()
db.instanceDao().insertInstance(
InstanceDatabaseEntity(
uri = baseUrl.toString(),
title = "PixelTest"
)
)
db.userDao().insertUser(
UserDatabaseEntity(
user_id = "123",
instance_uri = baseUrl.toString(),
username = "Testi",
display_name = "Testi Testo",
avatar_static = "some_avatar_url",
isActive = true,
accessToken = "token"
)
)
db.close()
// Open Drawer to click on navigation. // Open Drawer to click on navigation.
ActivityScenario.launch(MainActivity::class.java) ActivityScenario.launch(MainActivity::class.java)
onView(withId(R.id.drawer_layout)) onView(withId(R.id.drawer_layout))
@ -52,7 +72,7 @@ class DrawerMenuTest {
@Test @Test
fun testDrawerSettingsButton() { fun testDrawerSettingsButton() {
// Start the screen of your activity. // Start the screen of your activity.
onView(withId(R.id.nav_view)).perform(NavigationViewActions.navigateTo(R.id.nav_settings)) onView(withText(R.string.menu_settings)).perform(click())
// Check that settings activity was opened. // Check that settings activity was opened.
onView(withText(R.string.theme_title)).check(matches(isDisplayed())) onView(withText(R.string.theme_title)).check(matches(isDisplayed()))
} }
@ -60,7 +80,7 @@ class DrawerMenuTest {
@Test @Test
fun testThemeSettings() { fun testThemeSettings() {
// Start the screen of your activity. // Start the screen of your activity.
onView(withId(R.id.nav_view)).perform(NavigationViewActions.navigateTo(R.id.nav_settings)) onView(withText(R.string.menu_settings)).perform(click())
val themes = getInstrumentation().targetContext.resources.getStringArray(R.array.theme_entries) val themes = getInstrumentation().targetContext.resources.getStringArray(R.array.theme_entries)
//select theme modes //select theme modes
onView(withText(R.string.theme_title)).perform(click()) onView(withText(R.string.theme_title)).perform(click())
@ -81,7 +101,7 @@ class DrawerMenuTest {
@Test @Test
fun testDrawerLogoutButton() { fun testDrawerLogoutButton() {
// Start the screen of your activity. // Start the screen of your activity.
onView(withId(R.id.nav_view)).perform(NavigationViewActions.navigateTo(R.id.nav_logout)) onView(withText(R.string.logout)).perform(click())
// Check that settings activity was opened. // Check that settings activity was opened.
onView(withId(R.id.connect_instance_button)).check(matches(isDisplayed())) onView(withId(R.id.connect_instance_button)).check(matches(isDisplayed()))
} }
@ -89,38 +109,38 @@ class DrawerMenuTest {
@Test @Test
fun testDrawerProfileButton() { fun testDrawerProfileButton() {
// Start the screen of your activity. // Start the screen of your activity.
onView(withId(R.id.nav_view)).perform(NavigationViewActions.navigateTo(R.id.nav_account)) onView(withText(R.string.menu_account)).perform(click())
// Check that profile activity was opened. // Check that profile activity was opened.
onView(withId(R.id.profilePictureImageView)).check(matches(isDisplayed())) onView(withId(R.id.profilePictureImageView)).check(matches(isDisplayed()))
} }
@Test /*@Test
fun testDrawerAvatarClick() { fun testDrawerAvatarClick() {
// Start the screen of your activity. // Start the screen of your activity.
onView(withId(R.id.drawer_avatar)).perform(ViewActions.click()) onView(withText(R.string.menu_account)).perform(click())
// Check that profile activity was opened. // Check that profile activity was opened.
onView(withId(R.id.profilePictureImageView)).check(matches(isDisplayed())) onView(withId(R.id.profilePictureImageView)).check(matches(isDisplayed()))
} }*/
@Test /*@Test
fun testDrawerAccountNameClick() { fun testDrawerAccountNameClick() {
// Start the screen of your activity. // Start the screen of your activity.
onView(withId(R.id.drawer_account_name)).perform(ViewActions.click()) onView(withText("Testi")).perform(click())
// Check that profile activity was opened. // Check that profile activity was opened.
onView(withId(R.id.profilePictureImageView)).check(matches(isDisplayed())) onView(withText("Add Account")).check(matches(isDisplayed()))
} }*/
@Test @Test
fun clickFollowers() { fun clickFollowers() {
// Open My Profile from drawer // Open My Profile from drawer
onView(withId(R.id.nav_view)).perform(NavigationViewActions.navigateTo(R.id.nav_account)) onView(withText(R.string.menu_account)).perform(click())
Thread.sleep(1000) Thread.sleep(1000)
// Open followers list // Open followers list
onView(withId(R.id.nbFollowersTextView)).perform(ViewActions.click()) onView(withId(R.id.nbFollowersTextView)).perform(click())
Thread.sleep(1000) Thread.sleep(1000)
// Open follower's profile // Open follower's profile
onView(withText("ete2")).perform(ViewActions.click()) onView(withText("ete2")).perform(click())
Thread.sleep(1000) Thread.sleep(1000)
onView(withId(R.id.accountNameTextView)).check(matches(withText("Christian"))) onView(withId(R.id.accountNameTextView)).check(matches(withText("Christian")))
@ -129,13 +149,13 @@ class DrawerMenuTest {
@Test @Test
fun clickFollowing() { fun clickFollowing() {
// Open My Profile from drawer // Open My Profile from drawer
onView(withId(R.id.nav_view)).perform(NavigationViewActions.navigateTo(R.id.nav_account)) onView(withText(R.string.menu_account)).perform(click())
Thread.sleep(1000) Thread.sleep(1000)
// Open followers list // Open followers list
onView(withId(R.id.nbFollowingTextView)).perform(ViewActions.click()) onView(withId(R.id.nbFollowingTextView)).perform(click())
Thread.sleep(1000) Thread.sleep(1000)
// Open following's profile // Open following's profile
onView(withText("Dobios")).perform(ViewActions.click()) onView(withText("Dobios")).perform(click())
Thread.sleep(1000) Thread.sleep(1000)
onView(withId(R.id.accountNameTextView)).check(matches(withText("Andrew Dobis"))) onView(withId(R.id.accountNameTextView)).check(matches(withText("Andrew Dobis")))

View File

@ -1,6 +1,5 @@
package com.h.pixeldroid package com.h.pixeldroid
import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.view.View import android.view.View
@ -20,7 +19,6 @@ import androidx.test.rule.GrantPermissionRule
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.h.pixeldroid.adapters.ThumbnailAdapter import com.h.pixeldroid.adapters.ThumbnailAdapter
import com.h.pixeldroid.testUtility.CustomMatchers import com.h.pixeldroid.testUtility.CustomMatchers
import com.h.pixeldroid.testUtility.MockServer
import kotlinx.android.synthetic.main.fragment_edit_image.* import kotlinx.android.synthetic.main.fragment_edit_image.*
import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.allOf
import org.junit.Assert import org.junit.Assert
@ -33,7 +31,6 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class EditPhotoTest { class EditPhotoTest {
private val mockServer = MockServer()
private lateinit var activity: PhotoEditActivity private lateinit var activity: PhotoEditActivity
private lateinit var activityScenario: ActivityScenario<PhotoEditActivity> private lateinit var activityScenario: ActivityScenario<PhotoEditActivity>
@ -46,11 +43,6 @@ class EditPhotoTest {
@Before @Before
fun before() { fun before() {
val context = InstrumentationRegistry.getInstrumentation().targetContext val context = InstrumentationRegistry.getInstrumentation().targetContext
mockServer.start()
val baseUrl = mockServer.getUrl()
val preferences = context.getSharedPreferences("com.h.pixeldroid.pref", Context.MODE_PRIVATE)
preferences.edit().putString("accessToken", "azerty").apply()
preferences.edit().putString("domain", baseUrl.toString()).apply()
// Launch PhotoEditActivity // Launch PhotoEditActivity
val uri: Uri = Uri.parse("android.resource://com.h.pixeldroid/drawable/index") val uri: Uri = Uri.parse("android.resource://com.h.pixeldroid/drawable/index")

View File

@ -4,32 +4,29 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.text.SpannableString import android.text.SpannableString
import android.text.style.ClickableSpan import android.text.style.ClickableSpan
import android.view.Gravity
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso import androidx.test.espresso.Espresso
import androidx.test.espresso.NoMatchingViewException import androidx.test.espresso.NoMatchingViewException
import androidx.test.espresso.UiController import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction import androidx.test.espresso.ViewAction
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.contrib.DrawerActions
import androidx.test.espresso.contrib.DrawerMatchers
import androidx.test.espresso.contrib.NavigationViewActions
import androidx.test.espresso.contrib.RecyclerViewActions import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.intent.Intents import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.Intents.intended import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers import androidx.test.espresso.intent.matcher.IntentMatchers
import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.ActivityTestRule import androidx.test.rule.ActivityTestRule
import com.google.android.material.tabs.TabLayout import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.InstanceDatabaseEntity
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.fragments.feeds.PostViewHolder import com.h.pixeldroid.fragments.feeds.PostViewHolder
import com.h.pixeldroid.objects.Account import com.h.pixeldroid.objects.Account
import com.h.pixeldroid.objects.Account.Companion.ACCOUNT_TAG import com.h.pixeldroid.objects.Account.Companion.ACCOUNT_TAG
import com.h.pixeldroid.testUtility.MockServer import com.h.pixeldroid.testUtility.MockServer
import com.h.pixeldroid.utils.DBUtils
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers
import org.hamcrest.Matcher import org.hamcrest.Matcher
import org.hamcrest.Matchers import org.hamcrest.Matchers
@ -45,6 +42,8 @@ import org.junit.runner.RunWith
class IntentTest { class IntentTest {
private val mockServer = MockServer() private val mockServer = MockServer()
private lateinit var db: AppDatabase
private lateinit var context: Context
@get:Rule @get:Rule
var globalTimeout: Timeout = Timeout.seconds(100) var globalTimeout: Timeout = Timeout.seconds(100)
@ -59,10 +58,30 @@ class IntentTest {
fun before() { fun before() {
mockServer.start() mockServer.start()
val baseUrl = mockServer.getUrl() val baseUrl = mockServer.getUrl()
val preferences = InstrumentationRegistry.getInstrumentation()
.targetContext.getSharedPreferences("com.h.pixeldroid.pref", Context.MODE_PRIVATE) context = ApplicationProvider.getApplicationContext()
preferences.edit().putString("accessToken", "azerty").apply() db = DBUtils.initDB(context)
preferences.edit().putString("domain", baseUrl.toString()).apply() db.clearAllTables()
db.instanceDao().insertInstance(
InstanceDatabaseEntity(
uri = baseUrl.toString(),
title = "PixelTest"
)
)
db.userDao().insertUser(
UserDatabaseEntity(
user_id = "123",
instance_uri = baseUrl.toString(),
username = "Testi",
display_name = "Testi Testo",
avatar_static = "some_avatar_url",
isActive = true,
accessToken = "token"
)
)
db.close()
Intents.init() Intents.init()
} }
@ -145,14 +164,15 @@ class IntentTest {
} }
} }
@Test /*@Test
fun launchesIntent() { fun launchesIntent() {
// Open Drawer to click on navigation. // Open Drawer to click on navigation.
ActivityScenario.launch(MainActivity::class.java) ActivityScenario.launch(MainActivity::class.java)
Espresso.onView(ViewMatchers.withId(R.id.drawer_layout)) Espresso.onView(ViewMatchers.withId(R.id.drawer_layout))
.check(ViewAssertions.matches(DrawerMatchers.isClosed(Gravity.LEFT))) // Left Drawer should be closed. .check(ViewAssertions.matches(DrawerMatchers.isClosed(Gravity.LEFT))) // Left Drawer should be closed.
.perform(DrawerActions.open()) // Open Drawer .perform(DrawerActions.open()) // Open Drawer
Espresso.onView(ViewMatchers.withId(R.id.nav_view))
Espresso.onView(ViewMatchers.withId(R.id.drawer))
.perform(NavigationViewActions.navigateTo(R.id.nav_account)) .perform(NavigationViewActions.navigateTo(R.id.nav_account))
val expectedIntent: Matcher<Intent> = CoreMatchers.allOf( val expectedIntent: Matcher<Intent> = CoreMatchers.allOf(
@ -166,7 +186,7 @@ class IntentTest {
Thread.sleep(1000) Thread.sleep(1000)
intended(expectedIntent) intended(expectedIntent)
} } */
@After @After
fun after() { fun after() {

View File

@ -1,37 +1,20 @@
package com.h.pixeldroid package com.h.pixeldroid
import android.app.Activity
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.Intent.ACTION_VIEW import android.content.Intent.ACTION_VIEW
import android.net.Uri
import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.scrollTo import androidx.test.espresso.action.ViewActions.scrollTo
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.Intents.intended import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction
import androidx.test.espresso.intent.matcher.IntentMatchers.hasDataString import androidx.test.espresso.intent.matcher.IntentMatchers.hasDataString
import androidx.test.espresso.matcher.ViewMatchers.hasErrorText
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.rule.ActivityTestRule import androidx.test.rule.ActivityTestRule
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiSelector
import com.h.pixeldroid.db.InstanceDatabaseEntity
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.utils.DBUtils
import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.anyOf
import org.hamcrest.CoreMatchers.containsString import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.Matcher import org.hamcrest.Matcher
import org.junit.After import org.junit.After

View File

@ -4,21 +4,15 @@ import android.content.Context
import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.DrawerActions
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.UiSelector
import com.h.pixeldroid.db.AppDatabase import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.InstanceDatabaseEntity
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.utils.DBUtils import com.h.pixeldroid.utils.DBUtils
import kotlinx.android.synthetic.main.activity_login.login_activity_instance_chooser_button
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
@ -45,6 +39,7 @@ class LoginActivityOfflineTest {
val context = ApplicationProvider.getApplicationContext<Context>() val context = ApplicationProvider.getApplicationContext<Context>()
db = DBUtils.initDB(context) db = DBUtils.initDB(context)
db.clearAllTables() db.clearAllTables()
db.close()
} }
@Test @Test
@ -53,26 +48,6 @@ class LoginActivityOfflineTest {
onView(withId(R.id.login_activity_connection_required_text)).check(matches(isDisplayed())) onView(withId(R.id.login_activity_connection_required_text)).check(matches(isDisplayed()))
} }
@Test
fun offlineModeSelectAvailabeLaunchesMainActivityWithStoredAccountInstance() {
db.instanceDao().insertInstance(
InstanceDatabaseEntity(
uri = "some_uri",
title = "PixelTest"
))
db.userDao().insertUser(
UserDatabaseEntity(
user_id = "some_user_id",
instance_uri = "some_uri",
username = "Testi",
display_name = "Testi Testo",
avatar_static = "some_avatar_url"
))
ActivityScenario.launch(LoginActivity::class.java)
onView(withId(R.id.login_activity_instance_chooser_button)).perform(click())
onView(withId(R.id.drawer_layout)).perform(DrawerActions.open())
onView(withId(R.id.drawer_account_name)).check(matches(withText("Testi Testo")))
}
@After @After
fun after() { fun after() {

View File

@ -47,27 +47,7 @@ class LoginActivityOnlineTest {
pref.edit().clear().apply() pref.edit().clear().apply()
db = DBUtils.initDB(context) db = DBUtils.initDB(context)
db.clearAllTables() db.clearAllTables()
} db.close()
@Test
fun connectToSavedAccount() {
db.instanceDao().insertInstance(
InstanceDatabaseEntity(
uri = "some_uri",
title = "PixelTest"
)
)
db.userDao().insertUser(
UserDatabaseEntity(
user_id = "some_user_id",
instance_uri = "some_uri",
username = "Testi",
display_name = "Testi Testo",
avatar_static = "some_avatar_url"
)
)
ActivityScenario.launch(LoginActivity::class.java)
onView(withId(R.id.login_activity_instance_chooser_button)).perform(click())
} }
@Test @Test
@ -85,7 +65,7 @@ class LoginActivityOnlineTest {
ActivityScenario.launch(LoginActivity::class.java) ActivityScenario.launch(LoginActivity::class.java)
onView(withId(R.id.connect_instance_button)).perform(click()) onView(withId(R.id.connect_instance_button)).perform(click())
onView(withId(R.id.editText)).check(matches( onView(withId(R.id.editText)).check(matches(
hasErrorText(context.getString(R.string.login_empty_string_error)) hasErrorText(context.getString(R.string.invalid_domain))
)) ))
} }
@ -116,8 +96,30 @@ class LoginActivityOnlineTest {
@Test @Test
fun correctIntentReturnLoadsMainActivity() { fun correctIntentReturnLoadsMainActivity() {
context = ApplicationProvider.getApplicationContext()
db = DBUtils.initDB(context)
db.clearAllTables()
db.instanceDao().insertInstance(
InstanceDatabaseEntity(
uri = server.getUrl().toString(),
title = "PixelTest"
)
)
db.userDao().insertUser(
UserDatabaseEntity(
user_id = "123",
instance_uri = server.getUrl().toString(),
username = "Testi",
display_name = "Testi Testo",
avatar_static = "some_avatar_url",
isActive = true,
accessToken = "token"
)
)
db.close()
pref.edit() pref.edit()
.putString("accessToken", "azerty")
.putString("domain", server.getUrl().toString()) .putString("domain", server.getUrl().toString())
.putString("clientID", "test_id") .putString("clientID", "test_id")
.putString("clientSecret", "test_secret") .putString("clientSecret", "test_secret")
@ -125,6 +127,7 @@ class LoginActivityOnlineTest {
val uri = Uri.parse("oauth2redirect://com.h.pixeldroid?code=test_code") val uri = Uri.parse("oauth2redirect://com.h.pixeldroid?code=test_code")
val intent = Intent(ACTION_VIEW, uri, context, LoginActivity::class.java) val intent = Intent(ACTION_VIEW, uri, context, LoginActivity::class.java)
ActivityScenario.launch<LoginActivity>(intent) ActivityScenario.launch<LoginActivity>(intent)
Thread.sleep(1000)
onView(withId(R.id.main_activity_main_linear_layout)).check(matches(isDisplayed())) onView(withId(R.id.main_activity_main_linear_layout)).check(matches(isDisplayed()))
} }
} }

View File

@ -1,15 +1,11 @@
package com.h.pixeldroid package com.h.pixeldroid
import android.graphics.ColorMatrix
import android.content.Context import android.content.Context
import android.view.View.GONE import android.graphics.ColorMatrix
import android.view.View.VISIBLE
import android.widget.TextView import android.widget.TextView
import androidx.core.view.get
import androidx.core.view.isVisible
import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.Espresso.onData import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.click
@ -17,10 +13,11 @@ import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition
import androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition import androidx.test.espresso.contrib.RecyclerViewActions.scrollToPosition
import androidx.test.espresso.matcher.ViewMatchers.* import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.InstanceDatabaseEntity
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.fragments.feeds.PostViewHolder import com.h.pixeldroid.fragments.feeds.PostViewHolder
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.clickChildViewWithId import com.h.pixeldroid.testUtility.CustomMatchers.Companion.clickChildViewWithId
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.first import com.h.pixeldroid.testUtility.CustomMatchers.Companion.first
@ -29,14 +26,9 @@ import com.h.pixeldroid.testUtility.CustomMatchers.Companion.second
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.slowSwipeUp import com.h.pixeldroid.testUtility.CustomMatchers.Companion.slowSwipeUp
import com.h.pixeldroid.testUtility.CustomMatchers.Companion.typeTextInViewWithId import com.h.pixeldroid.testUtility.CustomMatchers.Companion.typeTextInViewWithId
import com.h.pixeldroid.testUtility.MockServer import com.h.pixeldroid.testUtility.MockServer
import com.h.pixeldroid.utils.DBUtils
import com.h.pixeldroid.utils.PostUtils.Companion.censorColorMatrix import com.h.pixeldroid.utils.PostUtils.Companion.censorColorMatrix
import com.h.pixeldroid.utils.PostUtils.Companion.uncensorColorMatrix import com.h.pixeldroid.utils.PostUtils.Companion.uncensorColorMatrix
import kotlinx.android.synthetic.main.fragment_feed.*
import kotlinx.android.synthetic.main.fragment_feed.view.*
import kotlinx.android.synthetic.main.post_fragment.*
import kotlinx.android.synthetic.main.post_fragment.view.*
import org.hamcrest.Matchers.`is`
import org.hamcrest.Matchers.not
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -49,21 +41,38 @@ class MockedServerTest {
private val mockServer = MockServer() private val mockServer = MockServer()
private lateinit var activityScenario: ActivityScenario<MainActivity> private lateinit var activityScenario: ActivityScenario<MainActivity>
private lateinit var db: AppDatabase
private lateinit var context: Context
@get:Rule @get:Rule
var globalTimeout: Timeout = Timeout.seconds(100) var globalTimeout: Timeout = Timeout.seconds(100)
@get:Rule
var activityRule: ActivityScenarioRule<MainActivity>
= ActivityScenarioRule(MainActivity::class.java)
@Before @Before
fun before(){ fun before(){
mockServer.start() mockServer.start()
val baseUrl = mockServer.getUrl() val baseUrl = mockServer.getUrl()
val preferences = InstrumentationRegistry.getInstrumentation() context = ApplicationProvider.getApplicationContext()
.targetContext.getSharedPreferences("com.h.pixeldroid.pref", Context.MODE_PRIVATE) db = DBUtils.initDB(context)
preferences.edit().putString("accessToken", "azerty").apply() db.clearAllTables()
preferences.edit().putString("domain", baseUrl.toString()).apply() db.instanceDao().insertInstance(
InstanceDatabaseEntity(
uri = baseUrl.toString(),
title = "PixelTest"
)
)
db.userDao().insertUser(
UserDatabaseEntity(
user_id = "123",
instance_uri = baseUrl.toString(),
username = "Testi",
display_name = "Testi Testo",
avatar_static = "some_avatar_url",
isActive = true,
accessToken = "token"
)
)
db.close()
activityScenario = ActivityScenario.launch(MainActivity::class.java) activityScenario = ActivityScenario.launch(MainActivity::class.java)
} }

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.assertion.ViewAssertions.matches
@ -11,7 +12,11 @@ import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.InstanceDatabaseEntity
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.testUtility.MockServer import com.h.pixeldroid.testUtility.MockServer
import com.h.pixeldroid.utils.DBUtils
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -22,6 +27,8 @@ import org.junit.runner.RunWith
class PostCreationActivityTest { class PostCreationActivityTest {
private val mockServer = MockServer() private val mockServer = MockServer()
private lateinit var db: AppDatabase
@get:Rule @get:Rule
val globalTimeout: Timeout = Timeout.seconds(30) val globalTimeout: Timeout = Timeout.seconds(30)
@ -31,10 +38,27 @@ class PostCreationActivityTest {
val context = InstrumentationRegistry.getInstrumentation().targetContext val context = InstrumentationRegistry.getInstrumentation().targetContext
mockServer.start() mockServer.start()
val baseUrl = mockServer.getUrl() val baseUrl = mockServer.getUrl()
val preferences = context.getSharedPreferences("com.h.pixeldroid.pref", Context.MODE_PRIVATE) db = DBUtils.initDB(context)
preferences.edit().putString("accessToken", "azerty").apply() db.clearAllTables()
preferences.edit().putString("domain", baseUrl.toString()).apply() db.instanceDao().insertInstance(
InstanceDatabaseEntity(
uri = baseUrl.toString(),
title = "PixelTest"
)
)
db.userDao().insertUser(
UserDatabaseEntity(
user_id = "123",
instance_uri = baseUrl.toString(),
username = "Testi",
display_name = "Testi Testo",
avatar_static = "some_avatar_url",
isActive = true,
accessToken = "token"
)
)
db.close()
val uri: Uri = Uri.parse("android.resource://com.h.pixeldroid/drawable/index") val uri: Uri = Uri.parse("android.resource://com.h.pixeldroid/drawable/index")
val intent = Intent(context, PostCreationActivity::class.java) val intent = Intent(context, PostCreationActivity::class.java)
.putExtra("picture_uri", uri) .putExtra("picture_uri", uri)

View File

@ -16,7 +16,11 @@ import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule import androidx.test.rule.GrantPermissionRule
import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.InstanceDatabaseEntity
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.testUtility.MockServer import com.h.pixeldroid.testUtility.MockServer
import com.h.pixeldroid.utils.DBUtils
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.camera_ui_container.* import kotlinx.android.synthetic.main.camera_ui_container.*
import org.hamcrest.Matcher import org.hamcrest.Matcher
@ -66,14 +70,35 @@ class PostFragmentUITests {
@get:Rule @get:Rule
var rule = ActivityScenarioRule(MainActivity::class.java) var rule = ActivityScenarioRule(MainActivity::class.java)
private lateinit var db: AppDatabase
@Before @Before
fun setup() { fun setup() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
mockServer.start() mockServer.start()
val baseUrl = mockServer.getUrl() val baseUrl = mockServer.getUrl()
val preferences = InstrumentationRegistry.getInstrumentation() db = DBUtils.initDB(context)
.targetContext.getSharedPreferences("com.h.pixeldroid.pref", Context.MODE_PRIVATE) db.clearAllTables()
preferences.edit().putString("accessToken", "azerty").apply() db.instanceDao().insertInstance(
preferences.edit().putString("domain", baseUrl.toString()).apply() InstanceDatabaseEntity(
uri = baseUrl.toString(),
title = "PixelTest"
)
)
db.userDao().insertUser(
UserDatabaseEntity(
user_id = "123",
instance_uri = baseUrl.toString(),
username = "Testi",
display_name = "Testi Testo",
avatar_static = "some_avatar_url",
isActive = true,
accessToken = "token"
)
)
db.close()
Thread.sleep(300) Thread.sleep(300)
} }

View File

@ -18,10 +18,14 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule import androidx.test.rule.GrantPermissionRule
import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.InstanceDatabaseEntity
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.objects.Account import com.h.pixeldroid.objects.Account
import com.h.pixeldroid.objects.Attachment import com.h.pixeldroid.objects.Attachment
import com.h.pixeldroid.objects.Status import com.h.pixeldroid.objects.Status
import com.h.pixeldroid.testUtility.MockServer import com.h.pixeldroid.testUtility.MockServer
import com.h.pixeldroid.utils.DBUtils
import org.hamcrest.CoreMatchers import org.hamcrest.CoreMatchers
import org.hamcrest.Matcher import org.hamcrest.Matcher
import org.junit.After import org.junit.After
@ -36,6 +40,7 @@ import org.junit.runner.RunWith
class PostTest { class PostTest {
private lateinit var context: Context private lateinit var context: Context
private lateinit var db: AppDatabase
@get:Rule @get:Rule
var globalTimeout: Timeout = Timeout.seconds(100) var globalTimeout: Timeout = Timeout.seconds(100)
@ -46,11 +51,27 @@ class PostTest {
val mockServer = MockServer() val mockServer = MockServer()
mockServer.start() mockServer.start()
val baseUrl = mockServer.getUrl() val baseUrl = mockServer.getUrl()
val preferences = context.getSharedPreferences( db = DBUtils.initDB(context)
"com.h.pixeldroid.pref", db.clearAllTables()
Context.MODE_PRIVATE) db.instanceDao().insertInstance(
preferences.edit().putString("accessToken", "azerty").apply() InstanceDatabaseEntity(
preferences.edit().putString("domain", baseUrl.toString()).apply() uri = baseUrl.toString(),
title = "PixelTest"
)
)
db.userDao().insertUser(
UserDatabaseEntity(
user_id = "123",
instance_uri = baseUrl.toString(),
username = "Testi",
display_name = "Testi Testo",
avatar_static = "some_avatar_url",
isActive = true,
accessToken = "token"
)
)
db.close()
Intents.init() Intents.init()
} }

View File

@ -166,7 +166,7 @@ class JsonValues {
"created_at": 12121212 "created_at": 12121212
}""" }"""
const val instanceJson = """{ const val instanceJson = """{
"uri": "pixeldroid.epfl", "uri": "REPLACEWITHDOMAIN",
"title": "PixelDroid", "title": "PixelDroid",
"description": "Test server description.", "description": "Test server description.",
"email": "lejeu@epfl.ch", "email": "lejeu@epfl.ch",

View File

@ -10,8 +10,8 @@ class MockServer {
companion object{ companion object{
private val server = MockWebServer() private val server = MockWebServer()
private val headerName = "Content-Type" private const val headerName = "Content-Type"
private val headerValue = "application/json; charset=utf-8" private const val headerValue = "application/json; charset=utf-8"
} }
fun start() { fun start() {
@ -33,7 +33,7 @@ class MockServer {
.setResponseCode(200).setBody(JsonValues.accountJson) .setResponseCode(200).setBody(JsonValues.accountJson)
"/api/v1/instance" -> return MockResponse() "/api/v1/instance" -> return MockResponse()
.addHeader(headerName, headerValue) .addHeader(headerName, headerValue)
.setResponseCode(200).setBody(JsonValues.instanceJson) .setResponseCode(200).setBody(JsonValues.instanceJson.replace("REPLACEWITHDOMAIN", getUrl().toString()))
"/api/v1/media" -> return MockResponse() "/api/v1/media" -> return MockResponse()
.addHeader(headerName, headerValue) .addHeader(headerName, headerValue)
.setResponseCode(200).setBody(JsonValues.mediaUploadResponseJson) .setResponseCode(200).setBody(JsonValues.mediaUploadResponseJson)

View File

@ -1,14 +1,14 @@
package com.h.pixeldroid package com.h.pixeldroid
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.h.pixeldroid.api.PixelfedAPI import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.fragments.feeds.AccountListFragment import com.h.pixeldroid.fragments.feeds.AccountListFragment
import com.h.pixeldroid.objects.Account import com.h.pixeldroid.objects.Account
import com.h.pixeldroid.objects.Account.Companion.ACCOUNT_ID_TAG import com.h.pixeldroid.objects.Account.Companion.ACCOUNT_ID_TAG
import com.h.pixeldroid.objects.Account.Companion.FOLLOWING_TAG import com.h.pixeldroid.objects.Account.Companion.FOLLOWING_TAG
import com.h.pixeldroid.utils.DBUtils
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
@ -25,11 +25,15 @@ class FollowsActivity : AppCompatActivity() {
val following = intent.getSerializableExtra(FOLLOWING_TAG) as Boolean val following = intent.getSerializableExtra(FOLLOWING_TAG) as Boolean
if(id == null) { if(id == null) {
val preferences = this.getSharedPreferences( val db = DBUtils.initDB(applicationContext)
"${BuildConfig.APPLICATION_ID}.pref", Context.MODE_PRIVATE
) val user = db.userDao().getActiveUser()
val pixelfedAPI = PixelfedAPI.create("${preferences.getString("domain", "")}")
val accessToken = preferences.getString("accessToken", "") val domain = user?.instance_uri.orEmpty()
val accessToken = user?.accessToken.orEmpty()
db.close()
val pixelfedAPI = PixelfedAPI.create(domain)
pixelfedAPI.verifyCredentials("Bearer $accessToken").enqueue(object : pixelfedAPI.verifyCredentials("Bearer $accessToken").enqueue(object :
Callback<Account> { Callback<Account> {

View File

@ -6,32 +6,22 @@ import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.View import android.view.View
import android.widget.ArrayAdapter import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.browser.customtabs.CustomTabsIntent import androidx.browser.customtabs.CustomTabsIntent
import com.h.pixeldroid.api.PixelfedAPI import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.db.AppDatabase import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.InstanceDatabaseEntity
import com.h.pixeldroid.objects.Account import com.h.pixeldroid.objects.Account
import com.h.pixeldroid.objects.Application import com.h.pixeldroid.objects.Application
import com.h.pixeldroid.objects.Instance import com.h.pixeldroid.objects.Instance
import com.h.pixeldroid.objects.Token import com.h.pixeldroid.objects.Token
import com.h.pixeldroid.utils.DBUtils import com.h.pixeldroid.utils.DBUtils
import com.h.pixeldroid.utils.DBUtils.Companion.storeInstance
import com.h.pixeldroid.utils.Utils import com.h.pixeldroid.utils.Utils
import kotlinx.android.synthetic.main.activity_login.connect_instance_button import com.h.pixeldroid.utils.Utils.Companion.normalizeDomain
import kotlinx.android.synthetic.main.activity_login.editText import kotlinx.android.synthetic.main.activity_login.*
import kotlinx.android.synthetic.main.activity_login.login_activity_connection_required_text import okhttp3.HttpUrl
import kotlinx.android.synthetic.main.activity_login.login_activity_instance_chooser
import kotlinx.android.synthetic.main.activity_login.login_activity_instance_chooser_button
import kotlinx.android.synthetic.main.activity_login.login_activity_instance_chooser_layout
import kotlinx.android.synthetic.main.activity_login.login_activity_instance_chooser_offline_text
import kotlinx.android.synthetic.main.activity_login.login_activity_instance_input_layout
import kotlinx.android.synthetic.main.activity_login.progressLayout
import kotlinx.android.synthetic.main.activity_login.whatsAnInstanceTextView
import okhttp3.internal.toImmutableList
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
@ -40,7 +30,6 @@ import retrofit2.Response
class LoginActivity : AppCompatActivity() { class LoginActivity : AppCompatActivity() {
companion object { companion object {
private const val TAG = "Login Activity"
private const val PACKAGE_ID = BuildConfig.APPLICATION_ID private const val PACKAGE_ID = BuildConfig.APPLICATION_ID
private const val SCOPE = "read write follow" private const val SCOPE = "read write follow"
} }
@ -51,7 +40,6 @@ class LoginActivity : AppCompatActivity() {
private lateinit var db: AppDatabase private lateinit var db: AppDatabase
private lateinit var pixelfedAPI: PixelfedAPI private lateinit var pixelfedAPI: PixelfedAPI
private var inputVisibility: Int = View.GONE private var inputVisibility: Int = View.GONE
private var chooserVisibility: Int = View.GONE
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -63,18 +51,6 @@ class LoginActivity : AppCompatActivity() {
preferences = getSharedPreferences("$PACKAGE_ID.pref", Context.MODE_PRIVATE) preferences = getSharedPreferences("$PACKAGE_ID.pref", Context.MODE_PRIVATE)
db = DBUtils.initDB(applicationContext) db = DBUtils.initDB(applicationContext)
// check for stored accounts/instances
val accounts: List<Map<String, String>> = getSavedAccounts()
if (accounts.isNotEmpty()) {
displayChooser(accounts)
login_activity_instance_chooser_button.setOnClickListener {
val choice: Int = login_activity_instance_chooser.selectedItemId.toInt()
setPreferences(accounts[choice])
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
}
if (Utils.hasInternet(applicationContext)) { if (Utils.hasInternet(applicationContext)) {
connect_instance_button.setOnClickListener { connect_instance_button.setOnClickListener {
registerAppToServer(normalizeDomain(editText.text.toString())) registerAppToServer(normalizeDomain(editText.text.toString()))
@ -82,55 +58,11 @@ class LoginActivity : AppCompatActivity() {
whatsAnInstanceTextView.setOnClickListener{ whatsAnInstance() } whatsAnInstanceTextView.setOnClickListener{ whatsAnInstance() }
inputVisibility = View.VISIBLE inputVisibility = View.VISIBLE
} else { } else {
if (accounts.isEmpty()) {
login_activity_connection_required_text.visibility = View.VISIBLE login_activity_connection_required_text.visibility = View.VISIBLE
} else {
login_activity_instance_chooser_offline_text.visibility = View.VISIBLE
}
} }
loadingAnimation(false) loadingAnimation(false)
} }
private fun getSavedAccounts(): List<Map<String, String>> {
val result = mutableListOf<Map<String, String>>()
val instances = db.instanceDao().getAll()
for (user in db.userDao().getAll()) {
val instance = instances.first {instance ->
instance.uri == user.instance_uri
}
result.add(mapOf(
Pair("username", user.username),
Pair("instance_title", instance.title),
Pair("instance_uri", instance.uri),
Pair("id", user.user_id)
))
}
return result.toImmutableList()
}
private fun displayChooser(accounts: List<Map<String, String>>) {
ArrayAdapter(
this,
android.R.layout.simple_spinner_item,
accounts.map { account ->
"${account["username"]}@${account["instance_title"]}"
}).also {
adapter ->
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
login_activity_instance_chooser.adapter = adapter
}
chooserVisibility = View.VISIBLE
}
private fun setPreferences(account: Map<String, String>) {
if (Utils.hasInternet(applicationContext))
registerAppToServer(normalizeDomain(account["instance_uri"].orEmpty()))
else
preferences.edit()
.putString("user_id", account["id"])
.apply()
}
override fun onStart(){ override fun onStart(){
super.onStart() super.onStart()
val url: Uri? = intent.data val url: Uri? = intent.data
@ -148,8 +80,6 @@ class LoginActivity : AppCompatActivity() {
loadingAnimation(false) loadingAnimation(false)
} }
override fun onBackPressed() {
}
private fun whatsAnInstance() { private fun whatsAnInstance() {
val i = Intent(Intent.ACTION_VIEW) val i = Intent(Intent.ACTION_VIEW)
@ -157,18 +87,27 @@ class LoginActivity : AppCompatActivity() {
startActivity(i) startActivity(i)
} }
private fun normalizeDomain(domain: String): String { private fun hideKeyboard() {
return "https://" + domain val view = currentFocus
.replace("http://", "") if (view != null) {
.replace("https://", "") (getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(
.trim(Char::isWhitespace) view.windowToken,
InputMethodManager.HIDE_NOT_ALWAYS
)
}
} }
private fun registerAppToServer(normalizedDomain: String) { private fun registerAppToServer(normalizedDomain: String) {
try{
HttpUrl.Builder().host(normalizedDomain.replace("https://", "")).scheme("https").build()
} catch (e: IllegalArgumentException) {
return failedRegistration(getString(R.string.invalid_domain))
}
hideKeyboard()
loadingAnimation(true) loadingAnimation(true)
if (normalizedDomain.replace("https://", "").isNullOrBlank())
return failedRegistration(getString(R.string.login_empty_string_error))
PixelfedAPI.create(normalizedDomain).registerApplication( PixelfedAPI.create(normalizedDomain).registerApplication(
appName,"$oauthScheme://$PACKAGE_ID", SCOPE appName,"$oauthScheme://$PACKAGE_ID", SCOPE
).enqueue(object : Callback<Application> { ).enqueue(object : Callback<Application> {
@ -250,70 +189,67 @@ class LoginActivity : AppCompatActivity() {
private fun authenticationSuccessful(accessToken: String) { private fun authenticationSuccessful(accessToken: String) {
saveUserAndInstance(accessToken) saveUserAndInstance(accessToken)
preferences.edit().putString("accessToken", accessToken).apply() wipeSharedSettings()
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
} }
private fun failedRegistration(message: String = getString(R.string.registration_failed)) { private fun failedRegistration(message: String = getString(R.string.registration_failed)) {
loadingAnimation(false) loadingAnimation(false)
editText.error = message editText.error = message
wipeSharedSettings()
}
private fun wipeSharedSettings(){
preferences.edit().remove("domain").remove("clientId").remove("clientSecret")
.apply()
} }
private fun loadingAnimation(on: Boolean){ private fun loadingAnimation(on: Boolean){
if(on) { if(on) {
login_activity_instance_input_layout.visibility = View.GONE login_activity_instance_input_layout.visibility = View.GONE
login_activity_instance_chooser_layout.visibility = View.GONE
progressLayout.visibility = View.VISIBLE progressLayout.visibility = View.VISIBLE
} }
else { else {
login_activity_instance_input_layout.visibility = inputVisibility login_activity_instance_input_layout.visibility = inputVisibility
login_activity_instance_chooser_layout.visibility = chooserVisibility
progressLayout.visibility = View.GONE progressLayout.visibility = View.GONE
} }
} }
private fun saveUserAndInstance(accessToken: String) { private fun saveUserAndInstance(accessToken: String) {
preferences.edit().putInt("max_toot_chars", Instance.DEFAULT_MAX_TOOT_CHARS).apply()
pixelfedAPI.instance().enqueue(object : Callback<Instance> { pixelfedAPI.instance().enqueue(object : Callback<Instance> {
override fun onFailure(call: Call<Instance>, t: Throwable) { override fun onFailure(call: Call<Instance>, t: Throwable) {
return failedRegistration(getString(R.string.instance_error))
} }
override fun onResponse(call: Call<Instance>, response: Response<Instance>) { override fun onResponse(call: Call<Instance>, response: Response<Instance>) {
if (response.isSuccessful && response.body() != null) { if (response.isSuccessful && response.body() != null) {
val instance = response.body() as Instance val instance = response.body() as Instance
storeInstance(instance) storeInstance(db, instance)
storeUser(accessToken) storeUser(accessToken, instance.uri)
} else {
return failedRegistration(getString(R.string.instance_error))
} }
} }
}) })
} }
private fun storeInstance(instance: Instance) { private fun storeUser(accessToken: String, instance: String) {
val maxTootChars = instance.max_toot_chars.toInt()
preferences.edit().putInt("max_toot_chars", maxTootChars).apply()
preferences.edit().putString("instance_uri", instance.uri).apply()
val dbInstance = InstanceDatabaseEntity(
uri = instance.uri,
title = instance.title,
max_toot_chars = maxTootChars,
thumbnail = instance.thumbnail
)
db.instanceDao().insertInstance(dbInstance)
}
private fun storeUser(accessToken: String) {
pixelfedAPI.verifyCredentials("Bearer $accessToken") pixelfedAPI.verifyCredentials("Bearer $accessToken")
.enqueue(object : Callback<Account> { .enqueue(object : Callback<Account> {
override fun onResponse(call: Call<Account>, response: Response<Account>) { override fun onResponse(call: Call<Account>, response: Response<Account>) {
if (response.body() != null && response.isSuccessful) { if (response.body() != null && response.isSuccessful) {
db.userDao().deActivateActiveUser()
val user = response.body() as Account val user = response.body() as Account
preferences.edit().putString("user_id", user.id).apply()
DBUtils.addUser( DBUtils.addUser(
db, db,
user, user,
preferences.getString("instance_uri", null).orEmpty() instance,
activeUser = true,
accessToken = accessToken
) )
db.close()
val intent = Intent(this@LoginActivity, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
} }
} }
override fun onFailure(call: Call<Account>, t: Throwable) { override fun onFailure(call: Call<Account>, t: Throwable) {

View File

@ -2,58 +2,68 @@ package com.h.pixeldroid
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.MenuItem
import android.view.View import android.view.View
import androidx.annotation.NonNull import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat import androidx.core.view.GravityCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.navigation.NavigationView import com.bumptech.glide.Glide
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
import com.h.pixeldroid.api.PixelfedAPI import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.fragments.CameraFragment
import com.h.pixeldroid.db.AppDatabase import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.UserDatabaseEntity import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.fragments.CameraFragment
import com.h.pixeldroid.fragments.SearchDiscoverFragment import com.h.pixeldroid.fragments.SearchDiscoverFragment
import com.h.pixeldroid.fragments.feeds.PostsFeedFragment
import com.h.pixeldroid.fragments.feeds.NotificationsFragment import com.h.pixeldroid.fragments.feeds.NotificationsFragment
import com.h.pixeldroid.fragments.feeds.OfflineFeedFragment import com.h.pixeldroid.fragments.feeds.OfflineFeedFragment
import com.h.pixeldroid.fragments.feeds.PostsFeedFragment
import com.h.pixeldroid.fragments.feeds.PublicTimelineFragment import com.h.pixeldroid.fragments.feeds.PublicTimelineFragment
import com.h.pixeldroid.objects.Account import com.h.pixeldroid.objects.Account
import com.h.pixeldroid.utils.DBUtils import com.h.pixeldroid.utils.DBUtils
import com.h.pixeldroid.utils.ImageConverter
import com.h.pixeldroid.utils.Utils.Companion.hasInternet import com.h.pixeldroid.utils.Utils.Companion.hasInternet
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.materialdrawer.iconics.iconicsIcon
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.*
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
import com.mikepenz.materialdrawer.util.DrawerImageLoader
import com.mikepenz.materialdrawer.widget.AccountHeaderView
import kotlinx.android.synthetic.main.activity_main.*
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.nav_header.view.drawer_account_name
import kotlinx.android.synthetic.main.nav_header.view.drawer_avatar
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener { class MainActivity : AppCompatActivity() {
private lateinit var preferences: SharedPreferences
private val searchDiscoverFragment: SearchDiscoverFragment = SearchDiscoverFragment() private val searchDiscoverFragment: SearchDiscoverFragment = SearchDiscoverFragment()
private lateinit var db: AppDatabase private lateinit var db: AppDatabase
private lateinit var header: AccountHeaderView
private var user: UserDatabaseEntity? = null
companion object {
const val ADD_ACCOUNT_IDENTIFIER: Long = -13
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme_NoActionBar) setTheme(R.style.AppTheme_NoActionBar)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
preferences = getSharedPreferences(
"${BuildConfig.APPLICATION_ID}.pref", Context.MODE_PRIVATE
)
db = DBUtils.initDB(applicationContext) db = DBUtils.initDB(applicationContext)
//get the currently active user
user = db.userDao().getActiveUser()
//Check if we have logged in and gotten an access token //Check if we have logged in and gotten an access token
if((hasInternet(applicationContext) && !preferences.contains("accessToken")) if (user == null) {
|| (!hasInternet(applicationContext) && !preferences.contains("user_id"))) { launchActivity(LoginActivity(), firstTime = true)
launchActivity(LoginActivity())
} else { } else {
setupDrawer() setupDrawer()
val tabs = arrayOf( val tabs = arrayOf(
@ -69,17 +79,102 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
} }
private fun setupDrawer() { private fun setupDrawer() {
nav_view.setNavigationItemSelectedListener(this) header = AccountHeaderView(this).apply {
headerBackgroundScaleType = ImageView.ScaleType.CENTER_CROP
currentHiddenInList = true
onAccountHeaderListener = { _: View?, profile: IProfile, current: Boolean ->
clickProfile(profile, current)
}
addProfile(ProfileSettingDrawerItem().apply {
identifier = ADD_ACCOUNT_IDENTIFIER
nameRes = R.string.add_account_name
descriptionRes = R.string.add_account_description
iconicsIcon = GoogleMaterial.Icon.gmd_add
}, 0)
attachToSliderView(drawer)
dividerBelowHeader = false
closeDrawerOnProfileListClick = true
}
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) {
Glide.with(imageView.context)
.load(uri)
.placeholder(placeholder)
.into(imageView)
}
override fun cancel(imageView: ImageView) {
Glide.with(imageView.context).clear(imageView)
}
override fun placeholder(ctx: Context, tag: String?): Drawable {
if (tag == DrawerImageLoader.Tags.PROFILE.name || tag == DrawerImageLoader.Tags.PROFILE_DRAWER_ITEM.name) {
return ctx.getDrawable(R.drawable.ic_default_user)!!
}
return super.placeholder(ctx, tag)
}
})
fillDrawerAccountInfo(user!!.user_id)
//after setting with the values in the db, we make sure to update the database and apply
//with the received one. This happens asynchronously.
getUpdatedAccount()
drawer.itemAdapter.add(
primaryDrawerItem {
nameRes = R.string.menu_account
iconicsIcon = GoogleMaterial.Icon.gmd_person
},
primaryDrawerItem {
nameRes = R.string.menu_settings
iconicsIcon = GoogleMaterial.Icon.gmd_settings
},
primaryDrawerItem {
nameRes = R.string.logout
iconicsIcon = GoogleMaterial.Icon.gmd_close
})
drawer.onDrawerItemClickListener = { v, drawerItem, position ->
when (position){
1 -> launchActivity(ProfileActivity())
2 -> launchActivity(SettingsActivity())
3 -> logOut()
}
false
}
}
private fun logOut(){
db.userDao().deleteActiveUsers()
val remainingUsers = db.userDao().getAll()
if (remainingUsers.isEmpty()){
//no more users, start first-time login flow
launchActivity(LoginActivity(), firstTime = true)
} else {
val newActive = remainingUsers.first()
db.userDao().activateUser(newActive.user_id)
//relaunch the app
launchActivity(MainActivity(), firstTime = true)
}
}
private fun getUpdatedAccount(){
if (hasInternet(applicationContext)) { if (hasInternet(applicationContext)) {
val accessToken = preferences.getString("accessToken", "") val domain = user?.instance_uri.orEmpty()
val pixelfedAPI = PixelfedAPI.create("${preferences.getString("domain", "")}") val accessToken = user?.accessToken.orEmpty()
val pixelfedAPI = PixelfedAPI.create(domain)
pixelfedAPI.verifyCredentials("Bearer $accessToken") pixelfedAPI.verifyCredentials("Bearer $accessToken")
.enqueue(object : Callback<Account> { .enqueue(object : Callback<Account> {
override fun onResponse(call: Call<Account>, response: Response<Account>) { override fun onResponse(call: Call<Account>, response: Response<Account>) {
if (response.body() != null && response.isSuccessful) { if (response.body() != null && response.isSuccessful) {
val account = response.body() as Account val account = response.body() as Account
DBUtils.addUser(db, account) DBUtils.addUser(db, account, domain, accessToken = accessToken)
fillDrawerAccountInfo(account) fillDrawerAccountInfo(account.id)
} }
} }
@ -87,38 +182,72 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
Log.e("DRAWER ACCOUNT:", t.toString()) Log.e("DRAWER ACCOUNT:", t.toString())
} }
}) })
} else {
val userId = preferences.getString("user_id", null).orEmpty()
if (userId.isNotEmpty()) {
val user: UserDatabaseEntity = db.userDao().getUserWithId(userId)
val account = Account(
id = user.user_id,
username = user.username,
display_name = user.display_name,
avatar_static = user.avatar_static
)
fillDrawerAccountInfo(account)
} else {
launchActivity(LoginActivity())
}
} }
} }
private fun fillDrawerAccountInfo(account: Account) { //called when switching profiles, or when clicking on current profile
val drawerAvatar = nav_view.getHeaderView(0).drawer_avatar private fun clickProfile(profile: IProfile, current: Boolean): Boolean {
val drawerAccountName = nav_view.getHeaderView(0).drawer_account_name if(current){
ImageConverter.setRoundImageFromURL( launchActivity(ProfileActivity())
View(applicationContext), return false
account.avatar_static, }
drawerAvatar //Clicked on add new account
) if(profile.identifier == ADD_ACCOUNT_IDENTIFIER){
drawerAvatar.setOnClickListener { launchActivity(ProfileActivity()) } launchActivity(LoginActivity())
// Set account name return false
drawerAccountName.apply { }
text = account.display_name
setOnClickListener { launchActivity(ProfileActivity()) } db.userDao().deActivateActiveUser()
db.userDao().activateUser(profile.identifier.toString())
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
return false
}
private inline fun primaryDrawerItem(block: PrimaryDrawerItem.() -> Unit): PrimaryDrawerItem {
return PrimaryDrawerItem()
.apply {
isSelectable = false
isIconTinted = true
}
.apply(block)
}
private fun fillDrawerAccountInfo(account: String) {
val users = db.userDao().getAll().toMutableList()
users.sortWith(Comparator { l, r ->
when {
l.isActive && !r.isActive -> -1
r.isActive && !l.isActive -> 1
else -> 0
}
})
val profiles: MutableList<IProfile> = users.map { user ->
ProfileDrawerItem().apply {
isSelected = user.isActive
nameText = user.display_name
iconUrl = user.avatar_static
isNameShown = true
identifier = user.user_id.toLong()
descriptionText = "${user.username}@${user.instance_uri.removePrefix("https://")}"
}
}.toMutableList()
// reuse the already existing "add account" item
for (profile in header.profiles.orEmpty()) {
if (profile.identifier == ADD_ACCOUNT_IDENTIFIER) {
profiles.add(profile)
break
} }
} }
header.clear()
header.profiles = profiles
header.setActiveProfile(account.toLong())
}
private fun setupTabs(tab_array: Array<Fragment>){ private fun setupTabs(tab_array: Array<Fragment>){
view_pager.adapter = object : FragmentStateAdapter(this) { view_pager.adapter = object : FragmentStateAdapter(this) {
@ -141,26 +270,17 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
}.attach() }.attach()
} }
/**
When clicking in the drawer menu, go to the corresponding activity
*/
override fun onNavigationItemSelected(@NonNull item: MenuItem): Boolean {
when (item.itemId){
R.id.nav_account -> launchActivity(ProfileActivity())
R.id.nav_settings -> launchActivity(SettingsActivity())
R.id.nav_logout -> launchActivity(LoginActivity())
}
drawer_layout.closeDrawer(GravityCompat.START)
return true
}
/** /**
Launches the given activity and put it as the current one Launches the given activity and put it as the current one
Setting argument firstTime to true means the task history will be reset (as if the app were launched anew into
this activity)
*/ */
private fun launchActivity(activity: AppCompatActivity) { private fun launchActivity(activity: AppCompatActivity, firstTime: Boolean = false) {
val intent = Intent(this, activity::class.java) val intent = Intent(this, activity::class.java)
if(firstTime){
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
startActivity(intent) startActivity(intent)
} }

View File

@ -1,27 +1,20 @@
package com.h.pixeldroid package com.h.pixeldroid
import android.app.Activity import android.app.Activity
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Bitmap.CompressFormat
import android.graphics.BitmapFactory
import android.graphics.Point import android.graphics.Point
import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.BitmapDrawable
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Log
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
@ -38,11 +31,13 @@ import com.zomato.photofilters.imageprocessors.subfilters.ContrastSubFilter
import com.zomato.photofilters.imageprocessors.subfilters.SaturationSubfilter import com.zomato.photofilters.imageprocessors.subfilters.SaturationSubfilter
import kotlinx.android.synthetic.main.activity_photo_edit.* import kotlinx.android.synthetic.main.activity_photo_edit.*
import kotlinx.android.synthetic.main.content_photo_edit.* import kotlinx.android.synthetic.main.content_photo_edit.*
import java.io.ByteArrayOutputStream
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors.newSingleThreadExecutor
import java.util.concurrent.Future
// This is an arbitrary number we are using to keep track of the permission // This is an arbitrary number we are using to keep track of the permission
// request. Where an app has multiple context for requesting permission, // request. Where an app has multiple context for requesting permission,
@ -88,17 +83,31 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
System.loadLibrary("NativeImageProcessor") System.loadLibrary("NativeImageProcessor")
} }
companion object{
private var executor: ExecutorService = newSingleThreadExecutor()
private var future: Future<*>? = null
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_photo_edit) setContentView(R.layout.activity_photo_edit)
//TODO move to xml:
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
supportActionBar!!.title = "Edit" supportActionBar!!.title = "Edit"
supportActionBar!!.setDisplayHomeAsUpEnabled(true) supportActionBar!!.setDisplayHomeAsUpEnabled(true)
supportActionBar!!.setHomeButtonEnabled(true) supportActionBar!!.setHomeButtonEnabled(true)
val cropButton: FloatingActionButton = findViewById(R.id.cropImageButton)
cropUri = intent.getParcelableExtra("picture_uri") cropUri = intent.getParcelableExtra("picture_uri")
// set on-click listener
cropButton.setOnClickListener {
startCrop()
}
loadImage() loadImage()
val file = File.createTempFile("temp_compressed_img", ".png", cacheDir) val file = File.createTempFile("temp_compressed_img", ".png", cacheDir)
file.writeBitmap(compressedImage!!) file.writeBitmap(compressedImage!!)
@ -109,13 +118,8 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
setupViewPager(viewPager) setupViewPager(viewPager)
tabLayout.setupWithViewPager(viewPager) tabLayout.setupWithViewPager(viewPager)
outputDirectory = getOutputDirectory() outputDirectory = getOutputDirectory()
}
val cropButton: FloatingActionButton = findViewById(R.id.cropImageButton)
// set on-click listener
cropButton.setOnClickListener {
startCrop()
}
}
//<editor-fold desc="ON LAUNCH"> //<editor-fold desc="ON LAUNCH">
private fun loadImage() { private fun loadImage() {
@ -192,49 +196,55 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
contrastFinal = CONTRAST_START contrastFinal = CONTRAST_START
} }
//</editor-fold> //</editor-fold>
//<editor-fold desc="EDITS"> //<editor-fold desc="EDITS">
private fun applyFilterAndShowImage(filter: Filter, image: Bitmap?) { private fun applyFilterAndShowImage(filter: Filter, image: Bitmap?) {
image_preview.setImageBitmap(filter.processFilter(image!!.copy(BITMAP_CONFIG, true))) future?.cancel(true)
future = executor.submit {
val bitmap = filter.processFilter(image!!.copy(BITMAP_CONFIG, true))
image_preview.post {
image_preview.setImageBitmap(bitmap)
}
}
} }
override fun onBrightnessChange(brightness: Int) { override fun onBrightnessChange(brightness: Int) {
brightnessFinal = brightness brightnessFinal = brightness
val myFilter = Filter() val myFilter = Filter()
myFilter.addSubFilter(BrightnessSubFilter(brightness)) myFilter.addEditFilters(brightness, saturationFinal, contrastFinal)
applyFilterAndShowImage(myFilter, filteredImage) applyFilterAndShowImage(myFilter, filteredImage)
} }
override fun onSaturationChange(saturation: Float) { override fun onSaturationChange(saturation: Float) {
saturationFinal = saturation saturationFinal = saturation
val myFilter = Filter() val myFilter = Filter()
myFilter.addSubFilter(SaturationSubfilter(saturation)) myFilter.addEditFilters(brightnessFinal, saturation, contrastFinal)
applyFilterAndShowImage(myFilter, filteredImage) applyFilterAndShowImage(myFilter, filteredImage)
} }
override fun onContrastChange(contrast: Float) { override fun onContrastChange(contrast: Float) {
contrastFinal = contrast contrastFinal = contrast
val myFilter = Filter() val myFilter = Filter()
myFilter.addSubFilter(ContrastSubFilter(contrast)) myFilter.addEditFilters(brightnessFinal, saturationFinal, contrast)
applyFilterAndShowImage(myFilter, filteredImage) applyFilterAndShowImage(myFilter, filteredImage)
} }
private fun addEditFilters(filter: Filter, br: Int, sa: Float, co: Float): Filter { private fun Filter.addEditFilters(br: Int, sa: Float, co: Float): Filter {
filter.addSubFilter(BrightnessSubFilter(br)) addSubFilter(BrightnessSubFilter(br))
filter.addSubFilter(ContrastSubFilter(co)) addSubFilter(ContrastSubFilter(co))
filter.addSubFilter(SaturationSubfilter(sa)) addSubFilter(SaturationSubfilter(sa))
return this
return filter
} }
override fun onEditStarted() { override fun onEditStarted() {
} }
override fun onEditCompleted() { override fun onEditCompleted() {
val bitmap = filteredImage.copy(BITMAP_CONFIG, true)
val myFilter = Filter() val myFilter = Filter()
addEditFilters(myFilter, brightnessFinal, saturationFinal, contrastFinal) myFilter.addEditFilters(brightnessFinal, saturationFinal, contrastFinal)
val bitmap = filteredImage.copy(BITMAP_CONFIG, true)
compressedImage = myFilter.processFilter(bitmap) compressedImage = myFilter.processFilter(bitmap)
} }
@ -268,7 +278,7 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
val newBr = if(brightnessFinal != 0) BRIGHTNESS_START/brightnessFinal else 0 val newBr = if(brightnessFinal != 0) BRIGHTNESS_START/brightnessFinal else 0
val newSa = if(saturationFinal != 0.0f) SATURATION_START/saturationFinal else 0.0f val newSa = if(saturationFinal != 0.0f) SATURATION_START/saturationFinal else 0.0f
val newCo = if(contrastFinal != 0.0f) CONTRAST_START/contrastFinal else 0.0f val newCo = if(contrastFinal != 0.0f) CONTRAST_START/contrastFinal else 0.0f
val myFilter = addEditFilters(Filter(), newBr, newSa, newCo) val myFilter = Filter().addEditFilters(newBr, newSa, newCo)
filteredImage = myFilter.processFilter(filteredImage) filteredImage = myFilter.processFilter(filteredImage)
} }
@ -319,8 +329,7 @@ class PhotoEditActivity : AppCompatActivity(), FilterListFragmentListener, EditI
} }
private fun applyFinalFilters(image: Bitmap?) { private fun applyFinalFilters(image: Bitmap?) {
var editFilter = Filter() val editFilter = Filter().addEditFilters(brightnessFinal, saturationFinal, contrastFinal)
editFilter = addEditFilters(editFilter, brightnessFinal, saturationFinal, contrastFinal)
finalImage = editFilter.processFilter(image!!.copy(BITMAP_CONFIG, true)) finalImage = editFilter.processFilter(image!!.copy(BITMAP_CONFIG, true))
if (actualFilter!=null) finalImage = actualFilter!!.processFilter(finalImage) if (actualFilter!=null) finalImage = actualFilter!!.processFilter(finalImage)

View File

@ -1,8 +1,6 @@
package com.h.pixeldroid package com.h.pixeldroid
import android.Manifest
import android.app.Application import android.app.Application
import android.view.WindowManager
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.h.pixeldroid.utils.ThemeUtils import com.h.pixeldroid.utils.ThemeUtils

View File

@ -1,7 +1,5 @@
package com.h.pixeldroid package com.h.pixeldroid
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View import android.view.View
@ -13,15 +11,16 @@ import com.h.pixeldroid.objects.Status
import com.h.pixeldroid.objects.Status.Companion.DISCOVER_TAG import com.h.pixeldroid.objects.Status.Companion.DISCOVER_TAG
import com.h.pixeldroid.objects.Status.Companion.DOMAIN_TAG import com.h.pixeldroid.objects.Status.Companion.DOMAIN_TAG
import com.h.pixeldroid.objects.Status.Companion.POST_TAG import com.h.pixeldroid.objects.Status.Companion.POST_TAG
import com.h.pixeldroid.utils.DBUtils
import kotlinx.android.synthetic.main.activity_post.* import kotlinx.android.synthetic.main.activity_post.*
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
class PostActivity : AppCompatActivity() { class PostActivity : AppCompatActivity() {
private lateinit var preferences: SharedPreferences
private lateinit var postFragment : PostFragment private lateinit var postFragment : PostFragment
lateinit var domain : String lateinit var domain : String
private lateinit var accessToken : String
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -29,11 +28,13 @@ class PostActivity : AppCompatActivity() {
val status = intent.getSerializableExtra(POST_TAG) as Status? val status = intent.getSerializableExtra(POST_TAG) as Status?
val discoverPost: DiscoverPost? = intent.getSerializableExtra(DISCOVER_TAG) as DiscoverPost? val discoverPost: DiscoverPost? = intent.getSerializableExtra(DISCOVER_TAG) as DiscoverPost?
val db = DBUtils.initDB(applicationContext)
preferences = getSharedPreferences( val user = db.userDao().getActiveUser()
"${BuildConfig.APPLICATION_ID}.pref", Context.MODE_PRIVATE
) domain = user?.instance_uri.orEmpty()
domain = preferences.getString("domain", "")!! accessToken = user?.accessToken.orEmpty()
db.close()
postFragment = PostFragment() postFragment = PostFragment()
val arguments = Bundle() val arguments = Bundle()
@ -52,7 +53,6 @@ class PostActivity : AppCompatActivity() {
discoverPost: DiscoverPost discoverPost: DiscoverPost
) { ) {
val api = PixelfedAPI.create(domain) val api = PixelfedAPI.create(domain)
val accessToken = preferences.getString("accessToken", "") ?: ""
val id = discoverPost.url?.substringAfterLast('/') ?: "" val id = discoverPost.url?.substringAfterLast('/') ?: ""
api.getStatus("Bearer $accessToken", id).enqueue(object : Callback<Status> { api.getStatus("Bearer $accessToken", id).enqueue(object : Callback<Status> {

View File

@ -1,8 +1,6 @@
package com.h.pixeldroid package com.h.pixeldroid
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.net.Uri import android.net.Uri
@ -16,8 +14,11 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.net.toUri import androidx.core.net.toUri
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.h.pixeldroid.api.PixelfedAPI import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.objects.Attachment import com.h.pixeldroid.objects.Attachment
import com.h.pixeldroid.objects.Instance
import com.h.pixeldroid.objects.Status import com.h.pixeldroid.objects.Status
import com.h.pixeldroid.utils.DBUtils
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.RequestBody import okhttp3.RequestBody
@ -38,9 +39,11 @@ class PostCreationActivity : AppCompatActivity() {
private lateinit var accessToken: String private lateinit var accessToken: String
private lateinit var pixelfedAPI: PixelfedAPI private lateinit var pixelfedAPI: PixelfedAPI
private lateinit var preferences: SharedPreferences
private lateinit var pictureFrame: ImageView private lateinit var pictureFrame: ImageView
private lateinit var image: File private lateinit var image: File
private var user: UserDatabaseEntity? = null
private var maxLength: Int = Instance.DEFAULT_MAX_TOOT_CHARS
private var description: String = "" private var description: String = ""
@ -55,11 +58,24 @@ class PostCreationActivity : AppCompatActivity() {
pictureFrame = findViewById(R.id.post_creation_picture_frame) pictureFrame = findViewById(R.id.post_creation_picture_frame)
pictureFrame.setImageURI(image.toUri()) pictureFrame.setImageURI(image.toUri())
preferences = getSharedPreferences( val db = DBUtils.initDB(applicationContext)
"${BuildConfig.APPLICATION_ID}.pref", Context.MODE_PRIVATE user = db.userDao().getActiveUser()
)
pixelfedAPI = PixelfedAPI.create("${preferences.getString("domain", "")}") val instances = db.instanceDao().getAll()
accessToken = preferences.getString("accessToken", "")!! db.close()
maxLength = if (user!=null){
val thisInstances =
instances.filter { instanceDatabaseEntity ->
instanceDatabaseEntity.uri.contains(user!!.instance_uri)
}
thisInstances.first().max_toot_chars
} else {
Instance.DEFAULT_MAX_TOOT_CHARS
}
val domain = user?.instance_uri.orEmpty()
accessToken = user?.accessToken.orEmpty()
pixelfedAPI = PixelfedAPI.create(domain)
// check if the picture is alright // check if the picture is alright
// TODO // TODO
@ -99,7 +115,6 @@ class PostCreationActivity : AppCompatActivity() {
private fun setDescription(): Boolean { private fun setDescription(): Boolean {
val textField = findViewById<TextInputEditText>(R.id.new_post_description_input_field) val textField = findViewById<TextInputEditText>(R.id.new_post_description_input_field)
val content = textField.text.toString() val content = textField.text.toString()
val maxLength = preferences.getInt("max_toot_chars", 500)
if (content.length > maxLength) { if (content.length > maxLength) {
// error, too much characters // error, too much characters
textField.error = "Description must contain $maxLength characters at most." textField.error = "Description must contain $maxLength characters at most."

View File

@ -1,8 +1,6 @@
package com.h.pixeldroid package com.h.pixeldroid
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Typeface import android.graphics.Typeface
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
@ -16,33 +14,38 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.adapters.ProfilePostsRecyclerViewAdapter import com.h.pixeldroid.adapters.ProfilePostsRecyclerViewAdapter
import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.objects.Account import com.h.pixeldroid.objects.Account
import com.h.pixeldroid.objects.Account.Companion.ACCOUNT_TAG import com.h.pixeldroid.objects.Account.Companion.ACCOUNT_TAG
import com.h.pixeldroid.objects.Relationship import com.h.pixeldroid.objects.Relationship
import com.h.pixeldroid.objects.Status import com.h.pixeldroid.objects.Status
import com.h.pixeldroid.utils.DBUtils
import com.h.pixeldroid.utils.ImageConverter import com.h.pixeldroid.utils.ImageConverter
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
class ProfileActivity : AppCompatActivity() { class ProfileActivity : AppCompatActivity() {
private lateinit var preferences : SharedPreferences
private lateinit var pixelfedAPI : PixelfedAPI private lateinit var pixelfedAPI : PixelfedAPI
private lateinit var adapter : ProfilePostsRecyclerViewAdapter private lateinit var adapter : ProfilePostsRecyclerViewAdapter
private lateinit var recycler : RecyclerView private lateinit var recycler : RecyclerView
private var accessToken : String? = null private lateinit var accessToken : String
private lateinit var domain : String
private var account: Account? = null private var account: Account? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile) setContentView(R.layout.activity_profile)
preferences = this.getSharedPreferences( val db = DBUtils.initDB(applicationContext)
"${BuildConfig.APPLICATION_ID}.pref", Context.MODE_PRIVATE)
pixelfedAPI = PixelfedAPI.create("${preferences.getString("domain", "")}") val user = db.userDao().getActiveUser()
accessToken = preferences.getString("accessToken", "")
domain = user?.instance_uri.orEmpty()
pixelfedAPI = PixelfedAPI.create(domain)
accessToken = user?.accessToken.orEmpty()
db.close()
// Set posts RecyclerView as a grid with 3 columns // Set posts RecyclerView as a grid with 3 columns
recycler = findViewById(R.id.profilePostsRecyclerView) recycler = findViewById(R.id.profilePostsRecyclerView)
@ -139,7 +142,7 @@ class ProfileActivity : AppCompatActivity() {
} }
private fun onClickEditButton() { private fun onClickEditButton() {
val url = "${preferences.getString("domain", "")}/settings/home" val url = "$domain/settings/home"
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
if(browserIntent.resolveActivity(packageManager) != null) { if(browserIntent.resolveActivity(packageManager) != null) {

View File

@ -2,7 +2,6 @@ package com.h.pixeldroid
import android.app.SearchManager import android.app.SearchManager
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
@ -17,7 +16,6 @@ import com.h.pixeldroid.fragments.feeds.search.SearchPostsFragment
import com.h.pixeldroid.objects.Results import com.h.pixeldroid.objects.Results
class SearchActivity : AppCompatActivity() { class SearchActivity : AppCompatActivity() {
private lateinit var preferences: SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -26,11 +24,15 @@ class SearchActivity : AppCompatActivity() {
var query = intent.getSerializableExtra("searchFeed") as String var query = intent.getSerializableExtra("searchFeed") as String
query = query.trim() query = query.trim()
val searchType = if (query.startsWith("#")){ val searchType = when {
query.startsWith("#") -> {
Results.SearchType.hashtags Results.SearchType.hashtags
} else if(query.startsWith("@")){ }
query.startsWith("@") -> {
Results.SearchType.accounts Results.SearchType.accounts
} else Results.SearchType.statuses }
else -> Results.SearchType.statuses
}
if(searchType != Results.SearchType.statuses) query = query.drop(1) if(searchType != Results.SearchType.statuses) query = query.drop(1)

View File

@ -3,9 +3,7 @@ package com.h.pixeldroid
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.h.pixeldroid.utils.ThemeUtils.Companion.setThemeFromPreferences import com.h.pixeldroid.utils.ThemeUtils.Companion.setThemeFromPreferences

View File

@ -5,7 +5,7 @@ import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter import androidx.fragment.app.FragmentPagerAdapter
class EditPhotoViewPagerAdapter (manager: FragmentManager): class EditPhotoViewPagerAdapter (manager: FragmentManager):
FragmentPagerAdapter(manager, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { FragmentPagerAdapter(manager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
private val fragmentList = ArrayList<Fragment>() private val fragmentList = ArrayList<Fragment>()
private val fragmentTitleList = ArrayList<String>() private val fragmentTitleList = ArrayList<String>()

View File

@ -12,8 +12,7 @@ import com.h.pixeldroid.objects.Status
import com.h.pixeldroid.utils.ImageConverter.Companion.setSquareImageFromURL import com.h.pixeldroid.utils.ImageConverter.Companion.setSquareImageFromURL
/** /**
* [RecyclerView.Adapter] that can display a list of [PostMiniature]s and makes a call to the * [RecyclerView.Adapter] that can display a list of [Status]s
* specified [OnListFragmentInteractionListener].
*/ */
class ProfilePostsRecyclerViewAdapter: RecyclerView.Adapter<ProfilePostsRecyclerViewAdapter.ViewHolder>() { class ProfilePostsRecyclerViewAdapter: RecyclerView.Adapter<ProfilePostsRecyclerViewAdapter.ViewHolder>() {
private val posts: ArrayList<Status> = ArrayList() private val posts: ArrayList<Status> = ArrayList()

View File

@ -46,12 +46,7 @@ class ThumbnailAdapter (private val context: Context,
} }
class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) { class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
var thumbnail: ImageView var thumbnail: ImageView = itemView.thumbnail
var filterName: TextView var filterName: TextView = itemView.filter_name
init {
thumbnail = itemView.thumbnail
filterName = itemView.filter_name
}
} }
} }

View File

@ -13,9 +13,18 @@ interface UserDao {
@Query("SELECT * FROM users") @Query("SELECT * FROM users")
fun getAll(): List<UserDatabaseEntity> fun getAll(): List<UserDatabaseEntity>
@Query("SELECT * FROM users WHERE isActive=1 LIMIT 1")
fun getActiveUser(): UserDatabaseEntity?
@Query("UPDATE users SET isActive=0 WHERE isActive=1")
fun deActivateActiveUser()
@Query("UPDATE users SET isActive=1 WHERE user_id=:id")
fun activateUser(id: String)
@Query("DELETE FROM users WHERE isActive=1")
fun deleteActiveUsers()
@Query("SELECT * FROM users WHERE user_id=:id LIMIT 1") @Query("SELECT * FROM users WHERE user_id=:id LIMIT 1")
fun getUserWithId(id: String): UserDatabaseEntity fun getUserWithId(id: String): UserDatabaseEntity
@Query("UPDATE users SET username = :username, display_name = :display_name, avatar_static = :avatar_static WHERE user_id=:user_id")
fun updateUser(user_id: String, username: String, display_name: String, avatar_static: String)
} }

View File

@ -19,5 +19,7 @@ data class UserDatabaseEntity (
var instance_uri: String, var instance_uri: String,
var username: String, var username: String,
var display_name: String, var display_name: String,
var avatar_static: String var avatar_static: String,
var isActive: Boolean,
var accessToken: String
) )

View File

@ -8,7 +8,6 @@ import android.content.pm.PackageManager
import android.content.res.Configuration import android.content.res.Configuration
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.hardware.display.DisplayManager
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.provider.MediaStore import android.provider.MediaStore
@ -31,13 +30,10 @@ import androidx.lifecycle.lifecycleScope
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import com.h.pixeldroid.PhotoEditActivity import com.h.pixeldroid.PhotoEditActivity
import com.h.pixeldroid.PostCreationActivity
import com.h.pixeldroid.R import com.h.pixeldroid.R
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.ExecutorService import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.math.abs import kotlin.math.abs
@ -70,10 +66,6 @@ class CameraFragment : Fragment() {
private var imageCapture: ImageCapture? = null private var imageCapture: ImageCapture? = null
private var camera: Camera? = null private var camera: Camera? = null
private val displayManager by lazy {
requireContext().getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
}
/** Blocking camera operations are performed using this executor */ /** Blocking camera operations are performed using this executor */
private lateinit var cameraExecutor: ExecutorService private lateinit var cameraExecutor: ExecutorService
@ -276,7 +268,7 @@ class CameraFragment : Fragment() {
if (cursor != null && cursor.moveToFirst()) { if (cursor != null && cursor.moveToFirst()) {
val uri = Uri.parse(cursor.getString(1)).path ?: "" val uri = Uri.parse(cursor.getString(1)).path ?: ""
setGalleryThumbnail(uri) setGalleryThumbnail(uri)
cursor.close(); cursor.close()
} }
} }

View File

@ -53,15 +53,12 @@ class FilterListFragment : Fragment(), FilterListFragmentListener {
fun displayImage(bitmap: Bitmap?) { fun displayImage(bitmap: Bitmap?) {
val r = Runnable { val r = Runnable {
val tbImage: Bitmap? val tbImage: Bitmap = (if (bitmap == null) {
if (bitmap == null) { MediaStore.Images.Media.getBitmap(requireActivity().contentResolver, PhotoEditActivity.URI.picture_uri)
tbImage = MediaStore.Images.Media.getBitmap(requireActivity().contentResolver, PhotoEditActivity.URI.picture_uri)
} else { } else {
tbImage = Bitmap.createScaledBitmap(bitmap, 100, 100, false) Bitmap.createScaledBitmap(bitmap, 100, 100, false)
} })
?: return@Runnable
if (tbImage == null)
return@Runnable
setupFilter(tbImage) setupFilter(tbImage)

View File

@ -1,6 +1,5 @@
package com.h.pixeldroid.fragments package com.h.pixeldroid.fragments
import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
@ -9,13 +8,13 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.h.pixeldroid.BuildConfig
import com.h.pixeldroid.R import com.h.pixeldroid.R
import com.h.pixeldroid.api.PixelfedAPI import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.fragments.feeds.PostViewHolder import com.h.pixeldroid.fragments.feeds.PostViewHolder
import com.h.pixeldroid.objects.Status import com.h.pixeldroid.objects.Status
import com.h.pixeldroid.objects.Status.Companion.DOMAIN_TAG import com.h.pixeldroid.objects.Status.Companion.DOMAIN_TAG
import com.h.pixeldroid.objects.Status.Companion.POST_TAG import com.h.pixeldroid.objects.Status.Companion.POST_TAG
import com.h.pixeldroid.utils.DBUtils
class PostFragment : Fragment() { class PostFragment : Fragment() {
@ -25,28 +24,29 @@ class PostFragment : Fragment() {
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
val current_status = arguments?.getSerializable(POST_TAG) as Status? val current_status = arguments?.getSerializable(POST_TAG) as Status?
val domain = arguments?.getString(DOMAIN_TAG)!! val statusDomain = arguments?.getString(DOMAIN_TAG)!!
val root: View = inflater.inflate(R.layout.post_fragment, container, false) val root: View = inflater.inflate(R.layout.post_fragment, container, false)
val picRequest = Glide.with(this) val picRequest = Glide.with(this)
.asDrawable().fitCenter() .asDrawable().fitCenter()
.placeholder(ColorDrawable(Color.GRAY)) .placeholder(ColorDrawable(Color.GRAY))
current_status?.setupPost(root, picRequest, this, domain, true) current_status?.setupPost(root, picRequest, this, statusDomain, true)
//Setup arguments needed for the onclicklisteners //Setup arguments needed for the onclicklisteners
val holder = PostViewHolder(root, requireContext()) val holder = PostViewHolder(root, requireContext())
val db = DBUtils.initDB(requireContext())
val preferences = requireActivity().getSharedPreferences( val user = db.userDao().getActiveUser()
"${BuildConfig.APPLICATION_ID}.pref", Context.MODE_PRIVATE
) val domain = user?.instance_uri.orEmpty()
val accessToken = preferences.getString("accessToken", "") val accessToken = user?.accessToken.orEmpty()
val api = PixelfedAPI.create("${preferences.getString("domain", "")}") val api = PixelfedAPI.create(domain)
current_status?.setDescription(root, api, "Bearer $accessToken") current_status?.setDescription(root, api, "Bearer $accessToken")
//Activate onclickListeners //Activate onclickListeners
current_status?.activateLiker(holder, api, "Bearer $accessToken", current_status!!.favourited) current_status?.activateLiker(holder, api, "Bearer $accessToken", current_status.favourited)
current_status?.activateReblogger(holder, api, "Bearer $accessToken", current_status!!.reblogged) current_status?.activateReblogger(holder, api, "Bearer $accessToken", current_status.reblogged)
current_status?.activateCommenter(holder, api, "Bearer $accessToken") current_status?.activateCommenter(holder, api, "Bearer $accessToken")
current_status?.showComments(holder, api, "Bearer $accessToken") current_status?.showComments(holder, api, "Bearer $accessToken")

View File

@ -1,7 +1,5 @@
package com.h.pixeldroid.fragments package com.h.pixeldroid.fragments
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -10,21 +8,14 @@ import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.h.pixeldroid.BuildConfig
import com.h.pixeldroid.R import com.h.pixeldroid.R
import com.h.pixeldroid.adapters.ProfilePostsRecyclerViewAdapter import com.h.pixeldroid.adapters.ProfilePostsRecyclerViewAdapter
import com.h.pixeldroid.api.PixelfedAPI
/** /**
* A fragment representing a list of Items. * A fragment representing a list of statuses of a profile.
* Activities containing this fragment MUST implement the
* [ProfilePostsFragment.OnListFragmentInteractionListener] interface.
*/ */
class ProfilePostsFragment : Fragment() { class ProfilePostsFragment : Fragment() {
private lateinit var preferences: SharedPreferences
private lateinit var pixelfedAPI: PixelfedAPI
private var accessToken: String? = null
private var columnCount = 3 private var columnCount = 3
@ -33,11 +24,7 @@ class ProfilePostsFragment : Fragment() {
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
val view = inflater.inflate(R.layout.fragment_profile_posts_list, container, false) val view = inflater.inflate(R.layout.fragment_profile_posts_list, container, false)
preferences = requireActivity().getSharedPreferences(
"${BuildConfig.APPLICATION_ID}.pref", Context.MODE_PRIVATE
)
pixelfedAPI = PixelfedAPI.create("${preferences.getString("domain", "")}")
accessToken = preferences.getString("accessToken", "")
// Set the adapter // Set the adapter
if (view is RecyclerView) { if (view is RecyclerView) {

View File

@ -1,8 +1,6 @@
package com.h.pixeldroid.fragments package com.h.pixeldroid.fragments
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
@ -16,7 +14,6 @@ import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.h.pixeldroid.BuildConfig
import com.h.pixeldroid.PostActivity import com.h.pixeldroid.PostActivity
import com.h.pixeldroid.R import com.h.pixeldroid.R
import com.h.pixeldroid.SearchActivity import com.h.pixeldroid.SearchActivity
@ -24,6 +21,7 @@ import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.objects.DiscoverPost import com.h.pixeldroid.objects.DiscoverPost
import com.h.pixeldroid.objects.DiscoverPosts import com.h.pixeldroid.objects.DiscoverPosts
import com.h.pixeldroid.objects.Status import com.h.pixeldroid.objects.Status
import com.h.pixeldroid.utils.DBUtils
import com.h.pixeldroid.utils.ImageConverter import com.h.pixeldroid.utils.ImageConverter
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
@ -35,7 +33,6 @@ import retrofit2.Response
class SearchDiscoverFragment : Fragment() { class SearchDiscoverFragment : Fragment() {
private lateinit var api: PixelfedAPI private lateinit var api: PixelfedAPI
private lateinit var preferences: SharedPreferences
private lateinit var recycler : RecyclerView private lateinit var recycler : RecyclerView
private lateinit var adapter : DiscoverRecyclerViewAdapter private lateinit var adapter : DiscoverRecyclerViewAdapter
private lateinit var accessToken: String private lateinit var accessToken: String
@ -43,7 +40,6 @@ class SearchDiscoverFragment : Fragment() {
private lateinit var discoverRefreshLayout: SwipeRefreshLayout private lateinit var discoverRefreshLayout: SwipeRefreshLayout
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
@ -67,11 +63,14 @@ class SearchDiscoverFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
preferences = requireActivity().getSharedPreferences(
"${BuildConfig.APPLICATION_ID}.pref", Context.MODE_PRIVATE val db = DBUtils.initDB(requireContext())
)
api = PixelfedAPI.create("${preferences.getString("domain", "")}") val user = db.userDao().getActiveUser()
accessToken = preferences.getString("accessToken", "") ?: ""
val domain = user?.instance_uri.orEmpty()
api = PixelfedAPI.create(domain)
accessToken = user?.accessToken.orEmpty()
discoverProgressBar = view.findViewById(R.id.discoverProgressBar) discoverProgressBar = view.findViewById(R.id.discoverProgressBar)
discoverRefreshLayout = view.findViewById(R.id.discoverRefreshLayout) discoverRefreshLayout = view.findViewById(R.id.discoverRefreshLayout)

View File

@ -1,7 +1,6 @@
package com.h.pixeldroid.fragments.feeds package com.h.pixeldroid.fragments.feeds
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
@ -20,10 +19,12 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.h.pixeldroid.BuildConfig
import com.h.pixeldroid.R import com.h.pixeldroid.R
import com.h.pixeldroid.api.PixelfedAPI import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.objects.FeedContent import com.h.pixeldroid.objects.FeedContent
import com.h.pixeldroid.utils.DBUtils
import kotlinx.android.synthetic.main.fragment_feed.view.* import kotlinx.android.synthetic.main.fragment_feed.view.*
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
@ -36,12 +37,15 @@ open class FeedFragment<T: FeedContent, VH: RecyclerView.ViewHolder?>: Fragment(
protected var accessToken: String? = null protected var accessToken: String? = null
protected lateinit var pixelfedAPI: PixelfedAPI protected lateinit var pixelfedAPI: PixelfedAPI
protected lateinit var preferences: SharedPreferences
protected lateinit var list : RecyclerView protected lateinit var list : RecyclerView
protected lateinit var adapter : FeedsRecyclerViewAdapter<T, VH> protected lateinit var adapter : FeedsRecyclerViewAdapter<T, VH>
protected lateinit var swipeRefreshLayout: SwipeRefreshLayout protected lateinit var swipeRefreshLayout: SwipeRefreshLayout
internal lateinit var loadingIndicator: ProgressBar internal lateinit var loadingIndicator: ProgressBar
private var user: UserDatabaseEntity? = null
private lateinit var db: AppDatabase
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -54,12 +58,11 @@ open class FeedFragment<T: FeedContent, VH: RecyclerView.ViewHolder?>: Fragment(
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout) swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout)
loadingIndicator = view.findViewById(R.id.progressBar) loadingIndicator = view.findViewById(R.id.progressBar)
list = swipeRefreshLayout.list list = swipeRefreshLayout.list
preferences = requireActivity().getSharedPreferences(
"${BuildConfig.APPLICATION_ID}.pref", Context.MODE_PRIVATE
)
list.layoutManager = LinearLayoutManager(context) list.layoutManager = LinearLayoutManager(context)
pixelfedAPI = PixelfedAPI.create("${preferences.getString("domain", "")}") db = DBUtils.initDB(requireContext())
accessToken = preferences.getString("accessToken", "") user = db.userDao().getActiveUser()
pixelfedAPI = PixelfedAPI.create(user?.instance_uri.orEmpty())
accessToken = user?.accessToken.orEmpty()
return view return view
} }

View File

@ -9,7 +9,6 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import android.widget.Toast
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.paging.LivePagedListBuilder import androidx.paging.LivePagedListBuilder
@ -81,7 +80,7 @@ class NotificationsFragment : FeedFragment<Notification, NotificationsFragment.N
private fun makeContent(): LiveData<PagedList<Notification>> { private fun makeContent(): LiveData<PagedList<Notification>> {
fun makeInitialCall(requestedLoadSize: Int): Call<List<Notification>> { fun makeInitialCall(requestedLoadSize: Int): Call<List<Notification>> {
return pixelfedAPI return pixelfedAPI
.notifications("Bearer $accessToken", min_id="1", limit="$requestedLoadSize") .notifications("Bearer $accessToken", limit="$requestedLoadSize")
} }
fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Notification>> { fun makeAfterCall(requestedLoadSize: Int, key: String): Call<List<Notification>> {
return pixelfedAPI return pixelfedAPI

View File

@ -20,20 +20,26 @@ import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
import com.bumptech.glide.util.ViewPreloadSizeProvider import com.bumptech.glide.util.ViewPreloadSizeProvider
import com.h.pixeldroid.R import com.h.pixeldroid.R
import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.objects.Status import com.h.pixeldroid.objects.Status
import com.h.pixeldroid.utils.DBUtils
import retrofit2.Call import retrofit2.Call
open class PostsFeedFragment : FeedFragment<Status, PostViewHolder>() { open class PostsFeedFragment : FeedFragment<Status, PostViewHolder>() {
lateinit var picRequest: RequestBuilder<Drawable> lateinit var picRequest: RequestBuilder<Drawable>
lateinit var domain : String lateinit var domain : String
private var user: UserDatabaseEntity? = null
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
val view = super.onCreateView(inflater, container, savedInstanceState) val view = super.onCreateView(inflater, container, savedInstanceState)
domain = preferences.getString("domain", "")!! val db = DBUtils.initDB(requireContext())
user = db.userDao().getActiveUser()
domain = user?.instance_uri.orEmpty()
//RequestBuilder that is re-used for every image //RequestBuilder that is re-used for every image
picRequest = Glide.with(this) picRequest = Glide.with(this)
.asDrawable().fitCenter() .asDrawable().fitCenter()

View File

@ -6,7 +6,6 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
@ -14,21 +13,11 @@ import androidx.lifecycle.Observer
import androidx.paging.LivePagedListBuilder import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList import androidx.paging.PagedList
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.ListPreloader
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
import com.bumptech.glide.util.ViewPreloadSizeProvider
import com.h.pixeldroid.R import com.h.pixeldroid.R
import com.h.pixeldroid.fragments.feeds.AccountListFragment
import com.h.pixeldroid.fragments.feeds.FeedFragment import com.h.pixeldroid.fragments.feeds.FeedFragment
import com.h.pixeldroid.fragments.feeds.FeedsRecyclerViewAdapter import com.h.pixeldroid.fragments.feeds.FeedsRecyclerViewAdapter
import com.h.pixeldroid.fragments.feeds.NotificationsFragment
import com.h.pixeldroid.objects.Account
import com.h.pixeldroid.objects.Notification
import com.h.pixeldroid.objects.Results import com.h.pixeldroid.objects.Results
import com.h.pixeldroid.objects.Tag import com.h.pixeldroid.objects.Tag
import kotlinx.android.synthetic.main.account_list_entry.view.*
import kotlinx.android.synthetic.main.fragment_tags.view.* import kotlinx.android.synthetic.main.fragment_tags.view.*
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback

View File

@ -5,7 +5,6 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.paging.LivePagedListBuilder import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList import androidx.paging.PagedList

View File

@ -7,25 +7,19 @@ import android.graphics.Typeface
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.text.Spanned import android.text.Spanned
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.util.Log
import android.view.View import android.view.View
import android.view.View.GONE import android.view.View.GONE
import android.view.View.VISIBLE import android.view.View.VISIBLE
import android.widget.*
import androidx.core.text.toSpanned import androidx.core.text.toSpanned
import android.widget.TextView
import android.widget.LinearLayout
import android.widget.Toast
import android.widget.PopupMenu
import android.widget.ImageView
import android.widget.FrameLayout
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.adapter.FragmentStateAdapter
import com.bumptech.glide.RequestBuilder import com.bumptech.glide.RequestBuilder
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
import com.h.pixeldroid.fragments.ImageFragment
import com.h.pixeldroid.R import com.h.pixeldroid.R
import com.h.pixeldroid.api.PixelfedAPI import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.fragments.ImageFragment
import com.h.pixeldroid.fragments.feeds.PostViewHolder import com.h.pixeldroid.fragments.feeds.PostViewHolder
import com.h.pixeldroid.utils.HtmlUtils.Companion.getDomain import com.h.pixeldroid.utils.HtmlUtils.Companion.getDomain
import com.h.pixeldroid.utils.HtmlUtils.Companion.parseHTMLText import com.h.pixeldroid.utils.HtmlUtils.Companion.parseHTMLText
@ -45,12 +39,10 @@ import com.karumi.dexter.listener.PermissionDeniedResponse
import com.karumi.dexter.listener.PermissionGrantedResponse import com.karumi.dexter.listener.PermissionGrantedResponse
import com.karumi.dexter.listener.single.BasePermissionListener import com.karumi.dexter.listener.single.BasePermissionListener
import kotlinx.android.synthetic.main.post_fragment.view.* import kotlinx.android.synthetic.main.post_fragment.view.*
import kotlinx.android.synthetic.main.post_fragment.view.postDate
import kotlinx.android.synthetic.main.post_fragment.view.postDomain
import java.io.Serializable import java.io.Serializable
import java.text.ParseException import java.text.ParseException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
/* /*
@ -96,9 +88,7 @@ data class Status(
{ {
companion object { companion object {
const val SAVE_TO_GALLERY_WRITE_PERMISSION = 1
const val POST_TAG = "postTag" const val POST_TAG = "postTag"
const val POST_FRAG_TAG = "postFragTag"
const val DOMAIN_TAG = "domainTag" const val DOMAIN_TAG = "domainTag"
const val DISCOVER_TAG = "discoverTag" const val DISCOVER_TAG = "discoverTag"
} }
@ -270,7 +260,7 @@ data class Status(
//Set comment initial visibility //Set comment initial visibility
rootView.findViewById<LinearLayout>(R.id.commentIn).visibility = View.GONE rootView.findViewById<LinearLayout>(R.id.commentIn).visibility = GONE
} }
fun setDescription(rootView: View, api : PixelfedAPI, credential: String) { fun setDescription(rootView: View, api : PixelfedAPI, credential: String) {
@ -295,13 +285,11 @@ data class Status(
//Activate the button //Activate the button
setEventListener { _, buttonState -> setEventListener { _, buttonState ->
if (buttonState) { if (buttonState) {
Log.e("REBLOG", "Reblogged post")
// Button is active // Button is active
reblogPost(holder, api, credential, this@Status)
} else {
Log.e("REBLOG", "Undo Reblogged post")
// Button is inactive
undoReblogPost(holder, api, credential, this@Status) undoReblogPost(holder, api, credential, this@Status)
} else {
// Button is inactive
reblogPost(holder, api, credential, this@Status)
} }
//show animation or not? //show animation or not?
true true
@ -323,11 +311,11 @@ data class Status(
//Activate the liker //Activate the liker
setEventListener { _, buttonState -> setEventListener { _, buttonState ->
if (buttonState) { if (buttonState) {
// Button is active // Button is active, unlike
likePostCall(holder, api, credential, this@Status)
} else {
// Button is inactive
unLikePostCall(holder, api, credential, this@Status) unLikePostCall(holder, api, credential, this@Status)
} else {
// Button is inactive, like
likePostCall(holder, api, credential, this@Status)
} }
//show animation or not? //show animation or not?
true true

View File

@ -3,8 +3,11 @@ package com.h.pixeldroid.utils
import android.content.Context import android.content.Context
import androidx.room.Room import androidx.room.Room
import com.h.pixeldroid.db.AppDatabase import com.h.pixeldroid.db.AppDatabase
import com.h.pixeldroid.db.InstanceDatabaseEntity
import com.h.pixeldroid.db.UserDatabaseEntity import com.h.pixeldroid.db.UserDatabaseEntity
import com.h.pixeldroid.objects.Account import com.h.pixeldroid.objects.Account
import com.h.pixeldroid.objects.Instance
import com.h.pixeldroid.utils.Utils.Companion.normalizeDomain
class DBUtils { class DBUtils {
companion object { companion object {
@ -14,26 +17,39 @@ class DBUtils {
AppDatabase::class.java, "pixeldroid" AppDatabase::class.java, "pixeldroid"
).allowMainThreadQueries().build() ).allowMainThreadQueries().build()
} }
private fun normalizeOrNot(uri: String): String{
fun addUser(db: AppDatabase, account: Account, instance_uri: String = "") { return if(uri.startsWith("http://localhost")){
if (instance_uri.isEmpty()) { uri
db.userDao().updateUser(
user_id = account.id,
username = account.username,
display_name = account.display_name,
avatar_static = account.avatar_static
)
} else { } else {
normalizeDomain(uri)
}
}
fun addUser(db: AppDatabase, account: Account, instance_uri: String, activeUser: Boolean = true, accessToken: String) {
db.userDao().insertUser( db.userDao().insertUser(
UserDatabaseEntity( UserDatabaseEntity(
user_id = account.id, user_id = account.id,
instance_uri = instance_uri, //make sure not to normalize to https when localhost, to allow testing
instance_uri = normalizeOrNot(instance_uri),
username = account.username, username = account.username,
display_name = account.display_name, display_name = account.display_name,
avatar_static = account.avatar_static avatar_static = account.avatar_static,
isActive = activeUser,
accessToken = accessToken
) )
) )
} }
fun storeInstance(db: AppDatabase, instance: Instance) {
val maxTootChars = instance.max_toot_chars.toInt()
val dbInstance = InstanceDatabaseEntity(
//make sure not to normalize to https when localhost, to allow testing
uri = normalizeOrNot(instance.uri),
title = instance.title,
max_toot_chars = maxTootChars,
thumbnail = instance.thumbnail
)
db.instanceDao().insertInstance(dbInstance)
} }
} }
} }

View File

@ -2,8 +2,6 @@ package com.h.pixeldroid.utils
import android.content.Context import android.content.Context
import android.net.ConnectivityManager import android.net.ConnectivityManager
import androidx.room.Room
import com.h.pixeldroid.db.AppDatabase
class Utils { class Utils {
companion object { companion object {
@ -12,6 +10,13 @@ class Utils {
return cm.activeNetwork != null return cm.activeNetwork != null
} }
fun normalizeDomain(domain: String): String {
return "https://" + domain
.replace("http://", "")
.replace("https://", "")
.trim(Char::isWhitespace)
}
} }
} }

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#000000" />
<item android:state_enabled="false" android:color="#000000" />
<item android:state_focused="true" android:color="#000000" />
<item android:color="#FFFFFF" />
</selector>

View File

@ -1,9 +0,0 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="135"
android:centerColor="#009688"
android:endColor="#00695C"
android:startColor="#4DB6AC"
android:type="linear" />
</shape>

View File

@ -1,9 +0,0 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="135"
android:centerColor="#009688"
android:endColor="#00695C"
android:startColor="#4DB6AC"
android:type="linear" />
</shape>

View File

@ -26,41 +26,6 @@
app:srcCompat="@drawable/ic_fred_phone" app:srcCompat="@drawable/ic_fred_phone"
android:contentDescription="TODO" /> android:contentDescription="TODO" />
<LinearLayout
android:id="@+id/login_activity_instance_chooser_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="60dp"
android:layout_marginBottom="15dp"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:id="@+id/login_activity_instance_chooser_offline_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/you_are_in_offline_mode"
android:textAlignment="center"
android:visibility="gone"/>
<Spinner
android:id="@+id/login_activity_instance_chooser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="15dp"/>
<Button
android:id="@+id/login_activity_instance_chooser_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/colorButtonBg"
android:textColor="@color/colorButtonText"
android:text="@string/enter"/>
</LinearLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/login_activity_instance_input_layout" android:id="@+id/login_activity_instance_input_layout"
android:layout_width="250dp" android:layout_width="250dp"

View File

@ -33,14 +33,11 @@
</LinearLayout> </LinearLayout>
<com.google.android.material.navigation.NavigationView <com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
android:id="@+id/nav_view" android:id="@+id/drawer"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="start" android:layout_gravity="start"
android:fitsSystemWindows="true" android:fitsSystemWindows="true" />
app:headerLayout="@layout/nav_header"
app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout> </androidx.drawerlayout.widget.DrawerLayout>

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".fragments.feeds.PostsFeedFragment">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/feedList"
android:name="com.h.pixeldroid.FeedFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="LinearLayoutManager"
tools:listitem="@layout/post_fragment" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout 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_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

View File

@ -1,36 +0,0 @@
<?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"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
android:background="@drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/drawer_avatar"
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/ic_default_user"
android:contentDescription="TODO" />
<TextView
android:id="@+id/drawer_account_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:text="@string/menu_slideshow"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<TextView
android:id="@+id/drawer_account_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/menu_subtitle" />
</LinearLayout>

View File

@ -68,7 +68,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"></androidx.viewpager2.widget.ViewPager2> app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/postTabs" android:id="@+id/postTabs"
@ -77,7 +77,7 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/postPager" app:layout_constraintTop_toBottomOf="@+id/postPager"
app:tabMode="auto"></com.google.android.material.tabs.TabLayout> app:tabMode="auto" />
<ImageView <ImageView
android:id="@+id/postPicture" android:id="@+id/postPicture"

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu 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"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_account"
android:title="@string/menu_account" />
<item
android:id="@+id/nav_settings"
android:title="@string/menu_settings"
android:icon="@drawable/ic_settings"/>
<item
android:id="@+id/nav_logout"
android:title="@string/logout" />
</group>
</menu>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="menu_slideshow">اسم الحساب</string>
<string name="token_error">خطأ في الحصول على الرمز المميز</string> <string name="token_error">خطأ في الحصول على الرمز المميز</string>
<string name="title_activity_settings2">الإعدادات</string> <string name="title_activity_settings2">الإعدادات</string>
<string name="theme_title">حلة التطبيق</string> <string name="theme_title">حلة التطبيق</string>
@ -10,15 +9,11 @@
<string name="registration_failed">لا يمكن تسجيل التطبيق على هذا الخادم</string> <string name="registration_failed">لا يمكن تسجيل التطبيق على هذا الخادم</string>
<string name="browser_launch_failed">تعذر إطلاق متصفح الويب. هل لديك واحد؟</string> <string name="browser_launch_failed">تعذر إطلاق متصفح الويب. هل لديك واحد؟</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="menu_subtitle">معلومات عن الحساب</string>
<string name="menu_account">ملفي التعريفي</string> <string name="menu_account">ملفي التعريفي</string>
<string name="menu_settings">الإعدادات</string> <string name="menu_settings">الإعدادات</string>
<string name="invalid_domain">اسم النطاق غير صالح</string> <string name="invalid_domain">اسم النطاق غير صالح</string>
<string name="auth_failed">فشلت المصادقة</string> <string name="auth_failed">فشلت المصادقة</string>
<string name="followed_notification">يتابعك %1$s</string> <string name="followed_notification">يتابعك %1$s</string>
<string name="take_a_picture">التقط صورة</string>
<string name="upload_a_picture">حمّل صورة</string>
<string name="or">أو</string>
<string name="description">الوصف…</string> <string name="description">الوصف…</string>
<string name="send">ارسل</string> <string name="send">ارسل</string>
<string name="whats_an_instance">ماذا نعني بمثيل الخادم؟</string> <string name="whats_an_instance">ماذا نعني بمثيل الخادم؟</string>
@ -30,24 +25,17 @@
<string name="image_download_success">تم التنزيل بنجاح</string> <string name="image_download_success">تم التنزيل بنجاح</string>
<string name="switch_camera_button_alt">تبديل الكاميرا</string> <string name="switch_camera_button_alt">تبديل الكاميرا</string>
<string name="gallery_button_alt">المعرض</string> <string name="gallery_button_alt">المعرض</string>
<string name="delete_title">تأكيد</string>
<string name="share_picture">شارِك الصورة…</string> <string name="share_picture">شارِك الصورة…</string>
<string name="NoCommentsToShow">لا توجد تعليقات في هذا المنشور…</string> <string name="NoCommentsToShow">لا توجد تعليقات في هذا المنشور…</string>
<string name="CommentDisplay">لإظهاره…</string> <string name="CommentDisplay">لإظهاره…</string>
<string name="connect_to_pixelfed">لِج إلى PixelFed</string> <string name="connect_to_pixelfed">لِج إلى PixelFed</string>
<string name="login_empty_string_error">لا يجب ترك العنوان فارغًا!</string>
<string name="lbl_brightness">السطوع</string> <string name="lbl_brightness">السطوع</string>
<string name="image_download_failed">فشل التنزيل ، حاول مجددًا مِن فضلك</string> <string name="image_download_failed">فشل التنزيل ، حاول مجددًا مِن فضلك</string>
<string name="liked_notification">أعجِب %1$s بمنشورك</string> <string name="liked_notification">أعجِب %1$s بمنشورك</string>
<string name="create_a_new_post">انشئ منشورًا جديدًا!</string>
<string name="capture_mode_camera">الكاميرا</string>
<string name="domain_of_your_instance">اسم نطاق مثيل خادمك</string> <string name="domain_of_your_instance">اسم نطاق مثيل خادمك</string>
<string name="login_connection_required_once">يجب عليك الاتصال بالأنترنت ولو لمرة واحدة قصد استخدام PixelDroid :(</string> <string name="login_connection_required_once">يجب عليك الاتصال بالأنترنت ولو لمرة واحدة قصد استخدام PixelDroid :(</string>
<string name="enter">أدخل</string>
<string name="attachment_summary_off">تنزيل المرفقات فقط عندما يُطلَب ذلك يدويًا</string>
<string name="capture_button_alt">لقطة شاشة</string> <string name="capture_button_alt">لقطة شاشة</string>
<string name="you_are_in_offline_mode">إنك غير متصل الآن ولكنه لا يزال بإمكانك عرض بعض المحتوى!</string> <string name="you_are_in_offline_mode">إنك غير متصل الآن ولكنه لا يزال بإمكانك عرض بعض المحتوى!</string>
<string name="auth_error_toast_msg">لقد أجاب الخادم بخطأ ، حاول مجددًا!</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / وسائط مخفية <string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / وسائط مخفية
\n (اضعط للعرض)</string> \n (اضعط للعرض)</string>
<string name="lbl_contrast">تباين عالٍ</string> <string name="lbl_contrast">تباين عالٍ</string>

View File

@ -3,7 +3,6 @@
<string name="shared_notification">%1$s ha compartit la teva publicació</string> <string name="shared_notification">%1$s ha compartit la teva publicació</string>
<string name="mention_notification">%1$s t\'ha esmentat</string> <string name="mention_notification">%1$s t\'ha esmentat</string>
<string name="followed_notification">%1$s et segueix</string> <string name="followed_notification">%1$s et segueix</string>
<string name="attachment_summary_off">Baixar fitxers adjunts només quan es sol·liciti manualment</string>
<string name="title_activity_settings2">Configuració</string> <string name="title_activity_settings2">Configuració</string>
<string name="token_error">S\'ha produït un error en obtenir el token</string> <string name="token_error">S\'ha produït un error en obtenir el token</string>
<string name="auth_failed">No s\'ha pogut autenticar</string> <string name="auth_failed">No s\'ha pogut autenticar</string>
@ -12,8 +11,6 @@
<string name="invalid_domain">Domini no vàlid</string> <string name="invalid_domain">Domini no vàlid</string>
<string name="menu_settings">Configuració</string> <string name="menu_settings">Configuració</string>
<string name="menu_account">El meu perfil</string> <string name="menu_account">El meu perfil</string>
<string name="menu_subtitle">Informació del compte</string>
<string name="menu_slideshow">Nom del compte</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="share_picture">Compartir imatge…</string> <string name="share_picture">Compartir imatge…</string>
<string name="image_download_success">La imatge s\'ha descarrega\'t correctament</string> <string name="image_download_success">La imatge s\'ha descarrega\'t correctament</string>
@ -24,10 +21,6 @@
<string name="whats_an_instance">Què és una instancia\?</string> <string name="whats_an_instance">Què és una instancia\?</string>
<string name="send">enviar</string> <string name="send">enviar</string>
<string name="description">Descripció…</string> <string name="description">Descripció…</string>
<string name="or">o</string>
<string name="upload_a_picture">Puja una imatge</string>
<string name="take_a_picture">Fes una foto</string>
<string name="create_a_new_post">Crea una nova publicació!</string>
<string name="liked_notification">%1$s ha dona\'t m\'agrada a la teva publicació</string> <string name="liked_notification">%1$s ha dona\'t m\'agrada a la teva publicació</string>
<string name="theme_title">Tema de l\'applicació</string> <string name="theme_title">Tema de l\'applicació</string>
<string name="switch_camera_button_alt">Canviar la càmera</string> <string name="switch_camera_button_alt">Canviar la càmera</string>
@ -40,16 +33,11 @@
<string name="tab_edit">EDICIÓ</string> <string name="tab_edit">EDICIÓ</string>
<string name="capture_button_alt">Captura</string> <string name="capture_button_alt">Captura</string>
<string name="gallery_button_alt">Galeria</string> <string name="gallery_button_alt">Galeria</string>
<string name="capture_mode_camera">Càmera</string>
<string name="delete_title">Confirmar</string>
<string name="NoCommentsToShow">No hi ha comentaris en aquesta publicació …</string> <string name="NoCommentsToShow">No hi ha comentaris en aquesta publicació …</string>
<string name="CommentDisplay">mostrar…</string> <string name="CommentDisplay">mostrar…</string>
<string name="domain_of_your_instance">Domini de la teva instancia</string> <string name="domain_of_your_instance">Domini de la teva instancia</string>
<string name="connect_to_pixelfed">Connectat a Pixelfed</string> <string name="connect_to_pixelfed">Connectat a Pixelfed</string>
<string name="you_are_in_offline_mode">Estàs en mode fora de línia, però encara pots veure algun contingut!</string> <string name="you_are_in_offline_mode">Estàs en mode fora de línia, però encara pots veure algun contingut!</string>
<string name="enter">Entrar</string>
<string name="login_empty_string_error">L\'adreça de la instància no pot estar buida!</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Imatges ocultes <string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Imatges ocultes
\n(fes clic per mostrar)</string> \n(fes clic per mostrar)</string>
<string name="auth_error_toast_msg">El servidor ha respost amb un error, torna-ho a provar!</string>
</resources> </resources>

View File

@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="menu_slideshow">Benutzername</string>
<string name="menu_subtitle">Kontoinformationen</string>
<string name="menu_account">Mein Profil</string> <string name="menu_account">Mein Profil</string>
<string name="menu_settings">Einstellungen</string> <string name="menu_settings">Einstellungen</string>
<string name="invalid_domain">Ungültige Domäne</string> <string name="invalid_domain">Ungültige Domäne</string>
@ -10,19 +8,14 @@
<string name="auth_failed">Authentifizierung fehlgeschlagen</string> <string name="auth_failed">Authentifizierung fehlgeschlagen</string>
<string name="token_error">Fehler beim Erhalten des Token</string> <string name="token_error">Fehler beim Erhalten des Token</string>
<string name="title_activity_settings2">Einstellungen</string> <string name="title_activity_settings2">Einstellungen</string>
<string name="or">oder</string>
<string name="theme_header">Erscheinungsbild</string> <string name="theme_header">Erscheinungsbild</string>
<string name="followed_notification">%1$s folgt dir</string> <string name="followed_notification">%1$s folgt dir</string>
<string name="mention_notification">%1$s hat dich erwähnt</string> <string name="mention_notification">%1$s hat dich erwähnt</string>
<string name="shared_notification">%1$s hat deinen Beitrag geteilt</string> <string name="shared_notification">%1$s hat deinen Beitrag geteilt</string>
<string name="liked_notification">%1$s hat deinen Beitrag favorisiert</string> <string name="liked_notification">%1$s hat deinen Beitrag favorisiert</string>
<string name="take_a_picture">Ein Foto aufnehmen</string>
<string name="upload_a_picture">Ein Foto hochladen</string>
<string name="send">senden</string> <string name="send">senden</string>
<string name="whats_an_instance">Was ist eine Instanz\?</string> <string name="whats_an_instance">Was ist eine Instanz\?</string>
<string name="theme_title">Erscheinungsbild</string> <string name="theme_title">Erscheinungsbild</string>
<string name="attachment_summary_off">Anhänge nur herunterladen, wenn sie manuell angefordert werden</string>
<string name="create_a_new_post">Neuen Beitrag erstellen!</string>
<string name="description">Beschreibung…</string> <string name="description">Beschreibung…</string>
<string name="save_to_gallery">In Galerie speichern…</string> <string name="save_to_gallery">In Galerie speichern…</string>
<string name="image_download_failed">Der Download ist fehlgeschlagen, bitte versuchen Sie es erneut</string> <string name="image_download_failed">Der Download ist fehlgeschlagen, bitte versuchen Sie es erneut</string>
@ -39,17 +32,12 @@
<string name="image_download_success">Bild erfolgreich heruntergeladen</string> <string name="image_download_success">Bild erfolgreich heruntergeladen</string>
<string name="capture_button_alt">Erfassen</string> <string name="capture_button_alt">Erfassen</string>
<string name="gallery_button_alt">Galerie</string> <string name="gallery_button_alt">Galerie</string>
<string name="capture_mode_camera">Kamera</string>
<string name="delete_title">Bestätigen</string>
<string name="share_picture">Foto teilen…</string> <string name="share_picture">Foto teilen…</string>
<string name="CommentDisplay">zeigen…</string> <string name="CommentDisplay">zeigen…</string>
<string name="domain_of_your_instance">Domain Ihrer Instanz</string> <string name="domain_of_your_instance">Domain Ihrer Instanz</string>
<string name="connect_to_pixelfed">Mit Pixelfed verbinden</string> <string name="connect_to_pixelfed">Mit Pixelfed verbinden</string>
<string name="login_connection_required_once">Sie müssen mindestens einmal mit dem Internet verbunden sein, um PixelDroid verwenden zu können :(</string> <string name="login_connection_required_once">Sie müssen mindestens einmal mit dem Internet verbunden sein, um PixelDroid verwenden zu können :(</string>
<string name="you_are_in_offline_mode">Sie befinden sich im Offline-Modus, aber Sie können immer noch einige Inhalte ansehen!</string> <string name="you_are_in_offline_mode">Sie befinden sich im Offline-Modus, aber Sie können immer noch einige Inhalte ansehen!</string>
<string name="auth_error_toast_msg">Server hat mit einem Fehler geantwortet, versuchen Sie es erneut!</string>
<string name="login_empty_string_error">Instanz-Adresse kann nicht leer sein!</string>
<string name="switch_camera_button_alt">Kamera wechseln</string> <string name="switch_camera_button_alt">Kamera wechseln</string>
<string name="registration_failed">Konnte die App nicht mit diesem Server verbinden</string> <string name="registration_failed">Konnte die App nicht mit diesem Server verbinden</string>
<string name="enter">Enter</string>
</resources> </resources>

View File

@ -6,16 +6,11 @@
<string name="invalid_domain">Dominio no válido</string> <string name="invalid_domain">Dominio no válido</string>
<string name="menu_settings">Ajustes</string> <string name="menu_settings">Ajustes</string>
<string name="menu_account">Mi perfil</string> <string name="menu_account">Mi perfil</string>
<string name="menu_subtitle">Información de la cuenta</string>
<string name="menu_slideshow">Nombre de la cuenta</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="token_error">Error al obtener el token</string> <string name="token_error">Error al obtener el token</string>
<string name="title_activity_settings2">Ajustes</string> <string name="title_activity_settings2">Ajustes</string>
<string name="shared_notification">%1$s compartió tu publicación</string> <string name="shared_notification">%1$s compartió tu publicación</string>
<string name="liked_notification">%1$s le gustó tu publicación</string> <string name="liked_notification">%1$s le gustó tu publicación</string>
<string name="create_a_new_post">¡Crear una nueva publicación!</string>
<string name="take_a_picture">Tomar una foto</string>
<string name="upload_a_picture">Subir una foto</string>
<string name="description">Descripción…</string> <string name="description">Descripción…</string>
<string name="send">enviar</string> <string name="send">enviar</string>
<string name="whats_an_instance">¿Qué es una instancia\?</string> <string name="whats_an_instance">¿Qué es una instancia\?</string>
@ -25,10 +20,8 @@
<string name="image_download_downloading">Descargando…</string> <string name="image_download_downloading">Descargando…</string>
<string name="image_download_success">La imagen se descargó con éxito</string> <string name="image_download_success">La imagen se descargó con éxito</string>
<string name="share_picture">Compartir foto…</string> <string name="share_picture">Compartir foto…</string>
<string name="attachment_summary_off">Descargar únicamente los archivos adjuntos cuando se solicite manualmente</string>
<string name="followed_notification">%1$s te siguió</string> <string name="followed_notification">%1$s te siguió</string>
<string name="mention_notification">%1$s te mencionó</string> <string name="mention_notification">%1$s te mencionó</string>
<string name="or">o</string>
<string name="switch_camera_button_alt">Cambiar cámara</string> <string name="switch_camera_button_alt">Cambiar cámara</string>
<string name="theme_title">Tema de la Aplicación</string> <string name="theme_title">Tema de la Aplicación</string>
<string name="theme_header">Tema</string> <string name="theme_header">Tema</string>
@ -39,16 +32,11 @@
<string name="tab_edit">EDITAR</string> <string name="tab_edit">EDITAR</string>
<string name="capture_button_alt">Capturar</string> <string name="capture_button_alt">Capturar</string>
<string name="gallery_button_alt">Galería</string> <string name="gallery_button_alt">Galería</string>
<string name="capture_mode_camera">Cámara</string>
<string name="delete_title">Confirmar</string>
<string name="NoCommentsToShow">No hay comentarios en esta publicación…</string> <string name="NoCommentsToShow">No hay comentarios en esta publicación…</string>
<string name="CommentDisplay">para mostrar…</string> <string name="CommentDisplay">para mostrar…</string>
<string name="domain_of_your_instance">Dominio de tu nodo</string> <string name="domain_of_your_instance">Dominio de tu nodo</string>
<string name="connect_to_pixelfed">Conectar con Pixelfed</string> <string name="connect_to_pixelfed">Conectar con Pixelfed</string>
<string name="you_are_in_offline_mode">Estás en modo sin conexión, ¡pero todavía puedes ver algo de contenido!</string> <string name="you_are_in_offline_mode">Estás en modo sin conexión, ¡pero todavía puedes ver algo de contenido!</string>
<string name="enter">Entrar</string>
<string name="auth_error_toast_msg">El servidor ha respondido con un error, ¡inténtalo de nuevo!</string>
<string name="login_empty_string_error">¡La dirección del nodo no puede estar vacía!</string>
<string name="login_connection_required_once">Necesitar conectarte a Internet al menos una vez para utilizar PixelDroid :(</string> <string name="login_connection_required_once">Necesitar conectarte a Internet al menos una vez para utilizar PixelDroid :(</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Contenido Oculto <string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Contenido Oculto
\n (haz clic para mostrar)</string> \n (haz clic para mostrar)</string>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="create_a_new_post">Sortu argitalpen berri bat!</string>
<string name="liked_notification">%1$s erabiltzaileak zure argitalpena gogoko du</string> <string name="liked_notification">%1$s erabiltzaileak zure argitalpena gogoko du</string>
<string name="shared_notification">%1$s erabiltzaileak zure argitalpena partekatu du</string> <string name="shared_notification">%1$s erabiltzaileak zure argitalpena partekatu du</string>
<string name="share_picture">Partekatu irudia…</string> <string name="share_picture">Partekatu irudia…</string>
@ -12,12 +11,8 @@
<string name="whats_an_instance">Zer da instantzia bat\?</string> <string name="whats_an_instance">Zer da instantzia bat\?</string>
<string name="send">bidali</string> <string name="send">bidali</string>
<string name="description">Deskribapena…</string> <string name="description">Deskribapena…</string>
<string name="or">edo</string>
<string name="upload_a_picture">Kargatu argazki bat</string>
<string name="take_a_picture">Atera argazki bat</string>
<string name="mention_notification">%1$s erabiltzaileak aipatu zaitu</string> <string name="mention_notification">%1$s erabiltzaileak aipatu zaitu</string>
<string name="followed_notification">%1$s jarraitzen hasi zaizu</string> <string name="followed_notification">%1$s jarraitzen hasi zaizu</string>
<string name="attachment_summary_off">Eskuz eskatzean bakarrik deskargatu eranskinak</string>
<string name="title_activity_settings2">Ezarpenak</string> <string name="title_activity_settings2">Ezarpenak</string>
<string name="token_error">Errorea tokena eskuratzean</string> <string name="token_error">Errorea tokena eskuratzean</string>
<string name="auth_failed">Ezin izan da autentifikatu</string> <string name="auth_failed">Ezin izan da autentifikatu</string>
@ -26,12 +21,8 @@
<string name="invalid_domain">Domeinu baliogabea</string> <string name="invalid_domain">Domeinu baliogabea</string>
<string name="menu_settings">Ezarpenak</string> <string name="menu_settings">Ezarpenak</string>
<string name="menu_account">Nire profila</string> <string name="menu_account">Nire profila</string>
<string name="menu_subtitle">Kontuaren informazioa</string>
<string name="menu_slideshow">Kontuaren izena</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="capture_mode_camera">Kamera</string>
<string name="gallery_button_alt">Galeria</string> <string name="gallery_button_alt">Galeria</string>
<string name="delete_title">Berretsi</string>
<string name="NoCommentsToShow">Iruzkinik gabeko argitalpena…</string> <string name="NoCommentsToShow">Iruzkinik gabeko argitalpena…</string>
<string name="you_are_in_offline_mode">Lineaz kanpo editatzeko moduan zaude, baina hala ere eduki batzuk ikus ditzakezu!</string> <string name="you_are_in_offline_mode">Lineaz kanpo editatzeko moduan zaude, baina hala ere eduki batzuk ikus ditzakezu!</string>
<string name="theme_title">Aplikazioaren gaia</string> <string name="theme_title">Aplikazioaren gaia</string>
@ -44,12 +35,9 @@
<string name="tab_filters">IRAGAZKIAK</string> <string name="tab_filters">IRAGAZKIAK</string>
<string name="connect_to_pixelfed">Konektatu Pixelfedera</string> <string name="connect_to_pixelfed">Konektatu Pixelfedera</string>
<string name="login_connection_required_once">PixelDroid erabili ahal izateko Internetera gutxienez behin konektatu behar duzu :(</string> <string name="login_connection_required_once">PixelDroid erabili ahal izateko Internetera gutxienez behin konektatu behar duzu :(</string>
<string name="enter">Sartu</string>
<string name="auth_error_toast_msg">Zerbitzariak errore batekin erantzun du, saiatu berriro!</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">Eduki-abisua / Multimedia ezkutatuta <string name="cw_nsfw_hidden_media_n_click_to_show">Eduki-abisua / Multimedia ezkutatuta
\n (egin klik erakusteko)</string> \n (egin klik erakusteko)</string>
<string name="lbl_brightness">DISTIRA</string> <string name="lbl_brightness">DISTIRA</string>
<string name="CommentDisplay">erakutsi…</string> <string name="CommentDisplay">erakutsi…</string>
<string name="login_empty_string_error">Instantziaren helbidea hutsik dago!</string>
<string name="domain_of_your_instance">Zure instantziaren domeinua</string> <string name="domain_of_your_instance">Zure instantziaren domeinua</string>
</resources> </resources>

View File

@ -1,11 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="create_a_new_post">مطلب جدیدی بگذارید!</string>
<string name="login_connection_required_once">برای استفاده از پیکسل‌دروید باید لااقل یک مرتبه به اینترنت وصل شوید :(</string> <string name="login_connection_required_once">برای استفاده از پیکسل‌دروید باید لااقل یک مرتبه به اینترنت وصل شوید :(</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">رسانهٔ پنهان / نامناسب برای محیط کار / دارای هشدار <string name="cw_nsfw_hidden_media_n_click_to_show">رسانهٔ پنهان / نامناسب برای محیط کار / دارای هشدار
\n(برای نمایش، کلیک کنید)</string> \n(برای نمایش، کلیک کنید)</string>
<string name="menu_slideshow">نام حساب</string>
<string name="menu_subtitle">اطلاعات حساب</string>
<string name="menu_settings">تنظیمات</string> <string name="menu_settings">تنظیمات</string>
<string name="invalid_domain">دامنه نامعتبر</string> <string name="invalid_domain">دامنه نامعتبر</string>
<string name="browser_launch_failed">نتوانستیم مرورگر را باز کنیم. آیا اصلا مرورگری دارید؟</string> <string name="browser_launch_failed">نتوانستیم مرورگر را باز کنیم. آیا اصلا مرورگری دارید؟</string>
@ -18,9 +15,6 @@
<string name="mention_notification">%1$s به شما اشاره کرد</string> <string name="mention_notification">%1$s به شما اشاره کرد</string>
<string name="shared_notification">%1$s مطلب شما را هم‌رسانی کرد</string> <string name="shared_notification">%1$s مطلب شما را هم‌رسانی کرد</string>
<string name="liked_notification">%1$s مطلب شما را پسندید</string> <string name="liked_notification">%1$s مطلب شما را پسندید</string>
<string name="take_a_picture">عکسی بگیرید</string>
<string name="upload_a_picture">تصویری بارگذاری کنید</string>
<string name="or">یا</string>
<string name="description">توضیحات…</string> <string name="description">توضیحات…</string>
<string name="send">بفرست</string> <string name="send">بفرست</string>
<string name="whats_an_instance">یک نمونه چیست؟</string> <string name="whats_an_instance">یک نمونه چیست؟</string>
@ -37,19 +31,13 @@
<string name="capture_button_alt">دریافت</string> <string name="capture_button_alt">دریافت</string>
<string name="switch_camera_button_alt">تغییر دوربین</string> <string name="switch_camera_button_alt">تغییر دوربین</string>
<string name="gallery_button_alt">نگارخانه</string> <string name="gallery_button_alt">نگارخانه</string>
<string name="capture_mode_camera">دوربین</string>
<string name="delete_title">تایید</string>
<string name="share_picture">هم‌رسانی تصویر…</string> <string name="share_picture">هم‌رسانی تصویر…</string>
<string name="NoCommentsToShow">نظری روی این مطلب نیست…</string> <string name="NoCommentsToShow">نظری روی این مطلب نیست…</string>
<string name="CommentDisplay">برای نمایش…</string> <string name="CommentDisplay">برای نمایش…</string>
<string name="domain_of_your_instance">دامنهٔ نمونهٔ شما</string> <string name="domain_of_your_instance">دامنهٔ نمونهٔ شما</string>
<string name="connect_to_pixelfed">اتصال به پیکسل‌فد</string> <string name="connect_to_pixelfed">اتصال به پیکسل‌فد</string>
<string name="you_are_in_offline_mode">شما در حالت برخط نیستید، اما همچنان می‌توانید برخی محتواها را ببینید!</string> <string name="you_are_in_offline_mode">شما در حالت برخط نیستید، اما همچنان می‌توانید برخی محتواها را ببینید!</string>
<string name="enter">ورود</string>
<string name="auth_error_toast_msg">کارساز، پاسخی حاوی خطا فرستاد، دوباره تلاش کنید!</string>
<string name="login_empty_string_error">نشانی نمونه نمی‌تواند خالی باشد!</string>
<string name="app_name">پیکسل‌دروید</string> <string name="app_name">پیکسل‌دروید</string>
<string name="menu_account">نمایهٔ من</string> <string name="menu_account">نمایهٔ من</string>
<string name="registration_failed">نتوانستیم برنامه را روی این کارساز ثبت کنیم</string> <string name="registration_failed">نتوانستیم برنامه را روی این کارساز ثبت کنیم</string>
<string name="attachment_summary_off">پیوست‌ها تنها در صورت درخواستی دستی بارگیری شوند</string>
</resources> </resources>

View File

@ -3,17 +3,11 @@
<string name="registration_failed">Impossible d\'enregistrer l\'application sur ce serveur</string> <string name="registration_failed">Impossible d\'enregistrer l\'application sur ce serveur</string>
<string name="auth_failed">Impossible d\'authentifier</string> <string name="auth_failed">Impossible d\'authentifier</string>
<string name="title_activity_settings2">Réglages</string> <string name="title_activity_settings2">Réglages</string>
<string name="menu_slideshow">Nom du compte</string>
<string name="menu_subtitle">Informations du compte</string>
<string name="menu_account">Mon profil</string> <string name="menu_account">Mon profil</string>
<string name="menu_settings">Réglages</string> <string name="menu_settings">Réglages</string>
<string name="attachment_summary_off">Télécharger uniquement les pièces jointes lorsque demandé manuellement</string>
<string name="followed_notification">%1$s vous a suivi</string> <string name="followed_notification">%1$s vous a suivi</string>
<string name="shared_notification">%1$s a partagé votre publication</string> <string name="shared_notification">%1$s a partagé votre publication</string>
<string name="liked_notification">%1$s a aimé(e) votre publication</string> <string name="liked_notification">%1$s a aimé(e) votre publication</string>
<string name="take_a_picture">Prendre une photo</string>
<string name="upload_a_picture">Mettre en ligne une photo</string>
<string name="or">ou</string>
<string name="description">Description…</string> <string name="description">Description…</string>
<string name="send">envoyer</string> <string name="send">envoyer</string>
<string name="whats_an_instance">Qu\'est-ce qu\'une instance \?</string> <string name="whats_an_instance">Qu\'est-ce qu\'une instance \?</string>
@ -27,7 +21,6 @@
<string name="browser_launch_failed">Impossible de lancer un navigateur, en avez-vous un \?</string> <string name="browser_launch_failed">Impossible de lancer un navigateur, en avez-vous un \?</string>
<string name="mention_notification">%1$s vous a mentionné</string> <string name="mention_notification">%1$s vous a mentionné</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="create_a_new_post">Créez une nouvelle publication !</string>
<string name="token_error">Erreur lors de l\'obtention du jeton</string> <string name="token_error">Erreur lors de l\'obtention du jeton</string>
<string name="connect_to_pixelfed">Se connecter à PixelFed</string> <string name="connect_to_pixelfed">Se connecter à PixelFed</string>
<string name="theme_title">Thème de lapplication</string> <string name="theme_title">Thème de lapplication</string>
@ -40,16 +33,11 @@
<string name="capture_button_alt">Capturer</string> <string name="capture_button_alt">Capturer</string>
<string name="switch_camera_button_alt">Changer de caméra</string> <string name="switch_camera_button_alt">Changer de caméra</string>
<string name="gallery_button_alt">Gallerie</string> <string name="gallery_button_alt">Gallerie</string>
<string name="capture_mode_camera">Appareil photo</string>
<string name="delete_title">Confirmer</string>
<string name="NoCommentsToShow">Aucun commentaire dans cette publication…</string> <string name="NoCommentsToShow">Aucun commentaire dans cette publication…</string>
<string name="domain_of_your_instance">Domaine de votre instance</string> <string name="domain_of_your_instance">Domaine de votre instance</string>
<string name="you_are_in_offline_mode">Vous êtes en mode hors ligne mais vous pouvez continuer accéder à un certain contenu !</string> <string name="you_are_in_offline_mode">Vous êtes en mode hors ligne mais vous pouvez continuer accéder à un certain contenu !</string>
<string name="enter">Entrez</string>
<string name="login_empty_string_error">Ladresse de linstance ne peut être laissée vide !</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Média caché <string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Média caché
\n (appuyez pour afficher)</string> \n (appuyez pour afficher)</string>
<string name="CommentDisplay">pour afficher…</string> <string name="CommentDisplay">pour afficher…</string>
<string name="login_connection_required_once">Vous devez vous connecter à Internet au moins une fois afin de pouvoir utiliser PixelDroid :(</string> <string name="login_connection_required_once">Vous devez vous connecter à Internet au moins une fois afin de pouvoir utiliser PixelDroid :(</string>
<string name="auth_error_toast_msg">Le serveur a répondu avec une erreur, veuillez réessayer !</string>
</resources> </resources>

View File

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="menu_slideshow">Nome da conta</string>
<string name="menu_subtitle">Información da conta</string>
<string name="menu_account">Perfil</string> <string name="menu_account">Perfil</string>
<string name="menu_settings">Axustes</string> <string name="menu_settings">Axustes</string>
<string name="invalid_domain">Dominio non válido</string> <string name="invalid_domain">Dominio non válido</string>
@ -15,10 +13,6 @@
<string name="mention_notification">%1$s mencionoute</string> <string name="mention_notification">%1$s mencionoute</string>
<string name="liked_notification">a %1$s gustoulle a publicación</string> <string name="liked_notification">a %1$s gustoulle a publicación</string>
<string name="shared_notification">%1$s comparteu a publicación</string> <string name="shared_notification">%1$s comparteu a publicación</string>
<string name="create_a_new_post">Crea una publicación!</string>
<string name="take_a_picture">Fai unha foto</string>
<string name="upload_a_picture">Sube unha imaxe</string>
<string name="or">ou</string>
<string name="description">Descrición…</string> <string name="description">Descrición…</string>
<string name="send">enviar</string> <string name="send">enviar</string>
<string name="whats_an_instance">Que é unha instancia\?</string> <string name="whats_an_instance">Que é unha instancia\?</string>
@ -34,8 +28,6 @@
<string name="capture_button_alt">Facer foto</string> <string name="capture_button_alt">Facer foto</string>
<string name="switch_camera_button_alt">Cambiar de cámara</string> <string name="switch_camera_button_alt">Cambiar de cámara</string>
<string name="gallery_button_alt">Galería</string> <string name="gallery_button_alt">Galería</string>
<string name="capture_mode_camera">Cámara</string>
<string name="delete_title">Confirmar</string>
<string name="share_picture">Compartir foto…</string> <string name="share_picture">Compartir foto…</string>
<string name="NoCommentsToShow">Sen comentarios na publicación…</string> <string name="NoCommentsToShow">Sen comentarios na publicación…</string>
<string name="image_download_failed">Fallou a descarga, inténtao outra vez</string> <string name="image_download_failed">Fallou a descarga, inténtao outra vez</string>
@ -44,12 +36,8 @@
<string name="connect_to_pixelfed">Conectar con Pixelfed</string> <string name="connect_to_pixelfed">Conectar con Pixelfed</string>
<string name="login_connection_required_once">Tes que conectarte cando menos unha vez a internet para usar PixelDroid :(</string> <string name="login_connection_required_once">Tes que conectarte cando menos unha vez a internet para usar PixelDroid :(</string>
<string name="you_are_in_offline_mode">Non tes conexión, pero aínda así podes ver algún contido!</string> <string name="you_are_in_offline_mode">Non tes conexión, pero aínda así podes ver algún contido!</string>
<string name="enter">Entrar</string>
<string name="auth_error_toast_msg">O servidor respondeu cun erro, inténtao outra vez!</string>
<string name="login_empty_string_error">O enderezo da instancia non pode estar baleiro!</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Agochado <string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Agochado
\n(preme para amosar)</string> \n(preme para amosar)</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="registration_failed">Non puidemos rexistrar a aplicación neste servidor</string> <string name="registration_failed">Non puidemos rexistrar a aplicación neste servidor</string>
<string name="attachment_summary_off">Descargar anexos só cando se solicite manualmente</string>
</resources> </resources>

View File

@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="menu_slideshow">Nome account</string>
<string name="title_activity_settings2">Impostazioni</string> <string name="title_activity_settings2">Impostazioni</string>
<string name="attachment_summary_off">Scarica gli allegati solo quando richiesto manualmente</string>
<string name="menu_account">Profilo personale</string> <string name="menu_account">Profilo personale</string>
<string name="menu_settings">Impostazioni</string> <string name="menu_settings">Impostazioni</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
@ -14,11 +12,7 @@
<string name="shared_notification">%1$s ha condiviso il tuo post</string> <string name="shared_notification">%1$s ha condiviso il tuo post</string>
<string name="followed_notification">%1$s ti ha seguito</string> <string name="followed_notification">%1$s ti ha seguito</string>
<string name="mention_notification">%1$s ti ha menzionato</string> <string name="mention_notification">%1$s ti ha menzionato</string>
<string name="take_a_picture">Fai una foto</string>
<string name="upload_a_picture">Carica una foto</string>
<string name="liked_notification">%1$s è piaciuto il tuo post</string> <string name="liked_notification">%1$s è piaciuto il tuo post</string>
<string name="create_a_new_post">Crea un nuovo post!</string>
<string name="or">o</string>
<string name="tab_filters">FILTRI</string> <string name="tab_filters">FILTRI</string>
<string name="send">invia</string> <string name="send">invia</string>
<string name="lbl_brightness">LUMINOSITÀ</string> <string name="lbl_brightness">LUMINOSITÀ</string>
@ -26,15 +20,11 @@
<string name="whats_an_instance">Cos\'è un\'istanza\?</string> <string name="whats_an_instance">Cos\'è un\'istanza\?</string>
<string name="logout">Disconnettersi</string> <string name="logout">Disconnettersi</string>
<string name="lbl_saturation">SATURAZIONE</string> <string name="lbl_saturation">SATURAZIONE</string>
<string name="enter">Entrare</string>
<string name="menu_subtitle">Informazioni account</string>
<string name="delete_title">Conferma</string>
<string name="connect_to_pixelfed">Connetti a Pixelfed</string> <string name="connect_to_pixelfed">Connetti a Pixelfed</string>
<string name="lbl_contrast">CONTRASTO</string> <string name="lbl_contrast">CONTRASTO</string>
<string name="save_to_gallery">Salva nella galleria…</string> <string name="save_to_gallery">Salva nella galleria…</string>
<string name="image_download_failed">Il download non è riuscito, per favore riprova</string> <string name="image_download_failed">Il download non è riuscito, per favore riprova</string>
<string name="share_picture">Condividi immagine…</string> <string name="share_picture">Condividi immagine…</string>
<string name="auth_error_toast_msg">Il server ha risposto con un errore, riprovare!</string>
<string name="image_download_downloading">Download in corso…</string> <string name="image_download_downloading">Download in corso…</string>
<string name="image_download_success">Immagine scaricata con successo</string> <string name="image_download_success">Immagine scaricata con successo</string>
<string name="NoCommentsToShow">Nessun commento in questo post…</string> <string name="NoCommentsToShow">Nessun commento in questo post…</string>
@ -45,11 +35,9 @@
<string name="capture_button_alt">Acquisizione</string> <string name="capture_button_alt">Acquisizione</string>
<string name="switch_camera_button_alt">Cambia fotocamera</string> <string name="switch_camera_button_alt">Cambia fotocamera</string>
<string name="gallery_button_alt">Galleria</string> <string name="gallery_button_alt">Galleria</string>
<string name="capture_mode_camera">Fotocamera</string>
<string name="domain_of_your_instance">Dominio della tua istanza</string> <string name="domain_of_your_instance">Dominio della tua istanza</string>
<string name="login_connection_required_once">È necessario connettersi a Internet almeno una volta per utilizzare PixelDroid :(</string> <string name="login_connection_required_once">È necessario connettersi a Internet almeno una volta per utilizzare PixelDroid :(</string>
<string name="you_are_in_offline_mode">Sei in modalità offline, ma puoi comunque visualizzare alcuni contenuti!</string> <string name="you_are_in_offline_mode">Sei in modalità offline, ma puoi comunque visualizzare alcuni contenuti!</string>
<string name="login_empty_string_error">L\'indirizzo dell\'istanza non può essere vuoto!</string>
<string name="invalid_domain">Dominio non valido</string> <string name="invalid_domain">Dominio non valido</string>
<string name="tab_edit">MODIFICA</string> <string name="tab_edit">MODIFICA</string>
</resources> </resources>

View File

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="menu_slideshow">アカウント名</string>
<string name="menu_subtitle">アカウント情報</string>
<string name="menu_account">プロフィール</string> <string name="menu_account">プロフィール</string>
<string name="menu_settings">設定</string> <string name="menu_settings">設定</string>
<string name="invalid_domain">無効なドメイン</string> <string name="invalid_domain">無効なドメイン</string>
@ -10,12 +8,8 @@
<string name="title_activity_settings2">設定</string> <string name="title_activity_settings2">設定</string>
<string name="theme_title">テーマ設定</string> <string name="theme_title">テーマ設定</string>
<string name="theme_header">テーマ</string> <string name="theme_header">テーマ</string>
<string name="attachment_summary_off">要求された場合にのみ添付ファイルをダウンロードする</string>
<string name="followed_notification">%1$s さんにフォローされました</string> <string name="followed_notification">%1$s さんにフォローされました</string>
<string name="liked_notification">%1$s さんがあなたの投稿をお気に入りに登録しました</string> <string name="liked_notification">%1$s さんがあなたの投稿をお気に入りに登録しました</string>
<string name="take_a_picture">写真を撮影</string>
<string name="upload_a_picture">画像をアップロード</string>
<string name="or">または</string>
<string name="description">説明…</string> <string name="description">説明…</string>
<string name="send">送信</string> <string name="send">送信</string>
<string name="whats_an_instance">インスタンスとは?</string> <string name="whats_an_instance">インスタンスとは?</string>
@ -30,24 +24,18 @@
<string name="capture_button_alt">キャプチャー</string> <string name="capture_button_alt">キャプチャー</string>
<string name="switch_camera_button_alt">カメラを切り替え</string> <string name="switch_camera_button_alt">カメラを切り替え</string>
<string name="gallery_button_alt">ギャラリー</string> <string name="gallery_button_alt">ギャラリー</string>
<string name="capture_mode_camera">カメラ</string>
<string name="delete_title">確認</string>
<string name="share_picture">画像を共有…</string> <string name="share_picture">画像を共有…</string>
<string name="CommentDisplay">表示する…</string> <string name="CommentDisplay">表示する…</string>
<string name="domain_of_your_instance">あなたの参加しているインスタンスのドメイン</string> <string name="domain_of_your_instance">あなたの参加しているインスタンスのドメイン</string>
<string name="connect_to_pixelfed">Pixelfedに接続</string> <string name="connect_to_pixelfed">Pixelfedに接続</string>
<string name="login_connection_required_once">PixelDroidを利用するにははじめにインターネットにアクセスする必要があります</string> <string name="login_connection_required_once">PixelDroidを利用するにははじめにインターネットにアクセスする必要があります</string>
<string name="auth_error_toast_msg">サーバーでエラーが発生しました。もう一度お試しください。</string>
<string name="login_empty_string_error">インスタンスアドレスを空欄にすることはできません</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Hidden Media <string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Hidden Media
\n (クリックで表示)</string> \n (クリックで表示)</string>
<string name="enter">入る</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="registration_failed">このサーバーにアプリケーションを登録することができませんでした</string> <string name="registration_failed">このサーバーにアプリケーションを登録することができませんでした</string>
<string name="browser_launch_failed">ブラウザが起動できませんでした。インストールされているか確認してください。</string> <string name="browser_launch_failed">ブラウザが起動できませんでした。インストールされているか確認してください。</string>
<string name="mention_notification">%1$s さんがあなたにメンションしました</string> <string name="mention_notification">%1$s さんがあなたにメンションしました</string>
<string name="shared_notification">%1$s さんがあなたの投稿を再共有しました</string> <string name="shared_notification">%1$s さんがあなたの投稿を再共有しました</string>
<string name="create_a_new_post">新しい投稿を作成</string>
<string name="tab_edit">編集</string> <string name="tab_edit">編集</string>
<string name="image_download_failed">ダウンロードに失敗しました、もう一度実行してください</string> <string name="image_download_failed">ダウンロードに失敗しました、もう一度実行してください</string>
<string name="NoCommentsToShow">この投稿にはコメントがありません…</string> <string name="NoCommentsToShow">この投稿にはコメントがありません…</string>

View File

@ -9,6 +9,5 @@
<color name="filterLabelNormal">#8A8889</color> <color name="filterLabelNormal">#8A8889</color>
<color name="filterLabelSelected">#221F20</color> <color name="filterLabelSelected">#221F20</color>
<color name="colorOptionMenu">#FF3990</color>
<color name="colorPrimaryError">#FF0000</color> <color name="colorPrimaryError">#FF0000</color>
</resources> </resources>

View File

@ -6,6 +6,8 @@
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
<item name="materialDrawerStyle">@style/Widget.MaterialDrawerStyle</item>
<item name="materialDrawerHeaderStyle">@style/Widget.MaterialDrawerHeaderStyle</item>
</style> </style>
<style name="AppTheme.Launcher"> <style name="AppTheme.Launcher">
<item name="android:windowBackground">@drawable/theme_night</item> <item name="android:windowBackground">@drawable/theme_night</item>

View File

@ -9,21 +9,14 @@
<string name="invalid_domain">Ongeldig domein</string> <string name="invalid_domain">Ongeldig domein</string>
<string name="menu_settings">Instellingen</string> <string name="menu_settings">Instellingen</string>
<string name="menu_account">Mijn profiel</string> <string name="menu_account">Mijn profiel</string>
<string name="menu_subtitle">Account informatie</string>
<string name="menu_slideshow">Account naam</string>
<string name="logout">Log uit</string> <string name="logout">Log uit</string>
<string name="whats_an_instance">Wat is een instance\?</string> <string name="whats_an_instance">Wat is een instance\?</string>
<string name="send">stuur</string> <string name="send">stuur</string>
<string name="description">Beschrijving…</string> <string name="description">Beschrijving…</string>
<string name="or">of</string>
<string name="upload_a_picture">Upload een foto</string>
<string name="take_a_picture">Maak een foto</string>
<string name="create_a_new_post">Schrijf een nieuw bericht!</string>
<string name="liked_notification">%1$s vond je bericht leuk</string> <string name="liked_notification">%1$s vond je bericht leuk</string>
<string name="shared_notification">%1$s heeft je bericht gedeeld</string> <string name="shared_notification">%1$s heeft je bericht gedeeld</string>
<string name="mention_notification">%1$s heeft je genoemd</string> <string name="mention_notification">%1$s heeft je genoemd</string>
<string name="followed_notification">%1$s volgt je</string> <string name="followed_notification">%1$s volgt je</string>
<string name="attachment_summary_off">Bijlagen alleen downloaden bij handmatige toestemming</string>
<string name="auth_failed">Kon niet authenticeren</string> <string name="auth_failed">Kon niet authenticeren</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="save_to_gallery">Opslaan in gallerij…</string> <string name="save_to_gallery">Opslaan in gallerij…</string>
@ -31,7 +24,6 @@
<string name="image_download_downloading">Word gedownload…</string> <string name="image_download_downloading">Word gedownload…</string>
<string name="image_download_success">Afbeelding met succes gedownload</string> <string name="image_download_success">Afbeelding met succes gedownload</string>
<string name="share_picture">Afbeelding delen…</string> <string name="share_picture">Afbeelding delen…</string>
<string name="capture_mode_camera">Camera</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Verborgen Media <string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Verborgen Media
\n (Klik om weer te geven)</string> \n (Klik om weer te geven)</string>
<string name="lbl_brightness">Helderheid</string> <string name="lbl_brightness">Helderheid</string>
@ -42,14 +34,10 @@
<string name="capture_button_alt">Vastleggen</string> <string name="capture_button_alt">Vastleggen</string>
<string name="switch_camera_button_alt">Van camera wisselen</string> <string name="switch_camera_button_alt">Van camera wisselen</string>
<string name="gallery_button_alt">Gallerij</string> <string name="gallery_button_alt">Gallerij</string>
<string name="enter">Enter</string>
<string name="delete_title">Bevestigen</string>
<string name="NoCommentsToShow">Geen reacties op dit bericht…</string> <string name="NoCommentsToShow">Geen reacties op dit bericht…</string>
<string name="CommentDisplay">weer te geven…</string> <string name="CommentDisplay">weer te geven…</string>
<string name="domain_of_your_instance">Domein van je instance</string> <string name="domain_of_your_instance">Domein van je instance</string>
<string name="connect_to_pixelfed">Met Pixelfed verbinden</string> <string name="connect_to_pixelfed">Met Pixelfed verbinden</string>
<string name="login_connection_required_once">Je moet in ieder geval één keer met het internet verbonden zijn geweest om PixelDroid te kunnen gebruiken :(</string> <string name="login_connection_required_once">Je moet in ieder geval één keer met het internet verbonden zijn geweest om PixelDroid te kunnen gebruiken :(</string>
<string name="you_are_in_offline_mode">Je bent in de offline modus, maar je kan nog steeds bepaalde inhoud zien!</string> <string name="you_are_in_offline_mode">Je bent in de offline modus, maar je kan nog steeds bepaalde inhoud zien!</string>
<string name="auth_error_toast_msg">De server heeft gereageerd met een foutmelding, probeer opnieuw!</string>
<string name="login_empty_string_error">Instance adres mag niet leeg zijn!</string>
</resources> </resources>

View File

@ -8,9 +8,6 @@
<string name="followed_notification">%1$s подписался на вас</string> <string name="followed_notification">%1$s подписался на вас</string>
<string name="mention_notification">%1$s упомянул вас</string> <string name="mention_notification">%1$s упомянул вас</string>
<string name="shared_notification">%1$s поделился вашим пост</string> <string name="shared_notification">%1$s поделился вашим пост</string>
<string name="create_a_new_post">Создайте новый пост!</string>
<string name="upload_a_picture">Загрузите изображение</string>
<string name="or">или</string>
<string name="send">отправить</string> <string name="send">отправить</string>
<string name="logout">Выйти</string> <string name="logout">Выйти</string>
<string name="lbl_brightness">ЯРКОСТЬ</string> <string name="lbl_brightness">ЯРКОСТЬ</string>
@ -24,30 +21,21 @@
<string name="image_download_success">Изображение успешно загружено</string> <string name="image_download_success">Изображение успешно загружено</string>
<string name="switch_camera_button_alt">Переключить камеру</string> <string name="switch_camera_button_alt">Переключить камеру</string>
<string name="gallery_button_alt">Галерея</string> <string name="gallery_button_alt">Галерея</string>
<string name="capture_mode_camera">Камера</string>
<string name="delete_title">Подтвердить</string>
<string name="NoCommentsToShow">Нет комментариев под этим постом…</string> <string name="NoCommentsToShow">Нет комментариев под этим постом…</string>
<string name="CommentDisplay">показать…</string> <string name="CommentDisplay">показать…</string>
<string name="domain_of_your_instance">Домен вашего инстанса</string> <string name="domain_of_your_instance">Домен вашего инстанса</string>
<string name="connect_to_pixelfed">Подключение к Pixelfed</string> <string name="connect_to_pixelfed">Подключение к Pixelfed</string>
<string name="menu_slideshow">Имя аккаунта</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="menu_subtitle">Информация об аккаунте</string>
<string name="menu_account">Мой профиль</string> <string name="menu_account">Мой профиль</string>
<string name="menu_settings">Настройки</string> <string name="menu_settings">Настройки</string>
<string name="invalid_domain">Неправильное доменное имя</string> <string name="invalid_domain">Неправильное доменное имя</string>
<string name="browser_launch_failed">Не удалось запустить браузер, есть ли он у вас\?</string> <string name="browser_launch_failed">Не удалось запустить браузер, есть ли он у вас\?</string>
<string name="attachment_summary_off">Вложения скачиваются только вручную по запросу</string>
<string name="liked_notification">%1$s понравился ваш пост</string> <string name="liked_notification">%1$s понравился ваш пост</string>
<string name="take_a_picture">Выберите изображение</string>
<string name="description">Описание…</string> <string name="description">Описание…</string>
<string name="image_download_failed">Скачивание не удалось, попробуйте ещё раз</string> <string name="image_download_failed">Скачивание не удалось, попробуйте ещё раз</string>
<string name="share_picture">Поделиться изображение…</string> <string name="share_picture">Поделиться изображение…</string>
<string name="login_connection_required_once">Вам необходимо подключение к интернету что бы использовать PixelDroid :(</string> <string name="login_connection_required_once">Вам необходимо подключение к интернету что бы использовать PixelDroid :(</string>
<string name="you_are_in_offline_mode">Вы в оффлайн режиме, но вы можете видеть некоторый контент!</string> <string name="you_are_in_offline_mode">Вы в оффлайн режиме, но вы можете видеть некоторый контент!</string>
<string name="enter">Войти</string>
<string name="auth_error_toast_msg">Сервер ответил ошибокой, попробуйте ещё раз!</string>
<string name="login_empty_string_error">Адрес инстанса не может быть пустым!</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Скрытое медиа <string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Скрытое медиа
\n (кликните что бы показать)</string> \n (кликните что бы показать)</string>
<string name="registration_failed">Не удалось зарегистрировать приложение на этом инстансе</string> <string name="registration_failed">Не удалось зарегистрировать приложение на этом инстансе</string>

View File

@ -4,13 +4,10 @@
<string name="invalid_domain">Ogiltig domän</string> <string name="invalid_domain">Ogiltig domän</string>
<string name="menu_settings">Inställningar</string> <string name="menu_settings">Inställningar</string>
<string name="menu_account">Min profil</string> <string name="menu_account">Min profil</string>
<string name="menu_subtitle">Kontoinformation</string>
<string name="menu_slideshow">Kontonamn</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="browser_launch_failed">Kunde inte starta en webbläsare, har du en\?</string> <string name="browser_launch_failed">Kunde inte starta en webbläsare, har du en\?</string>
<string name="token_error">Fel vid hämtning av token</string> <string name="token_error">Fel vid hämtning av token</string>
<string name="auth_failed">Kunde inte autentisera</string> <string name="auth_failed">Kunde inte autentisera</string>
<string name="attachment_summary_off">Enbart nedladdade bilagor när manuellt efterfrågade</string>
<string name="title_activity_settings2">Inställningar</string> <string name="title_activity_settings2">Inställningar</string>
<string name="domain_of_your_instance">Instansens domän</string> <string name="domain_of_your_instance">Instansens domän</string>
<string name="save_to_gallery">Spara till galleri…</string> <string name="save_to_gallery">Spara till galleri…</string>
@ -24,12 +21,7 @@
<string name="mention_notification">%1$s nämnde dig</string> <string name="mention_notification">%1$s nämnde dig</string>
<string name="shared_notification">%1$s delande ditt inlägg</string> <string name="shared_notification">%1$s delande ditt inlägg</string>
<string name="liked_notification">%1$s gillar ditt inlägg</string> <string name="liked_notification">%1$s gillar ditt inlägg</string>
<string name="create_a_new_post">Skapa ett nytt inlägg!</string>
<string name="take_a_picture">Ta en bild</string>
<string name="upload_a_picture">Ladda upp en bild</string>
<string name="or">eller</string>
<string name="description">Beskrivning…</string> <string name="description">Beskrivning…</string>
<string name="enter">Enter</string>
<string name="send">skicka</string> <string name="send">skicka</string>
<string name="whats_an_instance">Vad är en instans\?</string> <string name="whats_an_instance">Vad är en instans\?</string>
<string name="logout">Logga av</string> <string name="logout">Logga av</string>
@ -41,15 +33,11 @@
<string name="capture_button_alt">Lagra</string> <string name="capture_button_alt">Lagra</string>
<string name="switch_camera_button_alt">Byt kamera</string> <string name="switch_camera_button_alt">Byt kamera</string>
<string name="gallery_button_alt">Galleri</string> <string name="gallery_button_alt">Galleri</string>
<string name="capture_mode_camera">Kamera</string>
<string name="delete_title">Bekräfta</string>
<string name="share_picture">Dela bild…</string> <string name="share_picture">Dela bild…</string>
<string name="NoCommentsToShow">Inga kommentarer på detta inlägg…</string> <string name="NoCommentsToShow">Inga kommentarer på detta inlägg…</string>
<string name="CommentDisplay">att visa…</string> <string name="CommentDisplay">att visa…</string>
<string name="connect_to_pixelfed">Anslut till Pixelfed</string> <string name="connect_to_pixelfed">Anslut till Pixelfed</string>
<string name="you_are_in_offline_mode">Du är i nedkopplad läge, men du kan ändå se lite innehåll!</string> <string name="you_are_in_offline_mode">Du är i nedkopplad läge, men du kan ändå se lite innehåll!</string>
<string name="auth_error_toast_msg">Servern svarade med ett fel, försök igen!</string>
<string name="login_empty_string_error">Instansadressen får inte vara tom!</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Dold media <string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Dold media
\n(Tryck för att visa)</string> \n(Tryck för att visa)</string>
</resources> </resources>

View File

@ -2,17 +2,12 @@
<resources> <resources>
<string name="browser_launch_failed">Не вдалося відкрити браузер, він у вас є\?</string> <string name="browser_launch_failed">Не вдалося відкрити браузер, він у вас є\?</string>
<string name="image_download_failed">Не вдалося завантажити, спробуйте знову</string> <string name="image_download_failed">Не вдалося завантажити, спробуйте знову</string>
<string name="menu_subtitle">Інформація про акаунт</string>
<string name="menu_account">Мій профіль</string> <string name="menu_account">Мій профіль</string>
<string name="invalid_domain">Недоступний домен</string> <string name="invalid_domain">Недоступний домен</string>
<string name="title_activity_settings2">Налаштування</string> <string name="title_activity_settings2">Налаштування</string>
<string name="theme_title">Тема застосунку</string> <string name="theme_title">Тема застосунку</string>
<string name="theme_header">Тема</string> <string name="theme_header">Тема</string>
<string name="mention_notification">%1$s згадав(-ла) вас</string> <string name="mention_notification">%1$s згадав(-ла) вас</string>
<string name="create_a_new_post">Створити новий пост!</string>
<string name="take_a_picture">Сфотографувати</string>
<string name="upload_a_picture">Завантажити фото</string>
<string name="or">або</string>
<string name="description">Опис…</string> <string name="description">Опис…</string>
<string name="send">відправити</string> <string name="send">відправити</string>
<string name="lbl_brightness">Яскравість</string> <string name="lbl_brightness">Яскравість</string>
@ -24,8 +19,6 @@
<string name="image_download_success">Зображення успішно завантажено</string> <string name="image_download_success">Зображення успішно завантажено</string>
<string name="switch_camera_button_alt">Перемкнути камеру</string> <string name="switch_camera_button_alt">Перемкнути камеру</string>
<string name="gallery_button_alt">Галерея</string> <string name="gallery_button_alt">Галерея</string>
<string name="capture_mode_camera">Камера</string>
<string name="delete_title">Підтвердити</string>
<string name="share_picture">Поділитися фотографією…</string> <string name="share_picture">Поділитися фотографією…</string>
<string name="logout">Вийти</string> <string name="logout">Вийти</string>
<string name="NoCommentsToShow">Немає коментарів до цієї публікації…</string> <string name="NoCommentsToShow">Немає коментарів до цієї публікації…</string>

View File

@ -1,8 +0,0 @@
<resources>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="menu_slideshow">用户名</string>
<string name="registration_failed">无法在此服务器上注册应用程序</string> <string name="registration_failed">无法在此服务器上注册应用程序</string>
<string name="browser_launch_failed">无法跳转至浏览器,请确认是否安装</string> <string name="browser_launch_failed">无法跳转至浏览器,请确认是否安装</string>
<string name="image_download_success">成功下载图像</string> <string name="image_download_success">成功下载图像</string>
@ -13,18 +12,12 @@
<string name="send">发送</string> <string name="send">发送</string>
<string name="logout">注销</string> <string name="logout">注销</string>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="menu_subtitle">用户信息</string>
<string name="title_activity_settings2">配置</string> <string name="title_activity_settings2">配置</string>
<string name="theme_title">应用主题</string> <string name="theme_title">应用主题</string>
<string name="attachment_summary_off">仅在手动请求时下载附件</string>
<string name="followed_notification">关注了你</string> <string name="followed_notification">关注了你</string>
<string name="mention_notification">提到了你</string> <string name="mention_notification">提到了你</string>
<string name="shared_notification">分享了你的帖文</string> <string name="shared_notification">分享了你的帖文</string>
<string name="liked_notification">给你的帖文点赞</string> <string name="liked_notification">给你的帖文点赞</string>
<string name="create_a_new_post">创建一条新帖文!</string>
<string name="take_a_picture">拍照</string>
<string name="upload_a_picture">上传图片</string>
<string name="or"></string>
<string name="description">描述……</string> <string name="description">描述……</string>
<string name="whats_an_instance">什么是实例?</string> <string name="whats_an_instance">什么是实例?</string>
<string name="lbl_brightness">亮度</string> <string name="lbl_brightness">亮度</string>
@ -38,15 +31,10 @@
<string name="capture_button_alt">拍摄</string> <string name="capture_button_alt">拍摄</string>
<string name="switch_camera_button_alt">切换摄像头</string> <string name="switch_camera_button_alt">切换摄像头</string>
<string name="gallery_button_alt">相册</string> <string name="gallery_button_alt">相册</string>
<string name="capture_mode_camera">相机</string>
<string name="delete_title">确认</string>
<string name="NoCommentsToShow">这条帖文下没有评论……</string> <string name="NoCommentsToShow">这条帖文下没有评论……</string>
<string name="CommentDisplay">显示……</string> <string name="CommentDisplay">显示……</string>
<string name="domain_of_your_instance">实例的域名</string> <string name="domain_of_your_instance">实例的域名</string>
<string name="you_are_in_offline_mode">您处于离线模式,但仍可以查看已缓存内容!</string> <string name="you_are_in_offline_mode">您处于离线模式,但仍可以查看已缓存内容!</string>
<string name="login_empty_string_error">请输入实例地址!</string>
<string name="auth_error_toast_msg">服务器报错误,请重试!</string>
<string name="enter">输入</string>
<string name="connect_to_pixelfed">连接至 Pixelfed</string> <string name="connect_to_pixelfed">连接至 Pixelfed</string>
<string name="share_picture">分享图片……</string> <string name="share_picture">分享图片……</string>
<string name="login_connection_required_once">您至少需要连接到互联网一次才能使用 PixelDroid :(</string> <string name="login_connection_required_once">您至少需要连接到互联网一次才能使用 PixelDroid :(</string>

View File

@ -1,15 +1,4 @@
<resources> <resources>
<!-- Reply Preference -->
<string-array name="reply_entries">
<item>Reply</item>
<item>Reply to all</item>
</string-array>
<string-array name="reply_values">
<item>reply</item>
<item>reply_all</item>
</string-array>
<string-array name="theme_values"> <string-array name="theme_values">
<item>default</item> <item>default</item>
<item>light</item> <item>light</item>

View File

@ -11,6 +11,5 @@
<color name="colorButtonText">#FFFFFF</color> <color name="colorButtonText">#FFFFFF</color>
<color name="filterLabelNormal">#8A8889</color> <color name="filterLabelNormal">#8A8889</color>
<color name="filterLabelSelected">#221F20</color> <color name="filterLabelSelected">#221F20</color>
<color name="colorOptionMenu">#FF3990</color>
<color name="colorPrimaryError">#FF0000</color> <color name="colorPrimaryError">#FF0000</color>
</resources> </resources>

View File

@ -1,10 +1,4 @@
<resources> <resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="nav_header_vertical_spacing">8dp</dimen>
<dimen name="nav_header_height">176dp</dimen>
<dimen name="margin_xsmall">16dp</dimen> <dimen name="margin_xsmall">16dp</dimen>
<dimen name="margin_small">32dp</dimen> <dimen name="margin_small">32dp</dimen>
<dimen name="margin_medium">48dp</dimen> <dimen name="margin_medium">48dp</dimen>

View File

@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">PixelDroid</string> <string name="app_name">PixelDroid</string>
<string name="menu_slideshow">Account name</string>
<string name="menu_subtitle">Account information</string>
<string name="menu_account">My Profile</string> <string name="menu_account">My Profile</string>
<string name="menu_settings">Settings</string> <string name="menu_settings">Settings</string>
<string name="invalid_domain">"Invalid domain"</string> <string name="invalid_domain">"Invalid domain"</string>
@ -10,25 +8,21 @@
<string name="browser_launch_failed">"Could not launch a browser, do you have one?"</string> <string name="browser_launch_failed">"Could not launch a browser, do you have one?"</string>
<string name="auth_failed">"Could not authenticate"</string> <string name="auth_failed">"Could not authenticate"</string>
<string name="token_error">"Error getting token"</string> <string name="token_error">"Error getting token"</string>
<string name="instance_error">"Could not get instance information"</string>
<string name="title_activity_settings2">Settings</string> <string name="title_activity_settings2">Settings</string>
<!-- Theme Preferences --> <!-- Theme Preferences -->
<string name="theme_title">Application Theme</string> <string name="theme_title">Application Theme</string>
<string name="theme_header">Theme</string> <string name="theme_header">Theme</string>
<string name="attachment_summary_off">Only download attachments when manually requested</string>
<string name="followed_notification">%1$s followed you</string> <string name="followed_notification">%1$s followed you</string>
<string name="mention_notification">%1$s mentioned you</string> <string name="mention_notification">%1$s mentioned you</string>
<string name="shared_notification">%1$s shared your post</string> <string name="shared_notification">%1$s shared your post</string>
<string name="liked_notification">%1$s liked your post</string> <string name="liked_notification">%1$s liked your post</string>
<string name="create_a_new_post">Create a new post!</string>
<string name="take_a_picture">Take a picture</string>
<string name="upload_a_picture">Upload a picture</string>
<string name="or">or</string>
<string name="description">Description…</string> <string name="description">Description…</string>
<string name="send">send</string> <string name="send">send</string>
<string name="whats_an_instance">"What's an instance?"</string> <string name="whats_an_instance">"What's an instance?"</string>
<string name="logout">Logout</string> <string name="logout">Log out</string>
<string name="lbl_brightness">BRIGHTNESS</string> <string name="lbl_brightness">BRIGHTNESS</string>
<string name="lbl_contrast">CONTRAST</string> <string name="lbl_contrast">CONTRAST</string>
@ -43,18 +37,15 @@
<string name="capture_button_alt">Capture</string> <string name="capture_button_alt">Capture</string>
<string name="switch_camera_button_alt">Switch camera</string> <string name="switch_camera_button_alt">Switch camera</string>
<string name="gallery_button_alt">Gallery</string> <string name="gallery_button_alt">Gallery</string>
<string name="capture_mode_camera">Camera</string>
<string name="delete_title">Confirm</string>
<string name="share_picture">Share picture…</string> <string name="share_picture">Share picture…</string>
<string name="NoCommentsToShow">No comments on this post…</string> <string name="NoCommentsToShow">No comments on this post…</string>
<string name="CommentDisplay"> to show…</string> <string name="CommentDisplay"> to show…</string>
<string name="domain_of_your_instance">Domain of your instance</string> <string name="domain_of_your_instance">Domain of your instance</string>
<string name="connect_to_pixelfed">Connect to Pixelfed</string> <string name="connect_to_pixelfed">Connect to Pixelfed</string>
<string name="login_connection_required_once">You need to connect to the internet at least once to use PixelDroid :(</string> <string name="login_connection_required_once">You need to be online to be able to add the first account and use PixelDroid :(</string>
<string name="you_are_in_offline_mode">You are in offline mode, but you can still view some content!</string> <string name="you_are_in_offline_mode">You are in offline mode, but you can still view some content!</string>
<string name="enter">Enter</string> <string name="add_account_name">Add Account</string>
<string name="auth_error_toast_msg">Server has responded with an error, try again!</string> <string name="add_account_description">Add another Pixelfed Account</string>
<string name="login_empty_string_error">Instance address cannot be empty!</string>
<string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Hidden Media \n (click to show)</string> <string name="cw_nsfw_hidden_media_n_click_to_show">CW / NSFW / Hidden Media \n (click to show)</string>
</resources> </resources>

View File

@ -6,6 +6,8 @@
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
<item name="materialDrawerStyle">@style/Widget.MaterialDrawerStyle</item>
<item name="materialDrawerHeaderStyle">@style/Widget.MaterialDrawerHeaderStyle</item>
</style> </style>
<style name="AppTheme.Launcher"> <style name="AppTheme.Launcher">
<item name="android:windowBackground">@drawable/theme</item> <item name="android:windowBackground">@drawable/theme</item>
@ -32,4 +34,10 @@
<item name="android:background">@android:color/holo_orange_light</item> <item name="android:background">@android:color/holo_orange_light</item>
<item name="android:textAppearance">@android:style/TextAppearance.Large</item> <item name="android:textAppearance">@android:style/TextAppearance.Large</item>
</style> </style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources> </resources>