diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 230d7dd..74369ec 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.kbs.kbsintranett" minSdk = 28 targetSdk = 34 - versionCode = 2 - versionName = "1.2" + versionCode = 3 + versionName = "1.4" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/com/kbs/kbsintranett/CreateEventFragment.java b/app/src/main/java/com/kbs/kbsintranett/CreateEventFragment.java index 0938f12..07500a1 100644 --- a/app/src/main/java/com/kbs/kbsintranett/CreateEventFragment.java +++ b/app/src/main/java/com/kbs/kbsintranett/CreateEventFragment.java @@ -3,6 +3,8 @@ package com.kbs.kbsintranett; import android.app.AlertDialog; import android.app.DatePickerDialog; import android.app.TimePickerDialog; +import android.graphics.Color; +import android.graphics.Typeface; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; @@ -134,13 +136,11 @@ public class CreateEventFragment extends Fragment { private void prefillForm(CalendarEvent event) { etTitle.setText(event.getTitle()); - // Rens beskrivelsen for #varsel tag String cleanDesc = event.getDescription().replaceAll("#varsel:[\\d,]+", "").trim(); etDesc.setText(cleanDesc); etLocation.setText(event.getLocation()); // --- FIKS 404 FEIL VED OPPDATERING --- - // 1. Sett spinneren til riktig kalender ArrayAdapter adapter = (ArrayAdapter) spinnerCalendar.getAdapter(); if (adapter != null) { int position = adapter.getPosition(event.getCalendarName()); @@ -148,12 +148,9 @@ public class CreateEventFragment extends Fragment { spinnerCalendar.setSelection(position); } } - // 2. Deaktiver spinneren. Man kan ikke bytte kalender ved oppdatering (API-begrensning). - // Man må slette og opprette på nytt for å flytte. spinnerCalendar.setEnabled(false); // ------------------------------------- - // Dato-parsing try { SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault()); SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); @@ -161,7 +158,6 @@ public class CreateEventFragment extends Fragment { String start = event.getRawDate(); if (start != null) { if (start.length() == 10) { - // Heldags switchAllDay.setChecked(true); Date d = simpleFormat.parse(start); startCal.setTime(d); @@ -176,7 +172,6 @@ public class CreateEventFragment extends Fragment { endCal.setTime(d); } } else if (start.contains("T")) { - // Vanlig tid (kutt tidssone) if (start.length() > 19) start = start.substring(0, 19); startCal.setTime(isoFormat.parse(start)); @@ -191,10 +186,8 @@ public class CreateEventFragment extends Fragment { } } - // Varsler List existingReminders = event.getReminders(); if (!existingReminders.isEmpty()) { - // Fjern alle sjekkmerker først (15 min er default checked) for (int i = 0; i < chipGroupReminders.getChildCount(); i++) { ((Chip) chipGroupReminders.getChildAt(i)).setChecked(false); } @@ -217,14 +210,67 @@ public class CreateEventFragment extends Fragment { } } - private void setupCalendarSpinner() { - // HENT DYNAMISK LISTE FRA USERMANAGER - List calendars = UserManager.getInstance().getWriteableCalendars(); + // --- NY LOGIKK FOR FARGER I SPINNER --- + private String getCalendarColor(String name) { + // Matcher fargene i PHP-config (V12.6) + switch (name) { + case "Felles": return "#0069B3"; // KBS Blå + case "Administrasjonen": return "#607D8B"; // Blue Grey + case "Serviceavdelingen": return "#E65100"; // Orange + case "Automasjonsavdelingen": return "#2E7D32"; // Green + case "Prosjektavdelingen": return "#7B1FA2"; // Purple + default: return "#888888"; // Grå fallback + } + } + + private void setupCalendarSpinner() { + List calendars = UserManager.getInstance().getWriteableCalendars(); if (calendars.isEmpty()) calendars.add("Felles"); - spinnerCalendar.setAdapter(new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_dropdown_item, calendars)); + // Vi bruker en Custom Adapter for å styre farger + ArrayAdapter adapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item, calendars) { + + // getView: Dette er det som vises i selve boksen når noe er valgt + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + TextView view = (TextView) super.getView(position, convertView, parent); + + String calName = getItem(position); + String colorHex = getCalendarColor(calName); + + // Sett bakgrunnsfarge lik kalenderfarge + view.setBackgroundColor(Color.parseColor(colorHex)); + + // Hvit tekst for kontrast + view.setTextColor(Color.WHITE); + view.setTypeface(null, Typeface.BOLD); + + return view; + } + + // getDropDownView: Dette er listen som popper opp + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + TextView view = (TextView) super.getDropDownView(position, convertView, parent); + + String calName = getItem(position); + String colorHex = getCalendarColor(calName); + + // Her holder vi bakgrunnen hvit, men farger teksten + view.setBackgroundColor(Color.WHITE); + view.setTextColor(Color.parseColor(colorHex)); + view.setTypeface(null, Typeface.BOLD); + + return view; + } + }; + + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinnerCalendar.setAdapter(adapter); } + // -------------------------------------- private void setupReminderChips() { addChip("Ved start", 0); @@ -475,7 +521,6 @@ public class CreateEventFragment extends Fragment { } } - // NY: Henter navnet på kalenderen direkte fra Spinneren private String getCalendarSlug() { if (spinnerCalendar.getSelectedItem() != null) { return spinnerCalendar.getSelectedItem().toString(); diff --git a/app/src/main/java/com/kbs/kbsintranett/HomeFragment.java b/app/src/main/java/com/kbs/kbsintranett/HomeFragment.java index ca11c26..a871508 100644 --- a/app/src/main/java/com/kbs/kbsintranett/HomeFragment.java +++ b/app/src/main/java/com/kbs/kbsintranett/HomeFragment.java @@ -20,6 +20,7 @@ import androidx.fragment.app.Fragment; import androidx.navigation.Navigation; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.work.PeriodicWorkRequest; import androidx.work.WorkManager; import java.text.SimpleDateFormat; @@ -37,7 +38,10 @@ public class HomeFragment extends Fragment { private ActivityResultLauncher requestPermissionLauncher; private RecyclerView calendarRecycler; private RecyclerView newsRecycler; - private ProgressBar mainProgressBar; // Variabelen som må være her + private ProgressBar mainProgressBar; + private SwipeRefreshLayout swipeRefreshLayout; + + private int activeNetworkCalls = 0; @Override public void onCreate(@Nullable Bundle savedInstanceState) { @@ -46,7 +50,7 @@ public class HomeFragment extends Fragment { new ActivityResultContracts.RequestPermission(), isGranted -> { if (calendarRecycler != null) { - fetchCalendarEvents(calendarRecycler); + refreshData(); } } ); @@ -63,11 +67,12 @@ public class HomeFragment extends Fragment { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - // Her leter vi etter IDen som MÅ finnes i XML-filen over mainProgressBar = view.findViewById(R.id.main_loading_spinner); - if (mainProgressBar != null) mainProgressBar.setVisibility(View.VISIBLE); + swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_home); + swipeRefreshLayout.setOnRefreshListener(this::refreshData); + View profileBtn = view.findViewById(R.id.btn_profile); if (profileBtn != null) { profileBtn.setOnClickListener(v -> Navigation.findNavController(view).navigate(R.id.navigation_profile)); @@ -75,7 +80,6 @@ public class HomeFragment extends Fragment { Button btnCreateEvent = view.findViewById(R.id.btn_create_event); List writeable = UserManager.getInstance().getWriteableCalendars(); - if (writeable != null && !writeable.isEmpty()) { btnCreateEvent.setVisibility(View.VISIBLE); btnCreateEvent.setOnClickListener(v -> { @@ -85,6 +89,7 @@ public class HomeFragment extends Fragment { btnCreateEvent.setVisibility(View.GONE); } + // KALENDER: Standard scrolling (slik at man kan scrolle i vinduet på 230dp) calendarRecycler = view.findViewById(R.id.recycler_calendar); calendarRecycler.setLayoutManager(new LinearLayoutManager(getContext())); calendarRecycler.setAdapter(new CalendarAdapter(new ArrayList<>(), event -> {})); @@ -100,6 +105,7 @@ public class HomeFragment extends Fragment { } } + // NYHETER: Nested scrolling disabled (skal vises i full høyde under kalenderen) newsRecycler = view.findViewById(R.id.recycler_news); newsRecycler.setLayoutManager(new LinearLayoutManager(getContext())); newsRecycler.setNestedScrollingEnabled(false); @@ -112,22 +118,41 @@ public class HomeFragment extends Fragment { }); } - fetchNewsFromWordpress(newsRecycler); + refreshData(); } @Override public void onResume() { super.onResume(); + if (activeNetworkCalls == 0) { + refreshData(); + } + } + + private void refreshData() { + activeNetworkCalls = 2; + if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED) { fetchCalendarEvents(calendarRecycler); } else { + checkLoadingComplete(); requestPermissionLauncher.launch(Manifest.permission.READ_CALENDAR); } + + fetchNewsFromWordpress(newsRecycler); + } + + private void checkLoadingComplete() { + activeNetworkCalls--; + if (activeNetworkCalls <= 0) { + activeNetworkCalls = 0; + if (mainProgressBar != null) mainProgressBar.setVisibility(View.GONE); + if (swipeRefreshLayout != null) swipeRefreshLayout.setRefreshing(false); + } } private void fetchCalendarEvents(RecyclerView recyclerView) { new Thread(() -> { - // isPreview = true for raskere lasting List deviceEvents = CalendarManager.getDeviceEvents(getContext(), true); new Handler(Looper.getMainLooper()).post(() -> fetchApiEvents(recyclerView, deviceEvents)); }).start(); @@ -139,8 +164,6 @@ public class HomeFragment extends Fragment { public void onResponse(Call> call, Response> response) { if (!isAdded()) return; - if (mainProgressBar != null) mainProgressBar.setVisibility(View.GONE); - List apiEvents = new ArrayList<>(); if (response.isSuccessful() && response.body() != null) { apiEvents = response.body(); @@ -159,34 +182,38 @@ public class HomeFragment extends Fragment { } } - List top5 = new ArrayList<>(); + List topEvents = new ArrayList<>(); + // ENDRET: Grensen er satt tilbake til 5 for(int i=0; i { + recyclerView.setAdapter(new CalendarAdapter(topEvents, event -> { CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event); - sheet.setOnEventChangeListener(() -> fetchCalendarEvents(recyclerView)); + sheet.setOnEventChangeListener(HomeFragment.this::refreshData); sheet.show(getParentFragmentManager(), "CalendarDetails"); })); + + checkLoadingComplete(); } @Override public void onFailure(Call> call, Throwable t) { if (!isAdded()) return; - if (mainProgressBar != null) mainProgressBar.setVisibility(View.GONE); - if (!deviceEvents.isEmpty()) { - List top5 = new ArrayList<>(); - for(int i=0; i { + List topEvents = new ArrayList<>(); + // ENDRET: Grensen er satt tilbake til 5 (Fallback) + for(int i=0; i { CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event); sheet.show(getParentFragmentManager(), "CalendarDetails"); })); } else { recyclerView.setAdapter(new CalendarAdapter(new ArrayList<>(), null)); } + + checkLoadingComplete(); } }); } @@ -219,12 +246,14 @@ public class HomeFragment extends Fragment { }); recyclerView.setAdapter(adapter); } + checkLoadingComplete(); } @Override public void onFailure(Call> call, Throwable t) { if (getContext() == null) return; recyclerView.setAdapter(new NewsAdapter(new ArrayList<>(), null)); + checkLoadingComplete(); } }); } diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 2db0bab..4bc0253 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -5,128 +5,140 @@ android:layout_height="match_parent" android:background="@color/kbs_very_light_blue"> - + + android:layout_height="match_parent"> - - + android:layout_height="match_parent"> - + android:orientation="vertical" + android:padding="8dp"> - - + + -