Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ app.*.map.json
/android/app/build/
/android/build/
keystore_base64.txt

graphify-out*
*.txt*
20 changes: 20 additions & 0 deletions README_ES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# NFile - Traduccion al Espanol

Traduccion completa de la aplicacion NFile al espanol.

## Cambios realizados

- **Todos los textos de la interfaz** traducidos al espanol (~1000 strings en 55+ archivos Dart)
- **Notificaciones de Android** traducidas (FTP, Web Sharing, Audio Player, Archive Operations)
- **Sistema de localizacion** implementado en `lib/core/app_strings.dart` con soporte para ingles y espanol
- **APK compilado** listo para instalar

## Creditos

- Traduccion por: Skuuill
- Contacto: moreappmic@gmail.com
- App original: [NFile](https://github.com/MSOB7YY/NFile)

## Licencia

GNU GPL v3 (igual que el proyecto original)
2 changes: 1 addition & 1 deletion android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ android {
versionCode = flutter.versionCode
versionName = flutter.versionName
androidResources {
localeFilters.addAll(listOf("en"))
localeFilters.addAll(listOf("en", "es"))
}
}

Expand Down
41 changes: 41 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,37 @@
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>

<!-- Registro como gestor de archivos del sistema -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.APP_FILES" />
</intent-filter>

<!-- Modo Seleccionador (Picker) -->
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="*/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
<data android:mimeType="image/*" />
<data android:mimeType="video/*" />
<data android:mimeType="audio/*" />
</intent-filter>

<!-- Explorar almacenamiento -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="content" />
<data android:mimeType="vnd.android.document/root" />
</intent-filter>
</activity>

<activity-alias
Expand Down Expand Up @@ -186,6 +217,16 @@
</intent-filter>
</provider>

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>

<service
android:name=".FtpForegroundService"
android:enabled="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ class FtpForegroundService : Service() {
}

