Assistant: Hello! How are you today?
User: Hello, translate the following text to Italian: require "import"
import "android.widget.GridView"
import "android.content.Context"
import "android.content.Intent"
import "android.preference.PreferenceManager"
import "cjson"
import "android.speech.SpeechRecognizer"
import "android.speech.RecognitionListener"
import "android.speech.RecognizerIntent"

local context = service.getContext()
local sharedPreferences = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE)
local editor = sharedPreferences.edit()

-- تهيئة متغيرات الإعدادات
local isColloquial = sharedPreferences.getBoolean("isColloquial", true)
local isTranslationEnabled = sharedPreferences.getBoolean("isTranslationEnabled", false)

local sharedPrefs = PreferenceManager.getDefaultSharedPreferences(service)
local storedLanguage = sharedPrefs.getString("selectedLanguage", nil)
local selectedLanguage = storedLanguage or "مصر"

-- تعريف أكواد اللغات وقائمة ترتيبها
local languageCodes = {
  ["مصر"] = "ar-EG"
}
local orderedLanguages = {"مصر"}

-- تصريح مسبق لدالة startListening لاستخدامها لاحقاً
local startListening

-- دالة لتدمير كائن التعرف على الكلام إذا كان موجوداً
local function destroySpeechRecognizer()
  if speechRecognizer then
    speechRecognizer.destroy()
    speechRecognizer = nil
  end
end

-- دالة للتحقق من وجود مربع تعديل
local function isEditTextAvailable()
  return service.getEditText() ~= nil
end

-- دالة عرض قائمة الإعدادات (العامية/الفصحى + الترجمة)
local function showSettingsDialog()
  local layout = {GridView, id = "grid_settings", numColumns = 1, layout_width = "fill", layout_height = "fill"}
  local settingsItems = {
    isColloquial and "الكتابة بالعامية" or "الكتابة بالفصحى",
    isTranslationEnabled and "إيقاف الترجمة" or "تشغيل الترجمة"
  }
  local dlg = LuaDialog(service)
  dlg.View = loadlayout(layout)
  grid_settings.adapter = SingleLineAdapter(service, settingsItems)
  dlg.setTitle("الإعدادات")
  service.speak("الإعدادات")
  task(300, function()
    grid_settings.requestFocus()
    grid_settings.getChildAt(0).requestFocus()
  end)
  dlg.setButton("إغلاق", function() dlg.dismiss() end).show()
  grid_settings.onItemClick = function(_, v)
    if v.text == "الكتابة بالعامية" or v.text == "الكتابة بالفصحى" then
      isColloquial = not isColloquial
      editor.putBoolean("isColloquial", isColloquial)
      editor.apply()
      v.text = isColloquial and "الكتابة بالعامية" or "الكتابة بالفصحى"
      service.speak(v.text)
    elseif v.text == "تشغيل الترجمة" or v.text == "إيقاف الترجمة" then
      isTranslationEnabled = not isTranslationEnabled
      editor.putBoolean("isTranslationEnabled", isTranslationEnabled)
      editor.apply()
      v.text = isTranslationEnabled and "إيقاف الترجمة" or "تشغيل الترجمة"
      service.speak(v.text)
    end
  end
end

-- دالة عرض قائمة اللغات مع خيار الإعدادات (كما في الكود الأساسي)
local function showLanguageDialog()
  local items = orderedLanguages
  local layout = {GridView, id = "grid", numColumns = 1, layout_width = "fill", layout_height = "fill"}
  local dlg = LuaDialog(service)
  dlg.View = loadlayout(layout)
  grid.adapter = SingleLineAdapter(service, items)
  dlg.setTitle("قائمة اللغات")
  service.speak("قائمة اللغات")
  task(300, function()
    grid.requestFocus()
    grid.getChildAt(0).requestFocus()
  end)
  dlg.setButton2("الإعدادات", function() showSettingsDialog() end)
  dlg.setButton("إغلاق", function() dlg.dismiss() end).show()
  grid.onItemClick = function(_, v)
    dlg.dismiss()
    task(150, function()
      local language = v.text
      local languageCode = languageCodes[language]
      if languageCode then
        selectedLanguage = language
        local editor = sharedPreferences.edit()
        editor.putString("selectedLanguage", selectedLanguage)
        editor.apply()
        service.speak("اللغة المختارة: " .. language)
      end
      -- بعد اختيار اللغة يتم بدء الاستماع
      startListening()
    end)
  end
