Før feilsøking 3
This commit is contained in:
parent
272ffe6cdd
commit
6728516359
7 changed files with 156 additions and 161 deletions
|
|
@ -29,6 +29,7 @@
|
|||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.KBSIntranett"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
tools:targetApi="31">
|
||||
|
||||
<activity
|
||||
|
|
@ -49,7 +50,6 @@
|
|||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
|
||||
<!-- NYTT: Registrering av Firebase Messaging Service -->
|
||||
<service
|
||||
android:name=".MyFirebaseMessagingService"
|
||||
android:exported="false">
|
||||
|
|
@ -68,12 +68,10 @@
|
|||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<!-- Standard ikon for Firebase varsler -->
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||
android:resource="@drawable/ic_stat_kbs" />
|
||||
|
||||
<!-- Standard farge for Firebase varsler (KBS Blå) -->
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_color"
|
||||
android:resource="@color/kbs_logo_blue" />
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ package com.kbs.kbsintranett;
|
|||
import android.app.AlertDialog;
|
||||
import android.app.DatePickerDialog;
|
||||
import android.app.TimePickerDialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
|
|
@ -16,27 +16,30 @@ import android.widget.ArrayAdapter;
|
|||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.ToggleButton;
|
||||
import android.widget.RadioGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.google.android.material.chip.Chip;
|
||||
import com.google.android.material.chip.ChipGroup;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
|
@ -56,9 +59,7 @@ public class CreateEventFragment extends Fragment {
|
|||
private String selectedRRule = null;
|
||||
private boolean isCustomRecurrence = false;
|
||||
|
||||
// BRUKERLISTER
|
||||
private List<User> filteredUsers = new ArrayList<>();
|
||||
|
||||
private String originalOrganizer = null;
|
||||
private CalendarEvent eventToEdit = null;
|
||||
|
||||
|
|
@ -72,7 +73,6 @@ public class CreateEventFragment extends Fragment {
|
|||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
// Initialisering av Views
|
||||
etTitle = view.findViewById(R.id.et_title);
|
||||
etDesc = view.findViewById(R.id.et_desc);
|
||||
etLocation = view.findViewById(R.id.et_location);
|
||||
|
|
@ -91,7 +91,6 @@ public class CreateEventFragment extends Fragment {
|
|||
rbAll = view.findViewById(R.id.rb_visibility_all);
|
||||
rbSpecific = view.findViewById(R.id.rb_visibility_specific);
|
||||
|
||||
// Standardtidspunkt (neste time)
|
||||
startCal.add(Calendar.HOUR_OF_DAY, 1);
|
||||
startCal.set(Calendar.MINUTE, 0);
|
||||
endCal.setTime(startCal.getTime());
|
||||
|
|
@ -101,17 +100,25 @@ public class CreateEventFragment extends Fragment {
|
|||
setupReminderChips();
|
||||
fetchUsers();
|
||||
|
||||
// Sjekk om vi redigerer en eksisterende hendelse
|
||||
// Trygg henting av Serializable for å unngå "unchecked" warning
|
||||
if (getArguments() != null && getArguments().containsKey("edit_event")) {
|
||||
eventToEdit = (CalendarEvent) getArguments().getSerializable("edit_event");
|
||||
prefillForm(eventToEdit);
|
||||
btnSave.setText("Oppdater Hendelse");
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
eventToEdit = getArguments().getSerializable("edit_event", CalendarEvent.class);
|
||||
} else {
|
||||
@SuppressWarnings("deprecation")
|
||||
CalendarEvent e = (CalendarEvent) getArguments().getSerializable("edit_event");
|
||||
eventToEdit = e;
|
||||
}
|
||||
|
||||
if (eventToEdit != null) {
|
||||
prefillForm(eventToEdit);
|
||||
btnSave.setText("Oppdater Hendelse");
|
||||
}
|
||||
}
|
||||
|
||||
updateRecurrenceSpinner();
|
||||
updateUI();
|
||||
|
||||
// Listeners
|
||||
switchAllDay.setOnCheckedChangeListener((btn, isChecked) -> updateUI());
|
||||
btnStartDate.setOnClickListener(v -> pickDate(startCal, true));
|
||||
btnEndDate.setOnClickListener(v -> pickDate(endCal, false));
|
||||
|
|
@ -154,19 +161,17 @@ public class CreateEventFragment extends Fragment {
|
|||
private void fetchUsers() {
|
||||
RetrofitClient.getApiService().getUsersList().enqueue(new Callback<List<User>>() {
|
||||
@Override
|
||||
public void onResponse(Call<List<User>> call, Response<List<User>> response) {
|
||||
public void onResponse(@NonNull Call<List<User>> call, @NonNull Response<List<User>> response) {
|
||||
if (!isAdded()) return;
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
// BRUKER DEN SENTRALE HJELPEKLASSEN FOR FILTRERING
|
||||
filteredUsers = UserFilterHelper.getFilteredUsers(response.body());
|
||||
|
||||
if (eventToEdit != null) {
|
||||
parseParticipantsFromDescription(eventToEdit.getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(Call<List<User>> call, Throwable t) {}
|
||||
public void onFailure(@NonNull Call<List<User>> call, @NonNull Throwable t) {}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -215,11 +220,14 @@ public class CreateEventFragment extends Fragment {
|
|||
|
||||
if (m.find()) {
|
||||
rbSpecific.setChecked(true);
|
||||
String[] emails = m.group(1).split(",");
|
||||
for (String email : emails) {
|
||||
for (User u : filteredUsers) {
|
||||
if (u.getEmail().equalsIgnoreCase(email.trim())) {
|
||||
u.setSelected(true);
|
||||
String group = m.group(1);
|
||||
if (group != null) {
|
||||
String[] emails = group.split(",");
|
||||
for (String email : emails) {
|
||||
for (User u : filteredUsers) {
|
||||
if (u.getEmail().equalsIgnoreCase(email.trim())) {
|
||||
u.setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -233,7 +241,10 @@ public class CreateEventFragment extends Fragment {
|
|||
etTitle.setText(event.getTitle());
|
||||
if (event.getDescription() != null) {
|
||||
Matcher m = Pattern.compile("#arrangor:(.+)").matcher(event.getDescription());
|
||||
if (m.find()) originalOrganizer = m.group(1).trim();
|
||||
if (m.find()) {
|
||||
String group = m.group(1);
|
||||
if (group != null) originalOrganizer = group.trim();
|
||||
}
|
||||
}
|
||||
|
||||
String cleanDesc = event.getDescription()
|
||||
|
|
@ -244,8 +255,9 @@ public class CreateEventFragment extends Fragment {
|
|||
etDesc.setText(cleanDesc);
|
||||
etLocation.setText(event.getLocation());
|
||||
|
||||
ArrayAdapter<String> adapter = (ArrayAdapter<String>) spinnerCalendar.getAdapter();
|
||||
if (adapter != null) {
|
||||
if (spinnerCalendar.getAdapter() instanceof ArrayAdapter) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ArrayAdapter<String> adapter = (ArrayAdapter<String>) spinnerCalendar.getAdapter();
|
||||
int position = adapter.getPosition(event.getCalendarName());
|
||||
if (position >= 0) spinnerCalendar.setSelection(position);
|
||||
}
|
||||
|
|
@ -284,7 +296,10 @@ public class CreateEventFragment extends Fragment {
|
|||
if (!existingReminders.isEmpty()) {
|
||||
for (int i = 0; i < chipGroupReminders.getChildCount(); i++) {
|
||||
Chip chip = (Chip) chipGroupReminders.getChildAt(i);
|
||||
chip.setChecked(existingReminders.contains((Integer) chip.getTag()));
|
||||
Integer tag = (Integer) chip.getTag();
|
||||
if (tag != null) {
|
||||
chip.setChecked(existingReminders.contains(tag));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
@ -299,7 +314,7 @@ public class CreateEventFragment extends Fragment {
|
|||
calendars.add("Felles");
|
||||
}
|
||||
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, calendars) {
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<String>(requireContext(), android.R.layout.simple_spinner_item, calendars) {
|
||||
@NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||
TextView view = (TextView) super.getView(position, convertView, parent);
|
||||
view.setBackgroundColor(Color.parseColor(getCalendarColor(getItem(position))));
|
||||
|
|
@ -307,7 +322,7 @@ public class CreateEventFragment extends Fragment {
|
|||
view.setTypeface(null, Typeface.BOLD);
|
||||
return view;
|
||||
}
|
||||
@Override public View getDropDownView(int position, View convertView, ViewGroup parent) {
|
||||
@Override public View getDropDownView(int position, View convertView, @NonNull ViewGroup parent) {
|
||||
TextView view = (TextView) super.getDropDownView(position, convertView, parent);
|
||||
view.setTextColor(Color.parseColor(getCalendarColor(getItem(position))));
|
||||
view.setTypeface(null, Typeface.BOLD);
|
||||
|
|
@ -321,11 +336,11 @@ public class CreateEventFragment extends Fragment {
|
|||
private String getCalendarColor(String name) {
|
||||
if (name == null) return "#888888";
|
||||
switch (name) {
|
||||
case "Felles": return "#0069B3"; // KBS Blå
|
||||
case "AMU/HMS/Miljø": return "#2E7D32"; // Mørk grønn (Miljø-profil)
|
||||
case "Felles": return "#0069B3";
|
||||
case "AMU/HMS/Miljø": return "#2E7D32";
|
||||
case "Administrasjonen": return "#607D8B";
|
||||
case "Serviceavdelingen": return "#E65100";
|
||||
case "Automasjonsavdelingen": return "#2E7D32"; // Merk: Denne er lik Miljø nå, du kan bytte til f.eks #1B5E20 hvis ønskelig
|
||||
case "Automasjonsavdelingen": return "#2E7D32";
|
||||
case "Prosjektavdelingen": return "#7B1FA2";
|
||||
default: return "#888888";
|
||||
}
|
||||
|
|
@ -347,13 +362,14 @@ public class CreateEventFragment extends Fragment {
|
|||
if (eventToEdit == null) {
|
||||
for (int i=0; i<chipGroupReminders.getChildCount(); i++) {
|
||||
Chip c = (Chip) chipGroupReminders.getChildAt(i);
|
||||
if ((int)c.getTag() == 15) c.setChecked(true);
|
||||
Integer tag = (Integer) c.getTag();
|
||||
if (tag != null && tag == 15) c.setChecked(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addReminderChip(String text, int minutes) {
|
||||
Chip chip = new Chip(getContext());
|
||||
Chip chip = new Chip(requireContext());
|
||||
chip.setText(text);
|
||||
chip.setTag(minutes);
|
||||
chip.setCheckable(true);
|
||||
|
|
@ -369,7 +385,7 @@ public class CreateEventFragment extends Fragment {
|
|||
options.add("Ikke gjenta"); options.add("Daglig"); options.add("Ukentlig på " + dayName);
|
||||
options.add("Månedlig den " + dayOfMonth + "."); options.add("Månedlig den " + weekNo + ". " + dayName + "en");
|
||||
options.add("Årlig den " + dayOfMonth + ". " + monthName); options.add("Hver ukedag (man-fre)"); options.add("Egendefinert...");
|
||||
spinnerRecurrence.setAdapter(new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_dropdown_item, options));
|
||||
spinnerRecurrence.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_dropdown_item, options));
|
||||
}
|
||||
|
||||
private void generateStandardRRule(int position) {
|
||||
|
|
@ -406,7 +422,7 @@ public class CreateEventFragment extends Fragment {
|
|||
btnEndDatePicker.setText(new SimpleDateFormat("d. MMM yyyy", Locale.getDefault()).format(customEndCal.getTime()));
|
||||
btnEndDatePicker.setOnClickListener(v -> {
|
||||
rgEnd.check(R.id.rb_date);
|
||||
new DatePickerDialog(getContext(), (p, y, m, d) -> { customEndCal.set(y, m, d); btnEndDatePicker.setText(new SimpleDateFormat("d. MMM yyyy", Locale.getDefault()).format(customEndCal.getTime())); }, customEndCal.get(Calendar.YEAR), customEndCal.get(Calendar.MONTH), customEndCal.get(Calendar.DAY_OF_MONTH)).show();
|
||||
new DatePickerDialog(requireContext(), (p, y, m, d) -> { customEndCal.set(y, m, d); btnEndDatePicker.setText(new SimpleDateFormat("d. MMM yyyy", Locale.getDefault()).format(customEndCal.getTime())); }, customEndCal.get(Calendar.YEAR), customEndCal.get(Calendar.MONTH), customEndCal.get(Calendar.DAY_OF_MONTH)).show();
|
||||
});
|
||||
spinnerFreq.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override public void onItemSelected(AdapterView<?> p, View v, int pos, long id) { layoutWeekdays.setVisibility(pos == 1 ? View.VISIBLE : View.GONE); }
|
||||
|
|
@ -434,7 +450,7 @@ public class CreateEventFragment extends Fragment {
|
|||
}
|
||||
|
||||
private void pickDate(Calendar cal, boolean isStart) {
|
||||
new DatePickerDialog(getContext(), (view, y, m, d) -> {
|
||||
new DatePickerDialog(requireContext(), (view, y, m, d) -> {
|
||||
cal.set(y, m, d);
|
||||
if (isStart) {
|
||||
if (endCal.before(startCal)) { endCal.setTime(startCal.getTime()); if (!switchAllDay.isChecked()) endCal.add(Calendar.HOUR_OF_DAY, 1); }
|
||||
|
|
@ -445,7 +461,7 @@ public class CreateEventFragment extends Fragment {
|
|||
}
|
||||
|
||||
private void pickTime(Calendar cal) {
|
||||
new TimePickerDialog(getContext(), (view, h, m) -> {
|
||||
new TimePickerDialog(requireContext(), (view, h, m) -> {
|
||||
cal.set(Calendar.HOUR_OF_DAY, h); cal.set(Calendar.MINUTE, m);
|
||||
if (cal == startCal && endCal.before(startCal)) { endCal.setTime(startCal.getTime()); endCal.add(Calendar.HOUR_OF_DAY, 1); }
|
||||
updateUI();
|
||||
|
|
@ -473,7 +489,8 @@ public class CreateEventFragment extends Fragment {
|
|||
List<Integer> reminders = new ArrayList<>();
|
||||
for (int i=0; i<chipGroupReminders.getChildCount(); i++) {
|
||||
Chip c = (Chip) chipGroupReminders.getChildAt(i);
|
||||
if (c.isChecked()) reminders.add((Integer) c.getTag());
|
||||
Integer tag = (Integer) c.getTag();
|
||||
if (c.isChecked() && tag != null) reminders.add(tag);
|
||||
}
|
||||
String desc = etDesc.getText().toString();
|
||||
if (rbSpecific.isChecked()) {
|
||||
|
|
@ -490,13 +507,13 @@ public class CreateEventFragment extends Fragment {
|
|||
|
||||
Call<JsonElement> call = (eventToEdit != null) ? RetrofitClient.getApiService().updateCalendarEvent(req) : RetrofitClient.getApiService().createCalendarEvent(req);
|
||||
call.enqueue(new Callback<JsonElement>() {
|
||||
@Override public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
|
||||
@Override public void onResponse(@NonNull Call<JsonElement> call, @NonNull Response<JsonElement> response) {
|
||||
if (response.isSuccessful()) {
|
||||
Toast.makeText(getContext(), "Lagret!", Toast.LENGTH_LONG).show();
|
||||
Navigation.findNavController(getView()).navigateUp();
|
||||
Navigation.findNavController(requireView()).navigateUp();
|
||||
}
|
||||
}
|
||||
@Override public void onFailure(Call<JsonElement> call, Throwable t) { Toast.makeText(getContext(), "Feil!", Toast.LENGTH_SHORT).show(); }
|
||||
@Override public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) { Toast.makeText(getContext(), "Feil!", Toast.LENGTH_SHORT).show(); }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -31,8 +31,6 @@ import retrofit2.Response;
|
|||
public class FormsListFragment extends Fragment {
|
||||
|
||||
private LinearLayout formsContainer;
|
||||
private ProgressBar progressBar;
|
||||
private TextView errorText;
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
private static final Pattern TITLE_NUMBER_PATTERN = Pattern.compile("^(\\d+)[.\\s-]+\\s*(.*)");
|
||||
|
||||
|
|
@ -40,110 +38,68 @@ public class FormsListFragment extends Fragment {
|
|||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_forms_list, container, false);
|
||||
|
||||
formsContainer = view.findViewById(R.id.forms_container);
|
||||
swipeRefreshLayout = view.findViewById(R.id.swipe_refresh);
|
||||
|
||||
// Opprett en ProgressBar manuelt for første gangs lasting
|
||||
progressBar = new ProgressBar(getContext());
|
||||
LinearLayout.LayoutParams progressParams = new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
progressParams.gravity = Gravity.CENTER;
|
||||
progressBar.setLayoutParams(progressParams);
|
||||
swipeRefreshLayout.setOnRefreshListener(this::fetchFormsList);
|
||||
|
||||
formsContainer.addView(progressBar);
|
||||
|
||||
errorText = new TextView(getContext());
|
||||
errorText.setTextColor(Color.RED);
|
||||
errorText.setVisibility(View.GONE);
|
||||
errorText.setPadding(20, 20, 20, 20);
|
||||
formsContainer.addView(errorText);
|
||||
|
||||
// Sett opp listener for swipe
|
||||
swipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
fetchFormsList();
|
||||
});
|
||||
|
||||
// Hent data første gang
|
||||
// Første gangs lasting
|
||||
swipeRefreshLayout.setRefreshing(true);
|
||||
fetchFormsList();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void fetchFormsList() {
|
||||
// Skjul feilmelding før ny henting
|
||||
if (errorText != null) errorText.setVisibility(View.GONE);
|
||||
|
||||
RetrofitClient.getApiService().getFormsList().enqueue(new Callback<List<GravityForm>>() {
|
||||
@Override
|
||||
public void onResponse(Call<List<GravityForm>> call, Response<List<GravityForm>> response) {
|
||||
if (!isAdded()) return;
|
||||
|
||||
// Stopp lasting-indikatorer
|
||||
progressBar.setVisibility(View.GONE);
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
List<GravityForm> allForms = response.body();
|
||||
List<GravityForm> activeForms = new ArrayList<>();
|
||||
|
||||
for (GravityForm form : allForms) {
|
||||
for (GravityForm form : response.body()) {
|
||||
if (form.getIsActive()) {
|
||||
// NYTT: Hardkodet filtrering av skjemaer som ikke skal vises i listen
|
||||
// ID 10 = HMS-bekreftelse (Skal ligge i Håndbok/separat flyt)
|
||||
// ID 18 = Refusjon-vedlegg (Er et underskjema som brukes av ID 16)
|
||||
if (form.id == 10 || form.id == 18) {
|
||||
continue;
|
||||
// HMS-bekreftelse (10) og Refusjon-vedlegg (18) skal ikke i listen
|
||||
if (form.id != 10 && form.id != 18) {
|
||||
activeForms.add(form);
|
||||
}
|
||||
|
||||
activeForms.add(form);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(activeForms, new Comparator<GravityForm>() {
|
||||
@Override
|
||||
public int compare(GravityForm f1, GravityForm f2) {
|
||||
int num1 = extractNumber(f1.title);
|
||||
int num2 = extractNumber(f2.title);
|
||||
return Integer.compare(num1, num2);
|
||||
}
|
||||
});
|
||||
Collections.sort(activeForms, (f1, f2) ->
|
||||
Integer.compare(extractNumber(f1.title), extractNumber(f2.title)));
|
||||
|
||||
populateList(activeForms);
|
||||
|
||||
} else {
|
||||
String msg = "Kunne ikke hente skjemaer. Kode: " + response.code();
|
||||
if (response.code() == 401 || response.code() == 403) {
|
||||
msg += "\n(Mangler tilgang. Prøv å logge ut og inn igjen.)";
|
||||
showError("Sesjonen utløp, men er nå reparert. Vennligst sveip ned for å prøve igjen.");
|
||||
} else {
|
||||
showError("Kunne ikke hente skjemaer. Kode: " + response.code());
|
||||
}
|
||||
showError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<List<GravityForm>> call, Throwable t) {
|
||||
if (!isAdded()) return;
|
||||
|
||||
// Stopp lasting-indikatorer
|
||||
progressBar.setVisibility(View.GONE);
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
|
||||
showError("Nettverksfeil: " + t.getMessage());
|
||||
showError("Nettverksfeil: Prøv igjen.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void populateList(List<GravityForm> forms) {
|
||||
formsContainer.removeAllViews();
|
||||
|
||||
if (forms.isEmpty()) {
|
||||
showError("Ingen aktive skjemaer funnet.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (GravityForm form : forms) {
|
||||
int formId = form.id;
|
||||
String cleanTitle = cleanTitle(form.title);
|
||||
addFormButton(formsContainer, cleanTitle, formId);
|
||||
addFormButton(formsContainer, cleanTitle(form.title), form.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -174,30 +130,22 @@ public class FormsListFragment extends Fragment {
|
|||
|
||||
TextView tv = new TextView(getContext());
|
||||
tv.setText(message);
|
||||
tv.setTextColor(Color.RED);
|
||||
tv.setTextColor(Color.parseColor("#C40426")); // KBS Rød
|
||||
tv.setTextSize(16);
|
||||
tv.setGravity(Gravity.CENTER);
|
||||
tv.setPadding(40, 100, 40, 40);
|
||||
formsContainer.addView(tv);
|
||||
}
|
||||
|
||||
private int extractNumber(String title) {
|
||||
if (title == null) return 9999;
|
||||
Matcher m = TITLE_NUMBER_PATTERN.matcher(title.trim());
|
||||
if (m.find()) {
|
||||
try {
|
||||
return Integer.parseInt(m.group(1));
|
||||
} catch (NumberFormatException e) {
|
||||
return 9999;
|
||||
}
|
||||
}
|
||||
return 9999;
|
||||
return m.find() ? Integer.parseInt(m.group(1)) : 9999;
|
||||
}
|
||||
|
||||
private String cleanTitle(String title) {
|
||||
if (title == null) return "";
|
||||
Matcher m = TITLE_NUMBER_PATTERN.matcher(title.trim());
|
||||
if (m.find()) {
|
||||
return m.group(2);
|
||||
}
|
||||
return title;
|
||||
return m.find() ? m.group(2) : title;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,21 +3,26 @@ package com.kbs.kbsintranett;
|
|||
import android.app.Application;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
public class KbsApplication extends Application {
|
||||
|
||||
public static final String CHANNEL_ID = "kbs_calendar_channel";
|
||||
private static Context instance;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
instance = getApplicationContext();
|
||||
createNotificationChannel();
|
||||
}
|
||||
|
||||
public static Context getContext() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private void createNotificationChannel() {
|
||||
// Vi oppretter kanalen her ved oppstart, så den er klar uansett om
|
||||
// det er MainActivity eller en bakgrunnsjobb som trenger den.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
CHANNEL_ID,
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
|
@ -46,6 +46,15 @@ public class MainActivity extends AppCompatActivity {
|
|||
private AppBarConfiguration appBarConfiguration;
|
||||
private ActivityResultLauncher<String> requestPermissionLauncher;
|
||||
|
||||
private final BroadcastReceiver authFailedReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (RetrofitClient.ACTION_AUTH_FAILED.equals(intent.getAction())) {
|
||||
refreshGoogleToken();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
|
@ -62,7 +71,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
|
||||
if (navHostFragment != null) {
|
||||
navController = navHostFragment.getNavController();
|
||||
|
||||
appBarConfiguration = new AppBarConfiguration.Builder(
|
||||
R.id.navigation_home, R.id.navigation_calendar_full, R.id.navigation_tasks,
|
||||
R.id.navigation_forms, R.id.navigation_news_full, R.id.navigation_handbook)
|
||||
|
|
@ -71,7 +79,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
|
||||
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
|
||||
|
||||
// Vi bruker en tilpasset listener for å sikre at Hjem og andre punkter alltid fungerer
|
||||
navigationView.setNavigationItemSelectedListener(item -> {
|
||||
boolean handled = NavigationUI.onNavDestinationSelected(item, navController);
|
||||
if (handled || item.getItemId() == R.id.navigation_home) {
|
||||
|
|
@ -101,6 +108,20 @@ public class MainActivity extends AppCompatActivity {
|
|||
checkNotificationPermission();
|
||||
checkExactAlarmPermission();
|
||||
checkLoginState();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
registerReceiver(authFailedReceiver, new IntentFilter(RetrofitClient.ACTION_AUTH_FAILED), Context.RECEIVER_NOT_EXPORTED);
|
||||
} else {
|
||||
registerReceiver(authFailedReceiver, new IntentFilter(RetrofitClient.ACTION_AUTH_FAILED));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
try {
|
||||
unregisterReceiver(authFailedReceiver);
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
private void updateNavHeader(NavigationView navigationView) {
|
||||
|
|
@ -141,7 +162,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
else refreshGoogleToken();
|
||||
}
|
||||
|
||||
private void refreshGoogleToken() {
|
||||
public void refreshGoogleToken() {
|
||||
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
.requestIdToken(GOOGLE_WEB_CLIENT_ID).requestEmail().build();
|
||||
GoogleSignInClient client = GoogleSignIn.getClient(this, gso);
|
||||
|
|
@ -169,7 +190,10 @@ public class MainActivity extends AppCompatActivity {
|
|||
private void createNotificationChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannel channel = new NotificationChannel("kbs_calendar_channel", "Varsler", NotificationManager.IMPORTANCE_HIGH);
|
||||
getSystemService(NotificationManager.class).createNotificationChannel(channel);
|
||||
NotificationManager manager = getSystemService(NotificationManager.class);
|
||||
if (manager != null) {
|
||||
manager.createNotificationChannel(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.content.Intent;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
|
|
@ -18,33 +17,43 @@ import retrofit2.converter.gson.GsonConverterFactory;
|
|||
public class RetrofitClient {
|
||||
private static final String BASE_URL = "https://intranet.kbs.no/";
|
||||
private static Retrofit retrofit = null;
|
||||
|
||||
public static final String ACTION_AUTH_FAILED = "com.kbs.kbsintranett.AUTH_FAILED";
|
||||
|
||||
public static WordPressApiService getApiService() {
|
||||
if (retrofit == null) {
|
||||
|
||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||
if (BuildConfig.DEBUG) {
|
||||
// I debug-modus logger vi det mest nødvendige
|
||||
logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
|
||||
} else {
|
||||
// I release er vi stille for ytelse og sikkerhet
|
||||
logging.setLevel(HttpLoggingInterceptor.Level.NONE);
|
||||
}
|
||||
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.addInterceptor(logging)
|
||||
.addInterceptor(new Interceptor() {
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
Request originalRequest = chain.request();
|
||||
Request.Builder builder = originalRequest.newBuilder();
|
||||
|
||||
String dynamicCookie = UserManager.getInstance().getCookie();
|
||||
if (dynamicCookie != null && !dynamicCookie.isEmpty()) {
|
||||
builder.header("Cookie", dynamicCookie);
|
||||
}
|
||||
|
||||
return chain.proceed(builder.build());
|
||||
.addInterceptor(chain -> {
|
||||
Request originalRequest = chain.request();
|
||||
Request.Builder builder = originalRequest.newBuilder();
|
||||
String dynamicCookie = UserManager.getInstance().getCookie();
|
||||
if (dynamicCookie != null && !dynamicCookie.isEmpty()) {
|
||||
builder.header("Cookie", dynamicCookie);
|
||||
}
|
||||
return chain.proceed(builder.build());
|
||||
})
|
||||
.addInterceptor(chain -> {
|
||||
Request request = chain.request();
|
||||
Response response = chain.proceed(request);
|
||||
|
||||
if (response.code() == 401 || response.code() == 403) {
|
||||
if (!request.url().toString().contains("kbs/v1/login")) {
|
||||
Intent intent = new Intent(ACTION_AUTH_FAILED);
|
||||
intent.setPackage("com.kbs.kbsintranett");
|
||||
if (KbsApplication.getContext() != null) {
|
||||
KbsApplication.getContext().sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
return response;
|
||||
})
|
||||
.build();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/main_layout"
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/swipe_refresh"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:background="#F5F5F5">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipe_refresh"
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
android:background="#F5F5F5">
|
||||
|
||||
<ScrollView
|
||||
<LinearLayout
|
||||
android:id="@+id/forms_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp" />
|
||||
</ScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/forms_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
</ScrollView>
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
Loading…
Reference in a new issue