val notification = builder
.setContentTitle("NFile FTP Server")
.setContentText("Running at ftp://$ip:$port")
.setContentTitle(getString(R.string.ftp_server_title))
.setContentText(getString(R.string.ftp_server_running, ip, port))
.setSmallIcon(iconResId)
.setContentIntent(pendingIntent)
.setOngoing(true)
Expand All @@ -67,8 +67,8 @@ class FtpForegroundService : Service() {

private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "FTP Server"
val descriptionText = "Displays status of the background FTP Server"
val name = getString(R.string.ftp_server_channel_name)
val descriptionText = getString(R.string.ftp_server_channel_desc)
val importance = NotificationManager.IMPORTANCE_LOW
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
description = descriptionText
Expand Down
43 changes: 39 additions & 4 deletions android/app/src/main/kotlin/com/rubex/nfile/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class MainActivity : AudioServiceFragmentActivity() {
private var pendingPermissionResult: MethodChannel.Result? = null
private var safPermissionResult: MethodChannel.Result? = null
private val SAF_REQUEST_CODE = 10002
private var isPickerMode = false

private val ACTION_CANCEL_OPERATION = "com.rubex.nfile.ACTION_CANCEL_OPERATION"
private var notificationsChannel: MethodChannel? = null
Expand All @@ -66,6 +67,7 @@ class MainActivity : AudioServiceFragmentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
isPickerMode = intent?.action == Intent.ACTION_GET_CONTENT || intent?.action == Intent.ACTION_PICK
try {
Shizuku.addBinderReceivedListenerSticky {
// Binder ready
Expand Down Expand Up @@ -140,6 +142,39 @@ class MainActivity : AudioServiceFragmentActivity() {

override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)

MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.rubex.nfile/picker").setMethodCallHandler { call, result ->
when (call.method) {
"isPickerMode" -> result.success(isPickerMode)
"finishWithResult" -> {
val filePath = call.argument<String>("path")
if (filePath != null) {
try {
val file = File(filePath)
val uri = androidx.core.content.FileProvider.getUriForFile(
this@MainActivity,
"${applicationContext.packageName}.fileprovider",
file
)
val resultIntent = Intent().apply {
data = uri
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
}
setResult(android.app.Activity.RESULT_OK, resultIntent)
finish()
result.success(true)
} catch (e: Exception) {
e.printStackTrace()
result.success(false)
}
} else {
result.success(false)
}
}
else -> result.notImplemented()
}
}

MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
when (call.method) {
"checkStatus" -> {
Expand Down Expand Up @@ -710,11 +745,11 @@ class MainActivity : AudioServiceFragmentActivity() {
notificationsChannel?.setMethodCallHandler { call, result ->
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channelId = "nfile_archive_channel"
val channelName = "NFile Archive Operations"
val channelName = getString(R.string.archive_channel_name)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW).apply {
description = "Shows progress of file compression and extraction"
description = getString(R.string.archive_channel_desc)
}
notificationManager.createNotificationChannel(channel)
}
Expand Down Expand Up @@ -762,8 +797,8 @@ class MainActivity : AudioServiceFragmentActivity() {
.setContentIntent(openPendingIntent)

if (progress < max) {
builder.addAction(android.R.drawable.ic_menu_view, "Open", openPendingIntent)
builder.addAction(android.R.drawable.ic_menu_close_clear_cancel, "Cancel", cancelPendingIntent)
builder.addAction(android.R.drawable.ic_menu_view, "Abrir", openPendingIntent)
builder.addAction(android.R.drawable.ic_menu_close_clear_cancel, "Cancelar", cancelPendingIntent)
}

if (indeterminate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ class NFileDocumentsProvider : DocumentsProvider() {
row.add(DocumentsContract.Root.COLUMN_DOCUMENT_ID, getDocIdForFile(File("/storage/emulated/0")))
row.add(DocumentsContract.Root.COLUMN_MIME_TYPES, "*/*")
row.add(DocumentsContract.Root.COLUMN_FLAGS, flags)
row.add(DocumentsContract.Root.COLUMN_TITLE, "NFile Storage")
row.add(DocumentsContract.Root.COLUMN_SUMMARY, "Internal storage via NFile")
row.add(DocumentsContract.Root.COLUMN_ICON, android.R.drawable.sym_def_app_icon)
row.add(DocumentsContract.Root.COLUMN_TITLE, context?.getString(R.string.storage_provider_title) ?: "NFile Storage")
row.add(DocumentsContract.Root.COLUMN_SUMMARY, context?.getString(R.string.storage_provider_desc) ?: "Internal storage via NFile")
row.add(DocumentsContract.Root.COLUMN_ICON, R.mipmap.ic_launcher)

try {
val stat = android.os.StatFs("/storage/emulated/0")
Expand Down Expand Up @@ -112,6 +112,15 @@ class NFileDocumentsProvider : DocumentsProvider() {
return getDocIdForFile(file)
}

override fun renameDocument(documentId: String?, displayName: String?): String {
val file = getFileForDocId(documentId ?: "")
val newFile = File(file.parentFile, displayName ?: file.name)
if (!file.renameTo(newFile)) {
throw FileNotFoundException("Failed to rename document: $documentId")
}
return getDocIdForFile(newFile)
}

override fun deleteDocument(documentId: String?) {
val file = getFileForDocId(documentId ?: "")
if (!file.deleteRecursively()) {
Expand Down Expand Up @@ -153,7 +162,8 @@ class NFileDocumentsProvider : DocumentsProvider() {

private fun includeFile(result: MatrixCursor, docId: String?, file: File) {
val flags = DocumentsContract.Document.FLAG_SUPPORTS_DELETE or
DocumentsContract.Document.FLAG_SUPPORTS_WRITE
DocumentsContract.Document.FLAG_SUPPORTS_WRITE or
DocumentsContract.Document.FLAG_SUPPORTS_RENAME

val mimeType = getMimeType(file)
val finalFlags = if (mimeType == DocumentsContract.Document.MIME_TYPE_DIR) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ class WebSharingForegroundService : Service() {
Notification.Builder(this)
}

val title = if (isInternet) "NFile Internet Web Share" else "NFile Local Web Share"
val title = if (isInternet) getString(R.string.web_share_internet) else getString(R.string.web_share_local)

val notification = builder
.setContentTitle(title)
.setContentText("Running at $url")
.setContentText(getString(R.string.web_share_running, url))
.setSmallIcon(iconResId)
.setContentIntent(pendingIntent)
.setOngoing(true)
Expand All @@ -69,8 +69,8 @@ class WebSharingForegroundService : Service() {

private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "Web Sharing Server"
val descriptionText = "Displays status of the background Web Sharing Server"
val name = getString(R.string.web_share_channel_name)
val descriptionText = getString(R.string.web_share_channel_desc)
val importance = NotificationManager.IMPORTANCE_LOW
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
description = descriptionText
Expand Down
19 changes: 19 additions & 0 deletions android/app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="ftp_server_title">Servidor FTP NFile</string>
<string name="ftp_server_running">Ejecutándose en ftp://%1$s:%2$d</string>
<string name="ftp_server_channel_name">Servidor FTP</string>
<string name="ftp_server_channel_desc">Muestra el estado del Servidor FTP en segundo plano</string>

<string name="archive_channel_name">Operaciones de Archivo NFile</string>
<string name="archive_channel_desc">Muestra el progreso de compresión y extracción de archivos</string>

<string name="storage_provider_title">Almacenamiento NFile</string>
<string name="storage_provider_desc">Almacenamiento interno vía NFile</string>

<string name="web_share_internet">NFile Compartición Web por Internet</string>
<string name="web_share_local">NFile Compartición Web Local</string>
<string name="web_share_running">Ejecutándose en %1$s</string>
<string name="web_share_channel_name">Servidor de Compartición Web</string>
<string name="web_share_channel_desc">Muestra el estado del Servidor de Compartición Web en segundo plano</string>
</resources>
19 changes: 19 additions & 0 deletions android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="ftp_server_title">NFile FTP Server</string>
<string name="ftp_server_running">Running at ftp://%1$s:%2$d</string>
<string name="ftp_server_channel_name">FTP Server</string>
<string name="ftp_server_channel_desc">Displays status of the background FTP Server</string>

<string name="archive_channel_name">NFile Archive Operations</string>
<string name="archive_channel_desc">Shows progress of file compression and extraction</string>

<string name="storage_provider_title">NFile Storage</string>
<string name="storage_provider_desc">Internal storage via NFile</string>

<string name="web_share_internet">NFile Internet Web Share</string>
<string name="web_share_local">NFile Local Web Share</string>
<string name="web_share_running">Running at %1$s</string>
<string name="web_share_channel_name">Web Sharing Server</string>
<string name="web_share_channel_desc">Displays status of the background Web Sharing Server</string>
</resources>
8 changes: 8 additions & 0 deletions android/app/src/main/res/xml/file_paths.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="." />
<external-files-path name="external_files_path" path="." />
<cache-path name="cache" path="." />
<external-cache-path name="external_cache" path="." />
<files-path name="files" path="." />
</paths>
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
Loading
Loading