end

-- دالة لترميز النص لاستخدامه في عنوان URL
local function urlEncode(text)
  return tostring(text):gsub("\n", "\r\n"):gsub("([^%w %-%_%.%~])", function(c)
    return string.format("%%%02X", string.byte(c))
  end):gsub(" ", "+")
end

-- قائمة الأسماء اللاتينية الشائعة ومرادفاتها العربية
local latinNames = {
  ["جوجل"] = "Google",
  ["🙏"] = "🤲"
}

-- دالة لتحويل الكلمات اللاتينية المكتوبة بالعربية إلى الأصل اللاتيني
local function convertToLatin(text)
  for arabicName, latinName in pairs(latinNames) do
    text = text:gsub(arabicName, latinName)
  end
  return text
end

-- دالة لتنظيف النص (استجابة الـ API للترجمة)
local function cleanText(text)
  if not text or type(text) ~= "string" then
    return nil -- إرجاع nil إذا لم يكن النص صالحًا
  end
  -- فك تشفير النص باستخدام cjson
  local success, decoded = pcall(cjson.decode, text)
  if not success or not decoded then
    return nil -- إرجاع nil إذا فشلت عملية فك التشفير
  end
  -- التحقق إذا كان هناك استجابة نصية لعمل التنظيف عليها
  if decoded.response and type(decoded.response) == "string" then
    local cleanedText = decoded.response
    -- تنظيف النص باستخدام عدة خطوات لإزالة الرموز والعلامات الغريبة
    cleanedText = cleanedText:match("[*#](.*)") or cleanedText
    cleanedText = cleanedText:gsub("^[#*]*", "")
    cleanedText = cleanedText:match("^(.-)[<*#]") or cleanedText
    cleanedText = cleanedText:gsub("[#*]*$", "")
    cleanedText = convertToLatin(cleanedText) -- تحويل الأسماء إلى اللاتينية
    cleanedText = cleanedText:gsub("^%l", string.upper) -- تحويل أول حرف إلى حرف كبير
    cleanedText = cleanedText:gsub("%s+", " ") -- إزالة المسافات الزائدة
    cleanedText = cleanedText:match("^%s*(.-)%s*$") -- إزالة المسافات الفارغة من البداية والنهاية
    return cleanedText -- إعادة النص بعد التنظيف
  else
    return nil -- إرجاع nil إذا لم يكن هناك نص صالح
  end
end

-- دالة ترجمة النص عند تفعيل الترجمة باستخدام API الخاص بك
local function translateText()
  local node = service.getEditText()
  if node == nil then
    service.speak("عذراً، لا يوجد نص للترجمة.")
    return
  end
  local textToTranslate = service.getText(node)  -- this.getText(node)
  if not textToTranslate or textToTranslate == "" then
    service.speak("النص فارغ، لا يوجد شيء لترجمته.")
    return
  end
  -- صياغة جملة الترجمة لتشمل اللغة المختارة
  local prompt = "Hello, translate the following text to " .. selectedLanguage .. ": " .. textToTranslate
  local encodedPrompt = urlEncode(prompt)
  local url = "https://api-y5s2.onrender.com/ask?model=gpt-3.5-turbo&prompt=" .. encodedPrompt
  Http.get(url, function(status, data)
    if status == 200 then
      local translatedText = cleanText(data)
      if translatedText then
        task(200, function()
          service.setText(node, translatedText)
        end)
        service.speak(translatedText) -- نطق النص المترجم
        service.setClipData(translatedText) -- نسخ النص إلى الحافظة دون نطق رسالة النسخ
      end
    else
      service.speak("عذراً، تعذر الترجمة. يرجى المحاولة لاحقاً.")
    end
  end)
end

