Rewrite: Complete Release Tweaks

This commit is contained in:
Daniel 2025-11-16 21:10:12 +03:00
parent 188bc459b1
commit 300fceae98
11 changed files with 45 additions and 51 deletions

View file

@ -4,11 +4,11 @@ plugins {
}
android {
namespace = "com.example.vedroid"
namespace = "com.example.androidsshclient"
compileSdk = 34
defaultConfig {
applicationId = "com.example.vedroid"
applicationId = "com.example.androidsshclient"
minSdk = 21
targetSdk = 34
versionCode = 1

View file

@ -9,7 +9,7 @@
<application
android:allowBackup="false"
android:icon="@drawable/ic_launcher"
android:label="Vedroid SSH Client"
android:label="Android SSH Client"
android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
<!-- Главный экран -->

View file

@ -1,4 +1,4 @@
package com.example.vedroid
package com.example.androidsshclient
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

View file

@ -1,7 +1,7 @@
package com.example.vedroid
package com.example.androidsshclient
import android.content.SharedPreferences
import android.content.Intent // ✅ Добавляем этот импорт
import android.content.Intent
import android.os.Bundle
import android.widget.*
import androidx.appcompat.app.AlertDialog
@ -13,7 +13,7 @@ import com.jcraft.jsch.ChannelExec
import com.jcraft.jsch.JSch
import org.json.JSONArray
import org.json.JSONObject
import com.example.vedroid.model.SshProfile
import com.example.androidsshclient.model.SshProfile
class SshActivity : AppCompatActivity() {
@ -27,7 +27,7 @@ class SshActivity : AppCompatActivity() {
private lateinit var profilesSpinner: Spinner
private lateinit var saveProfileButton: Button
private lateinit var deleteProfileButton: Button
private lateinit var terminalButton: Button // ✅ Добавляем terminalButton
private lateinit var terminalButton: Button
private val jsch = JSch()
private lateinit var prefs: SharedPreferences
@ -55,7 +55,7 @@ class SshActivity : AppCompatActivity() {
profilesSpinner = findViewById(R.id.profilesSpinner)
saveProfileButton = findViewById(R.id.saveProfileButton)
deleteProfileButton = findViewById(R.id.deleteProfileButton)
terminalButton = findViewById(R.id.terminalButton) // ✅ Инициализируем terminalButton
terminalButton = findViewById(R.id.terminalButton)
executeButton.isEnabled = false
@ -94,7 +94,7 @@ class SshActivity : AppCompatActivity() {
deleteCurrentProfile()
}
terminalButton.setOnClickListener { // ✅ Добавляем обработчик для terminalButton
terminalButton.setOnClickListener {
val position = profilesSpinner.selectedItemPosition
if (position > 0) {
val profile = profiles[position - 1]
@ -160,14 +160,13 @@ class SshActivity : AppCompatActivity() {
}
prefs.edit().putString("profiles", jsonArray.toString()).apply()
loadProfiles() // Reload to update spinner
loadProfiles()
}
private fun showSaveProfileDialog() {
val dialogView = layoutInflater.inflate(R.layout.dialog_save_profile, null)
val nameInput = dialogView.findViewById<EditText>(R.id.profileNameInput)
// Pre-fill with current connection details
nameInput.setText("${usernameInput.text}@${hostInput.text}")
AlertDialog.Builder(this)
@ -192,14 +191,13 @@ class SshActivity : AppCompatActivity() {
password = passwordInput.text.toString()
)
profiles.removeAll { it.name == name } // Remove existing with same name
profiles.removeAll { it.name == name }
profiles.add(profile)
saveProfiles()
// Select the newly saved profile
profilesSpinner.setSelection(adapter.getPosition(name))
appendOutput("Profile '$name' saved")
appendOutput("Profile '$name' saved")
}
private fun deleteCurrentProfile() {
@ -213,7 +211,7 @@ class SshActivity : AppCompatActivity() {
profiles.removeAt(position - 1)
saveProfiles()
profilesSpinner.setSelection(0) // Select "New Profile"
appendOutput("🗑️ Profile '${profile.name}' deleted")
appendOutput("Profile '${profile.name}' deleted")
}
.setNegativeButton("Cancel", null)
.show()
@ -226,7 +224,7 @@ class SshActivity : AppCompatActivity() {
usernameInput.setText(profile.username)
passwordInput.setText(profile.password)
appendOutput("📁 Loaded profile: ${profile.name}")
appendOutput("Loaded profile: ${profile.name}")
}
private fun connectSsh() {
@ -236,28 +234,28 @@ class SshActivity : AppCompatActivity() {
val password = passwordInput.text.toString()
if (host.isEmpty() || username.isEmpty() || password.isEmpty()) {
appendOutput("Please fill all fields")
appendOutput("Please fill all fields")
return
}
GlobalScope.launch(Dispatchers.IO) {
try {
appendOutput("🔌 Connecting to $host:$port...")
appendOutput("Connecting to $host:$port...")
val session = jsch.getSession(username, host, port).apply {
setPassword(password)
setConfig("StrictHostKeyChecking", "no") // ⚠️ Only for testing!
setConfig("StrictHostKeyChecking", "no")
connect(30000) // 30 second timeout
}
appendOutput("Connected successfully!")
appendOutput("Connected successfully!")
runOnUiThread {
executeButton.isEnabled = true
}
} catch (e: Exception) {
appendOutput("Connection failed: ${e.message}")
appendOutput("Connection failed: ${e.message}")
e.printStackTrace()
}
}
@ -270,13 +268,13 @@ class SshActivity : AppCompatActivity() {
val password = passwordInput.text.toString()
if (host.isEmpty() || username.isEmpty() || password.isEmpty()) {
appendOutput("Please fill all fields")
appendOutput("Please fill all fields")
return
}
GlobalScope.launch(Dispatchers.IO) {
try {
appendOutput("💻 Executing: $command")
appendOutput("Executing: $command")
val session = jsch.getSession(username, host, port).apply {
setPassword(password)
@ -300,16 +298,16 @@ class SshActivity : AppCompatActivity() {
runOnUiThread {
if (output.isNotEmpty()) {
appendOutput("📄 Output:\n$output")
appendOutput("Output:\n$output")
}
if (error.isNotEmpty()) {
appendOutput("⚠️ Error:\n$error")
appendOutput("Error:\n$error")
}
appendOutput("🔚 Command completed")
appendOutput("Command completed")
}
} catch (e: Exception) {
appendOutput("SSH operation failed: ${e.message}")
appendOutput("SSH operation failed: ${e.message}")
e.printStackTrace()
}
}
@ -323,7 +321,6 @@ class SshActivity : AppCompatActivity() {
}
}
// Простой data class для профилей
data class SshProfile(
val name: String,
val host: String,

View file

@ -1,4 +1,4 @@
package com.example.vedroid
package com.example.androidsshclient
import android.os.Bundle
import android.text.method.ScrollingMovementMethod
@ -113,7 +113,7 @@ class TerminalActivity : AppCompatActivity() {
private fun connectToTerminal(host: String, port: Int, username: String, password: String) {
terminalScope.launch(Dispatchers.IO) {
try {
appendToTerminal("🔌 Connecting to $host:$port...\n")
appendToTerminal("Connecting to $host:$port...\n")
val session = jsch.getSession(username, host, port).apply {
setPassword(password)
@ -146,8 +146,8 @@ class TerminalActivity : AppCompatActivity() {
isConnected = true
appendToTerminal("Connected to SSH terminal\n")
appendToTerminal("💡 Type commands in the input field below\n\n")
appendToTerminal("Connected to SSH terminal\n")
appendToTerminal("Type commands in the input field below\n\n")
// Запускаем чтение вывода
launch(Dispatchers.IO) {
@ -155,7 +155,7 @@ class TerminalActivity : AppCompatActivity() {
}
} catch (e: Exception) {
appendToTerminal("Connection failed: ${e.message}\n")
appendToTerminal("Connection failed: ${e.message}\n")
}
}
}
@ -175,7 +175,7 @@ class TerminalActivity : AppCompatActivity() {
}
} catch (e: Exception) {
if (isConnected) {
appendToTerminal("\nConnection lost\n")
appendToTerminal("\nConnection lost\n")
}
} finally {
disconnect()
@ -213,7 +213,7 @@ class TerminalActivity : AppCompatActivity() {
outputStream?.write("$command\n".toByteArray(StandardCharsets.UTF_8))
outputStream?.flush()
} catch (e: Exception) {
appendToTerminal("Error sending command\n")
appendToTerminal("Error sending command\n")
}
}
@ -252,7 +252,7 @@ class TerminalActivity : AppCompatActivity() {
outputStream?.flush()
appendToTerminal("^C\n")
} catch (e: Exception) {
appendToTerminal("Error sending Ctrl+C\n")
appendToTerminal("Error sending Ctrl+C\n")
}
}
}
@ -266,7 +266,7 @@ class TerminalActivity : AppCompatActivity() {
outputStream?.flush()
appendToTerminal("^D\n")
} catch (e: Exception) {
appendToTerminal("Error sending Ctrl+D\n")
appendToTerminal("Error sending Ctrl+D\n")
}
}
}
@ -301,7 +301,7 @@ class TerminalActivity : AppCompatActivity() {
} catch (e: Exception) {
// Ignore
}
appendToTerminal("\n🔌 Disconnected\n")
appendToTerminal("\nDisconnected\n")
}
override fun onDestroy() {

View file

@ -1,4 +1,4 @@
package com.example.vedroid.model
package com.example.androidsshclient.model
// Теперь не нужно Serializable
data class SshProfile(

View file

@ -8,7 +8,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SSH Client with Profiles"
android:text="SSH Client"
android:textSize="24sp"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="20dp" />
@ -31,7 +31,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="💾"
android:text="Save Profile"
android:layout_marginEnd="4dp" />
<Button
@ -39,7 +39,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="🗑️"
android:text="Delete Profile"
android:layout_marginStart="4dp" />
</LinearLayout>
@ -106,12 +106,11 @@
android:text="Execute: ls -la"
android:layout_marginTop="8dp" />
<!-- Добавляем после executeButton -->
<Button
android:id="@+id/terminalButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="🖥️ Open Interactive Terminal"
android:text="Open Interactive Terminal"
android:layout_marginBottom="8dp"
android:backgroundTint="#4CAF50" />

View file

@ -111,7 +111,7 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="💡 Use ↑↓ for command history"
android:text="Use scroll for command history"
android:textSize="12sp"
android:textColor="#AAAAAA"
android:gravity="center"

View file

@ -1,4 +1,4 @@
<resources>
<string name="app_name">Vedroid</string>
<string name="app_name">Android</string>
<string name="hello_world">Hello World!</string>
</resources>

View file

@ -1,6 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Vedroid" parent="Theme.AppCompat.Light.DarkActionBar">
<style name="Theme.Android" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">#3F51B5</item>
<item name="colorPrimaryVariant">#303F9F</item>