Før caching
This commit is contained in:
parent
91f8c2c0c7
commit
5497e68110
4 changed files with 91 additions and 86 deletions
39
app/google-services.json
Normal file
39
app/google-services.json
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"project_info": {
|
||||
"project_number": "738325360287",
|
||||
"project_id": "intranet-glogin-452614",
|
||||
"storage_bucket": "intranet-glogin-452614.firebasestorage.app"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:738325360287:android:c97082eedba86b85b43caa",
|
||||
"android_client_info": {
|
||||
"package_name": "com.kbs.kbsintranett"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "738325360287-cidl3plnqv9ei74vm9vm5muustj6eenb.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyC0vrXCWJNLzrgOk1ChWeFpYlqxKPqxUf0"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "738325360287-cidl3plnqv9ei74vm9vm5muustj6eenb.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
|
|
@ -43,14 +43,15 @@ import androidx.activity.result.ActivityResultLauncher;
|
|||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
|
@ -102,11 +103,12 @@ public class FormsFragment extends Fragment {
|
|||
|
||||
private LinearLayout formContainer;
|
||||
private LinearLayout historyContainer;
|
||||
private View historyWrapper; // Wrapper for historikk-modulen
|
||||
private View historyWrapper;
|
||||
private TextView txtStatus;
|
||||
private TextView lblHistory;
|
||||
private ProgressBar loadingSpinner;
|
||||
private ImageView btnToggleHistory;
|
||||
private Toolbar toolbar; // NYTT
|
||||
|
||||
// --- HOVEDSKJEMA STATE ---
|
||||
private Map<String, View> fieldWrappers = new HashMap<>();
|
||||
|
|
@ -118,7 +120,7 @@ public class FormsFragment extends Fragment {
|
|||
private Map<String, View> childInputViews = new HashMap<>();
|
||||
private Map<String, Boolean> childRequiredFieldsMap = new HashMap<>();
|
||||
private Map<String, Uri> childFileUploads = new HashMap<>();
|
||||
// Lagring av Nested Entries
|
||||
|
||||
private List<NestedEntry> nestedEntries = new ArrayList<>();
|
||||
private LinearLayout nestedEntriesContainer;
|
||||
private TextView totalAmountView;
|
||||
|
|
@ -184,12 +186,17 @@ public class FormsFragment extends Fragment {
|
|||
lblHistory = view.findViewById(R.id.lbl_history);
|
||||
loadingSpinner = view.findViewById(R.id.loading_spinner);
|
||||
|
||||
// NYTT: Finn toolbar og sett listener
|
||||
toolbar = view.findViewById(R.id.forms_toolbar);
|
||||
if (toolbar != null) {
|
||||
toolbar.setNavigationOnClickListener(v -> Navigation.findNavController(view).navigateUp());
|
||||
}
|
||||
|
||||
btnToggleHistory = view.findViewById(R.id.btn_toggle_history);
|
||||
if (btnToggleHistory != null) {
|
||||
btnToggleHistory.setOnClickListener(v -> toggleHistoryVisibility());
|
||||
}
|
||||
|
||||
// --- FIKS FOR NULLPOINTER EXCEPTION PÅ LAYOUTTRANSITION ---
|
||||
if (view instanceof ViewGroup) {
|
||||
LayoutTransition transition = ((ViewGroup) view).getLayoutTransition();
|
||||
if (transition == null) {
|
||||
|
|
@ -198,7 +205,6 @@ public class FormsFragment extends Fragment {
|
|||
}
|
||||
transition.enableTransitionType(LayoutTransition.CHANGING);
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
|
||||
if (formContainer == null) {
|
||||
formContainer = new LinearLayout(getContext());
|
||||
|
|
@ -229,11 +235,9 @@ public class FormsFragment extends Fragment {
|
|||
if (historyWrapper == null || btnToggleHistory == null) return;
|
||||
|
||||
if (historyWrapper.getVisibility() == View.VISIBLE) {
|
||||
// Skjul historikk
|
||||
historyWrapper.setVisibility(View.GONE);
|
||||
btnToggleHistory.setImageResource(android.R.drawable.arrow_down_float);
|
||||
} else {
|
||||
// Vis historikk
|
||||
historyWrapper.setVisibility(View.VISIBLE);
|
||||
btnToggleHistory.setImageResource(android.R.drawable.arrow_up_float);
|
||||
}
|
||||
|
|
@ -300,20 +304,17 @@ public class FormsFragment extends Fragment {
|
|||
nestedEntries.clear();
|
||||
updateStatus("");
|
||||
|
||||
// Reset visibility of history on new load
|
||||
// NYTT: Sett tittelen i Toolbaren i stedet for å legge til en TextView
|
||||
if (toolbar != null) {
|
||||
toolbar.setTitle(getCleanTitle(form.title));
|
||||
}
|
||||
|
||||
if (historyWrapper != null) {
|
||||
historyWrapper.setVisibility(View.VISIBLE);
|
||||
if (btnToggleHistory != null) btnToggleHistory.setImageResource(android.R.drawable.arrow_up_float);
|
||||
}
|
||||
|
||||
TextView title = new TextView(getContext());
|
||||
title.setText(getCleanTitle(form.title));
|
||||
title.setTextSize(24);
|
||||
title.setTypeface(null, Typeface.BOLD);
|
||||
title.setTextColor(Color.BLACK);
|
||||
title.setPadding(0, 0, 0, 20);
|
||||
formContainer.addView(title);
|
||||
|
||||
// Beskrivelse legges fortsatt inn som innhold
|
||||
if (form.description != null && !form.description.isEmpty()) {
|
||||
TextView formDesc = new TextView(getContext());
|
||||
String cleanDesc = form.description.replaceFirst("^\\d+\\.\\s*", "");
|
||||
|
|
@ -429,14 +430,13 @@ public class FormsFragment extends Fragment {
|
|||
btnAdd.setBackgroundColor(Color.parseColor("#53AFE9"));
|
||||
btnAdd.setTextColor(Color.WHITE);
|
||||
btnAdd.setOnClickListener(v -> {
|
||||
expandFormModule(); // Trigger expand
|
||||
expandFormModule();
|
||||
int childFormId = 18;
|
||||
if (field.gpnfForm != null) {
|
||||
try {
|
||||
childFormId = Integer.parseInt(field.gpnfForm);
|
||||
} catch (NumberFormatException e) { e.printStackTrace(); }
|
||||
}
|
||||
// NYTT: Sender med felt-ID fra hovedskjemaet (f.eks "25")
|
||||
openChildFormDialog(childFormId, field.id);
|
||||
});
|
||||
container.addView(btnAdd);
|
||||
|
|
@ -455,7 +455,6 @@ public class FormsFragment extends Fragment {
|
|||
container.addView(totalAmountView);
|
||||
}
|
||||
|
||||
// NY SIGNATUR: Tar imot parentFieldId
|
||||
private void openChildFormDialog(int childFormId, String parentFieldId) {
|
||||
if (getActivity() == null) return;
|
||||
ProgressBar pBar = new ProgressBar(getContext());
|
||||
|
|
@ -483,7 +482,6 @@ public class FormsFragment extends Fragment {
|
|||
});
|
||||
}
|
||||
|
||||
// NY SIGNATUR: Tar imot parentFieldId
|
||||
private void showChildFormDialog(GravityForm childForm, String parentFieldId) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
childInputViews.clear();
|
||||
|
|
@ -533,7 +531,6 @@ public class FormsFragment extends Fragment {
|
|||
});
|
||||
}
|
||||
|
||||
// NY SIGNATUR: Tar imot parentFieldId og sender den som meta
|
||||
private void submitChildForm(int childFormId, AlertDialog dialog, String parentFieldId) {
|
||||
JSONObject inputValues = new JSONObject();
|
||||
for (Map.Entry<String, View> entry : childInputViews.entrySet()) {
|
||||
|
|
@ -559,13 +556,9 @@ public class FormsFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
// --- HER ER FIKSEN FOR BUGGEN ---
|
||||
// Vi legger ved en ekstra parameter som forteller Gravity Forms at dette
|
||||
// er en nested entry som hører til et bestemt felt (f.eks "25").
|
||||
if (parentFieldId != null) {
|
||||
textParts.put("gpnf_entry_nested_form_field", RequestBody.create(MultipartBody.FORM, parentFieldId));
|
||||
}
|
||||
// ---------------------------------
|
||||
|
||||
for (Map.Entry<String, Uri> fileEntry : childFileUploads.entrySet()) {
|
||||
String fieldId = fileEntry.getKey();
|
||||
|
|
@ -585,9 +578,6 @@ public class FormsFragment extends Fragment {
|
|||
JsonObject json = response.body().getAsJsonObject();
|
||||
if (json.has("is_valid") && json.get("is_valid").getAsBoolean()) {
|
||||
String entryId = json.has("entry_id") ? json.get("entry_id").getAsString() : "";
|
||||
|
||||
// NB: Tilpass ID-ene her hvis skjema 18 endres.
|
||||
// ID 3 = Beskrivelse, ID 4 = Beløp
|
||||
String desc = getInputValueGeneric(childInputViews.get("3"));
|
||||
String price = getInputValueGeneric(childInputViews.get("4"));
|
||||
addNestedEntry(entryId, desc, price);
|
||||
|
|
@ -661,10 +651,9 @@ public class FormsFragment extends Fragment {
|
|||
Button btnUpload = new Button(getContext());
|
||||
btnUpload.setText("Velg fil / Ta bilde");
|
||||
btnUpload.setOnClickListener(v -> {
|
||||
// Setter state før vi viser dialog
|
||||
pendingFileFieldId = field.id;
|
||||
isSelectingForChild = isChild;
|
||||
expandFormModule(); // Trigger expand
|
||||
expandFormModule();
|
||||
showFileSourceDialog();
|
||||
});
|
||||
TextView txtFileName = new TextView(getContext());
|
||||
|
|
@ -681,23 +670,19 @@ public class FormsFragment extends Fragment {
|
|||
reqMap.put(field.id, field.isRequired);
|
||||
}
|
||||
|
||||
// Hjelpemetode for å vise dialog
|
||||
private void showFileSourceDialog() {
|
||||
String[] options = {"Ta bilde", "Velg fil"};
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle("Last opp vedlegg")
|
||||
.setItems(options, (dialog, which) -> {
|
||||
if (which == 0) {
|
||||
// Ta bilde - SJEKKER PERMISSION FØRST
|
||||
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
openCamera();
|
||||
} else {
|
||||
// Spør om lov
|
||||
requestPermissionLauncher.launch(Manifest.permission.CAMERA);
|
||||
}
|
||||
} else {
|
||||
// Velg fil
|
||||
if (filePickerLauncher != null) {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("*/*");
|
||||
|
|
@ -790,7 +775,7 @@ public class FormsFragment extends Fragment {
|
|||
timeInput.setClickable(true);
|
||||
timeInput.setHint("00:00");
|
||||
timeInput.setOnClickListener(v -> {
|
||||
expandFormModule(); // Trigger expand
|
||||
expandFormModule();
|
||||
Calendar mcurrentTime = Calendar.getInstance();
|
||||
int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
|
||||
int minute = mcurrentTime.get(Calendar.MINUTE);
|
||||
|
|
@ -831,7 +816,7 @@ public class FormsFragment extends Fragment {
|
|||
public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
||||
public void afterTextChanged(Editable s) { evaluateAllConditionalLogic(); }
|
||||
});
|
||||
attachInteractionListener(input); // Add listener
|
||||
attachInteractionListener(input);
|
||||
|
||||
container.addView(input);
|
||||
views.put(field.id, input);
|
||||
|
|
@ -845,7 +830,7 @@ public class FormsFragment extends Fragment {
|
|||
input.setMinLines(3);
|
||||
input.setGravity(android.view.Gravity.TOP | android.view.Gravity.START);
|
||||
|
||||
attachInteractionListener(input); // Add listener
|
||||
attachInteractionListener(input);
|
||||
|
||||
container.addView(input);
|
||||
views.put(field.id, input);
|
||||
|
|
@ -859,7 +844,6 @@ public class FormsFragment extends Fragment {
|
|||
RadioButton rb = new RadioButton(getContext());
|
||||
rb.setText(choice.text);
|
||||
rb.setTag(choice.value);
|
||||
// Also trigger expand on RadioButton click
|
||||
rb.setOnClickListener(v -> {
|
||||
expandFormModule();
|
||||
evaluateAllConditionalLogic();
|
||||
|
|
@ -867,7 +851,6 @@ public class FormsFragment extends Fragment {
|
|||
group.addView(rb);
|
||||
}
|
||||
}
|
||||
// Fallback listener
|
||||
group.setOnCheckedChangeListener((g, i) -> {
|
||||
expandFormModule();
|
||||
evaluateAllConditionalLogic();
|
||||
|
|
@ -879,7 +862,6 @@ public class FormsFragment extends Fragment {
|
|||
|
||||
private void renderSelectField(LinearLayout container, GravityField field, Map<String, View> views, Map<String, Boolean> req) {
|
||||
Spinner spinner = new Spinner(getContext());
|
||||
// Spinner touch listener is tricky, usually set onTouchListener works
|
||||
spinner.setOnTouchListener((v, event) -> {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
expandFormModule();
|
||||
|
|
@ -922,7 +904,6 @@ public class FormsFragment extends Fragment {
|
|||
checkBox.setText(inputDef.label);
|
||||
|
||||
String value = "1";
|
||||
// Fallback
|
||||
if (field.choices != null && i < field.choices.size()) {
|
||||
value = field.choices.get(i).value;
|
||||
}
|
||||
|
|
@ -940,24 +921,20 @@ public class FormsFragment extends Fragment {
|
|||
|
||||
private void renderDateField(LinearLayout container, GravityField field, Map<String, View> views, Map<String, Boolean> req) {
|
||||
EditText dateInput = new EditText(getContext());
|
||||
// --- DATO LØSNING (Fix for Read Only / Dagens Dato) ---
|
||||
if (field.readOnly || (formId == ID_REFUSJON_UTLEGG && "28".equals(field.id))) {
|
||||
// Sett dagens dato
|
||||
SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy", Locale.getDefault());
|
||||
dateInput.setText(df.format(new Date()));
|
||||
|
||||
// Gjør den "read-only" men synlig
|
||||
dateInput.setFocusable(false);
|
||||
dateInput.setClickable(false);
|
||||
dateInput.setEnabled(false);
|
||||
dateInput.setTextColor(Color.BLACK);
|
||||
} else {
|
||||
// Vanlig dato-velger
|
||||
dateInput.setFocusable(false);
|
||||
dateInput.setClickable(true);
|
||||
dateInput.setHint("dd.mm.yyyy");
|
||||
dateInput.setOnClickListener(v -> {
|
||||
expandFormModule(); // Trigger expand
|
||||
expandFormModule();
|
||||
Calendar c = Calendar.getInstance();
|
||||
new DatePickerDialog(getContext(), (view, year, month, dayOfMonth) -> {
|
||||
dateInput.setText(String.format("%02d.%02d.%d", dayOfMonth, month + 1, year));
|
||||
|
|
@ -1361,20 +1338,17 @@ public class FormsFragment extends Fragment {
|
|||
}
|
||||
|
||||
try {
|
||||
// Vis flere oppføringer siden vi nå har scrolle-mulighet øverst
|
||||
int count = Math.min(entries.length(), 20);
|
||||
for (int i = 0; i < count; i++) {
|
||||
JSONObject entry = entries.getJSONObject(i);
|
||||
String date = entry.optString("date_created");
|
||||
|
||||
// Prøv å finne en bedre tittel enn bare dato (f.eks Prosjektnavn eller Sted)
|
||||
String titleText = "Innsendt: " + date;
|
||||
TextView item = new TextView(getContext());
|
||||
item.setText(titleText);
|
||||
item.setPadding(10, 20, 10, 20);
|
||||
item.setBackgroundResource(android.R.drawable.list_selector_background);
|
||||
item.setTextSize(14);
|
||||
// Add click listener to show details
|
||||
item.setOnClickListener(v -> showEntryDetails(entry));
|
||||
View line = new View(getContext());
|
||||
line.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1));
|
||||
|
|
@ -1387,20 +1361,16 @@ public class FormsFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
// NY METODE: Vis detaljer i dialog med delingsknapp
|
||||
private void showEntryDetails(JSONObject entry) {
|
||||
// HVIS dette er Form 16 (Refusjon), må vi først hente vedleggene (som ligger i Form 18)
|
||||
if (formId == ID_REFUSJON_UTLEGG) {
|
||||
Log.d(TAG, "Form 16 detected. Checking for child entries...");
|
||||
String nestedIds = entry.optString("25"); // Felt 25 i Form 16 inneholder ID-ene til vedleggene
|
||||
String nestedIds = entry.optString("25");
|
||||
|
||||
if (!nestedIds.isEmpty()) {
|
||||
Log.d(TAG, "Nested IDs found: " + nestedIds);
|
||||
List<String> ids = new ArrayList<>();
|
||||
|
||||
// ROBUST PARSING AV ID-LISTE
|
||||
if (nestedIds.startsWith("[") && nestedIds.endsWith("]")) {
|
||||
// Dette er en JSON-array streng (f.eks [101, 102])
|
||||
try {
|
||||
JSONArray jsonArray = new JSONArray(nestedIds);
|
||||
for(int i=0; i<jsonArray.length(); i++) {
|
||||
|
|
@ -1410,42 +1380,34 @@ public class FormsFragment extends Fragment {
|
|||
Log.e(TAG, "Failed to parse nested IDs as JSON array", e);
|
||||
}
|
||||
} else {
|
||||
// Dette er en komma-separert streng (f.eks "101, 102")
|
||||
for (String id : nestedIds.split(",")) {
|
||||
ids.add(id.trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (!ids.isEmpty()) {
|
||||
// Vis en "Laster..." dialog mens vi henter data
|
||||
AlertDialog loadingDialog = new AlertDialog.Builder(getContext())
|
||||
.setMessage("Henter vedleggsdetaljer...")
|
||||
.setCancelable(false)
|
||||
.show();
|
||||
|
||||
// Start rekursiv henting
|
||||
StringBuilder accumulatedHtml = new StringBuilder();
|
||||
StringBuilder accumulatedText = new StringBuilder();
|
||||
|
||||
// Legg først til basis-info fra hovedskjemaet
|
||||
appendBasicInfo(entry, accumulatedHtml, accumulatedText);
|
||||
|
||||
fetchChildEntriesRecursive(ids, 0, accumulatedHtml, accumulatedText, loadingDialog);
|
||||
return; // Stopp her, dialogen vises når data er hentet
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "No nested IDs found in field 25.");
|
||||
}
|
||||
}
|
||||
|
||||
// --- STANDARD VISNING (For alle andre skjemaer) ---
|
||||
StringBuilder htmlBuilder = new StringBuilder();
|
||||
StringBuilder textBuilder = new StringBuilder();
|
||||
appendBasicInfo(entry, htmlBuilder, textBuilder);
|
||||
showFinalDialog(htmlBuilder, textBuilder);
|
||||
}
|
||||
|
||||
// Hjelpemetode for å legge til info fra hovedskjemaet
|
||||
private void appendBasicInfo(JSONObject entry, StringBuilder html, StringBuilder text) {
|
||||
try {
|
||||
String date = entry.optString("date_created");
|
||||
|
|
@ -1455,7 +1417,6 @@ public class FormsFragment extends Fragment {
|
|||
if (currentForm != null && currentForm.fields != null) {
|
||||
for (GravityField field : currentForm.fields) {
|
||||
if ("section".equals(field.type) || "html".equals(field.type) || "captcha".equals(field.type)) continue;
|
||||
// Hopp over felt 25 (Vedleggs-IDer) i Form 16, siden vi viser det bedre senere
|
||||
if (formId == ID_REFUSJON_UTLEGG && "25".equals(field.id)) continue;
|
||||
|
||||
String value = "";
|
||||
|
|
@ -1470,8 +1431,6 @@ public class FormsFragment extends Fragment {
|
|||
|
||||
if (!value.trim().isEmpty()) {
|
||||
if ("fileupload".equals(field.type)) {
|
||||
// Håndter filopplastinger (single/multiple)
|
||||
// Her antar vi enkel URL, men for sikkerhets skyld bruker vi extractUrl
|
||||
String cleanUrl = extractUrl(value);
|
||||
if (cleanUrl.startsWith("http")) {
|
||||
html.append("<b>").append(field.label).append(":</b><br>")
|
||||
|
|
@ -1491,27 +1450,20 @@ public class FormsFragment extends Fragment {
|
|||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
// Rekursiv metode for å hente barn-oppføringer (Vedlegg)
|
||||
private void fetchChildEntriesRecursive(List<String> ids, int index, StringBuilder html, StringBuilder text, AlertDialog loader) {
|
||||
if (index >= ids.size()) {
|
||||
// Alle ferdige! Vis dialogen.
|
||||
loader.dismiss();
|
||||
showFinalDialog(html, text);
|
||||
return;
|
||||
}
|
||||
|
||||
String entryId = ids.get(index);
|
||||
Log.d(TAG, "Fetching child entry ID: " + entryId);
|
||||
|
||||
RetrofitClient.getApiService().getSingleEntry(entryId).enqueue(new retrofit2.Callback<JsonElement>() {
|
||||
@Override
|
||||
public void onResponse(retrofit2.Call<JsonElement> call, retrofit2.Response<JsonElement> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
try {
|
||||
JsonObject json = response.body().getAsJsonObject();
|
||||
// I Form 18: Felt 1 = Fil, Felt 3 = Beskrivelse, Felt 4 = Beløp
|
||||
|
||||
// Parse Description and Price
|
||||
String desc = json.has("3") ? json.get("3").getAsString() : "Uten beskrivelse";
|
||||
String price = json.has("4") ? json.get("4").getAsString() : "";
|
||||
|
||||
|
|
@ -1521,11 +1473,9 @@ public class FormsFragment extends Fragment {
|
|||
html.append(desc).append(" (").append(price).append(")<br>");
|
||||
text.append(desc).append(" (").append(price).append(")\n");
|
||||
|
||||
// Parse File Field (ID 1) - Can be multiple files!
|
||||
if (json.has("1")) {
|
||||
JsonElement fileEl = json.get("1");
|
||||
if (fileEl.isJsonArray()) {
|
||||
// It is a real JSON array
|
||||
JsonArray arr = fileEl.getAsJsonArray();
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
String url = arr.get(i).getAsString().replace("\\/", "/");
|
||||
|
|
@ -1533,7 +1483,6 @@ public class FormsFragment extends Fragment {
|
|||
text.append(url).append("\n");
|
||||
}
|
||||
} else {
|
||||
// It is a string. Check if it's a JSON string array like "[\"http...\"]"
|
||||
String rawString = fileEl.getAsString();
|
||||
if (rawString.startsWith("[") && rawString.endsWith("]")) {
|
||||
try {
|
||||
|
|
@ -1544,13 +1493,11 @@ public class FormsFragment extends Fragment {
|
|||
text.append(url).append("\n");
|
||||
}
|
||||
} catch (JSONException ex) {
|
||||
// Fallback: simple cleanup
|
||||
String clean = extractUrl(rawString);
|
||||
html.append("<a href=\"").append(clean).append("\">Åpne fil</a><br>");
|
||||
text.append(clean).append("\n");
|
||||
}
|
||||
} else {
|
||||
// Just a plain URL string
|
||||
String clean = extractUrl(rawString);
|
||||
if(clean.startsWith("http")) {
|
||||
html.append("<a href=\"").append(clean).append("\">Åpne fil</a><br>");
|
||||
|
|
@ -1565,17 +1512,12 @@ public class FormsFragment extends Fragment {
|
|||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error parsing child entry", e);
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Failed to fetch child entry: " + response.code());
|
||||
}
|
||||
// Gå til neste (uansett om denne feilet eller ei)
|
||||
fetchChildEntriesRecursive(ids, index + 1, html, text, loader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(retrofit2.Call<JsonElement> call, Throwable t) {
|
||||
Log.e(TAG, "Network error fetching child entry", t);
|
||||
// Hopp over ved feil
|
||||
fetchChildEntriesRecursive(ids, index + 1, html, text, loader);
|
||||
}
|
||||
});
|
||||
|
|
@ -1598,7 +1540,6 @@ public class FormsFragment extends Fragment {
|
|||
.show();
|
||||
}
|
||||
|
||||
// Hjelpemetode for å rydde opp i URLer fra JSON (f.eks ["http://..."] -> http://...)
|
||||
private String extractUrl(String rawValue) {
|
||||
if (rawValue == null) return "";
|
||||
String clean = rawValue.replace("[", "")
|
||||
|
|
|
|||
|
|
@ -8,6 +8,25 @@
|
|||
android:background="#F5F5F5"
|
||||
tools:context=".FormsFragment">
|
||||
|
||||
<!-- NYTT: Toolbar med tilbake-knapp -->
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Light">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/forms_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/white"
|
||||
app:navigationIcon="@android:drawable/ic_menu_revert"
|
||||
app:titleTextColor="@color/black"
|
||||
app:title="Laster..." />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<!-- Resten er likt, men nå under toolbaren -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/history_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/white">
|
||||
|
|
@ -91,12 +92,17 @@
|
|||
android:text="Av: Forfatter"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- BYTTET FRA TextView TIL WebView -->
|
||||
<!--
|
||||
WebView for innhold.
|
||||
tools:ignore="WebViewLayout" hindrer feilmeldingen om wrap_content,
|
||||
da dette er ønsket oppførsel inne i en NestedScrollView.
|
||||
-->
|
||||
<WebView
|
||||
android:id="@+id/detail_webview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none" />
|
||||
android:scrollbars="none"
|
||||
tools:ignore="WebViewLayout" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
|
|
|||
Loading…
Reference in a new issue