-- دالة معالجة النص المستمع إليه (تنفيذ الترجمة أو التصحيح حسب الحالة)
local function processRecognizedText(text)
  if isTranslationEnabled then
    -- عند تفعيل زر الترجمة، يتم إسكات صوت الاستماع ويتم استدعاء وظيفة الترجمة مباشرةً
    translateText()
    return
  end
  local instruction = ""
  if isColloquial then
    instruction = "صحح النص سواء كان كلمة، جملة، أو نص كامل، الذي سأقدمه لك فقط دون إرسال أي تعليقات أو شروحات مع النص."
    if selectedLanguage == "مصر" then
      instruction = instruction .. "\n صحح النص باللغة العربية الدارجة، مع وضع علامات الترقيم المناسبة. (" .. (languageCodes["مصر"] or "ar-EG") .. ")."
    end
    instruction = instruction .. "\nplease provide me processed text without your confirming description.\nThis is the text:\n" .. text
  else
    instruction = "صحح النص سواء كان كلمة، جملة، أو نص كامل، الذي سأقدمه لك فقط دون إرسال أي تعليقات أو شروحات مع النص."
    if selectedLanguage == "مصر" then
      instruction = instruction .. "\n صحح النص باللغة العربية، مع وضع علامات الترقيم المناسبة. (" .. (languageCodes["مصر"] or "ar-EG") .. ")."
    end
    instruction = instruction .. "\nplease provide me processed text without your confirming description.\nThis is the text:\n" .. text
  end
  local encodedQuestion = urlEncode(instruction)
  local url = "https://api-y5s2.onrender.com/ask?model=gpt-3.5-turbo&prompt=Hello" .. encodedQuestion
  Http.get(url, function(status, data)
    if status == 200 then
      local cleanedData = cleanText(data)
      task(200, function()
        local node = service.getEditText()
        if node == nil then
          service.speak("عذراً، لا يتوفر مربع تعديل.")
        else
          if addNewLine then
            service.insert(node, cleanedData .. "\n")
          else
            service.insert(node, cleanedData .. " ")
          end
        end
      end)
      service.speak(cleanedData)
    else
      service.speak("عذرا، الخدمة غير متوفرة حالياً. يرجى المحاولة لاحقاً، ربما تكون في فترة صيانة.")
    end
  end)
end

-- دالة التحقق من وجود اتصال بالإنترنت
local function hasInternetConnection()
  local connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE)
  local networkInfo = connectivityManager.getActiveNetworkInfo()
  return networkInfo ~= nil and networkInfo.isConnected()
end

-- تعريف دالة startListening
startListening = function()
  if not hasInternetConnection() then
    service.asyncSpeak("عذرًا، لا يتوفر اتصال بالإنترنت. يُرجى التحقق من اتصالك بالإنترنت والمحاولة مرة أخرى.")
    return false
  end
  if not isEditTextAvailable() then
    service.asyncSpeak("عذرًا، لا يتوفر مربع تعديل.")
    return false
  end
  destroySpeechRecognizer()
  speechRecognizer = SpeechRecognizer.createSpeechRecognizer(service)
  
  local function getSpeechListener()
    return RecognitionListener {
      onReadyForSpeech = function(params) end,
      onPartialResults = function(partialResults)
        local data = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
        if data and data.size() > 0 then
          local partialText = data.get(0)
          local node = service.getEditText()
          service.setText(node, partialText)
        end
      end,
      onBeginningOfSpeech = function() end,
      onEndOfSpeech = function() end,
      onResults = function(results)
        local data = results.getParcelableArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
        if data and data.size() > 0 then
          local recognizedText = data.get(0)
          processRecognizedText(recognizedText)
        end
        destroySpeechRecognizer()
      end,
      onError = function(error)
        service.asyncSpeak("انتهت مهلة إدخال الكلام.")
        destroySpeechRecognizer()
      end
    }
  end
  
  local recognizerIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
  recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
  recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, languageCodes[selectedLanguage])
  recognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1)
  speechRecognizer.setRecognitionListener(getSpeechListener())
  speechRecognizer.startListening(recognizerIntent)
  return true
end

-- عند بدء التطبيق:
-- إذا كان كائن speechRecognizer موجوداً (مثلاً عند تكرار التنفيذ) يتم عرض قائمة اللغات،
-- أما عند التشغيل الأول فيبدأ الاستماع مباشرةً.
if speechRecognizer then
  destroySpeechRecognizer()
  showLanguageDialog()
else
  local vibrator = context.getSystemService(Context.VIBRATOR_SERVICE)
  if vibrationEnabled then
    vibrator.vibrate(5)
  end
  startListening()
end

return true
Assistant: