Før refreshing på forsiden
This commit is contained in:
parent
530a5a3d16
commit
d3b9504f9a
15 changed files with 530 additions and 202 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application)
|
alias(libs.plugins.android.application)
|
||||||
|
// NY LINJE: Aktiver Google Services plugin her
|
||||||
|
id("com.google.gms.google-services")
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
|
@ -10,8 +12,8 @@ android {
|
||||||
applicationId = "com.kbs.kbsintranett"
|
applicationId = "com.kbs.kbsintranett"
|
||||||
minSdk = 28
|
minSdk = 28
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 1
|
versionCode = 2
|
||||||
versionName = "1.0"
|
versionName = "1.2"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
@ -63,4 +65,10 @@ dependencies {
|
||||||
|
|
||||||
// Swipe Refresh Layout
|
// Swipe Refresh Layout
|
||||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||||
}
|
|
||||||
|
// NY LINJE: Firebase BOM (Bill of Materials) styrer versjoner
|
||||||
|
implementation(platform("com.google.firebase:firebase-bom:33.1.2"))
|
||||||
|
|
||||||
|
// NY LINJE: (Valgfritt, men lurt for statistikk)
|
||||||
|
implementation("com.google.firebase:firebase-analytics")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,23 +15,31 @@ import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.navigation.Navigation;
|
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
import retrofit2.Response;
|
import retrofit2.Response;
|
||||||
|
|
||||||
public class CalendarDetailsBottomSheet extends BottomSheetDialogFragment {
|
public class CalendarDetailsBottomSheet extends BottomSheetDialogFragment {
|
||||||
private CalendarEvent event;
|
private CalendarEvent event;
|
||||||
|
private OnEventChangeListener changeListener;
|
||||||
|
|
||||||
|
// Interface for å varsle foreldre-fragmentet om endringer
|
||||||
|
public interface OnEventChangeListener {
|
||||||
|
void onEventChanged();
|
||||||
|
}
|
||||||
|
|
||||||
public CalendarDetailsBottomSheet(CalendarEvent event) {
|
public CalendarDetailsBottomSheet(CalendarEvent event) {
|
||||||
this.event = event;
|
this.event = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOnEventChangeListener(OnEventChangeListener listener) {
|
||||||
|
this.changeListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
|
@ -41,7 +49,7 @@ public class CalendarDetailsBottomSheet extends BottomSheetDialogFragment {
|
||||||
TextView time = view.findViewById(R.id.sheet_time);
|
TextView time = view.findViewById(R.id.sheet_time);
|
||||||
TextView desc = view.findViewById(R.id.sheet_desc);
|
TextView desc = view.findViewById(R.id.sheet_desc);
|
||||||
TextView loc = view.findViewById(R.id.sheet_location);
|
TextView loc = view.findViewById(R.id.sheet_location);
|
||||||
TextView calName = view.findViewById(R.id.sheet_calendar_name); // NYTT
|
TextView calName = view.findViewById(R.id.sheet_calendar_name);
|
||||||
|
|
||||||
LinearLayout adminLayout = view.findViewById(R.id.layout_admin_buttons);
|
LinearLayout adminLayout = view.findViewById(R.id.layout_admin_buttons);
|
||||||
Button btnDelete = view.findViewById(R.id.btn_delete);
|
Button btnDelete = view.findViewById(R.id.btn_delete);
|
||||||
|
|
@ -50,7 +58,6 @@ public class CalendarDetailsBottomSheet extends BottomSheetDialogFragment {
|
||||||
title.setText(event.getTitle());
|
title.setText(event.getTitle());
|
||||||
time.setText(event.getTime() + " (" + event.getDay() + ". " + event.getMonth() + ")");
|
time.setText(event.getTime() + " (" + event.getDay() + ". " + event.getMonth() + ")");
|
||||||
|
|
||||||
// NYTT: Sett navn og farge
|
|
||||||
calName.setText(event.getCalendarName().toUpperCase());
|
calName.setText(event.getCalendarName().toUpperCase());
|
||||||
try {
|
try {
|
||||||
int color = Color.parseColor(event.getCalendarColor());
|
int color = Color.parseColor(event.getCalendarColor());
|
||||||
|
|
@ -75,13 +82,6 @@ public class CalendarDetailsBottomSheet extends BottomSheetDialogFragment {
|
||||||
|
|
||||||
// Sjekk admin-rettigheter
|
// Sjekk admin-rettigheter
|
||||||
if (UserManager.getInstance().isEditorOrAbove()) {
|
if (UserManager.getInstance().isEditorOrAbove()) {
|
||||||
// MERK: Selv om man er admin, bør man kanskje bare kunne slette/endre events fra kalendere
|
|
||||||
// man faktisk har skrivetilgang til i konfigurasjonen.
|
|
||||||
// Men siden admin har tilgang til alt i PHP, viser vi knappene.
|
|
||||||
// Hvis brukeren er vanlig ansatt (men ikke i f.eks service), vil skrivetilgang sjekkes
|
|
||||||
// mot 'writeable_calendars' eller ved API-kall.
|
|
||||||
// Enklest her: Vi viser knappene hvis brukeren KAN skrive til denne kalenderen.
|
|
||||||
|
|
||||||
boolean canEdit = UserManager.getInstance().getWriteableCalendars().contains(event.getCalendarName())
|
boolean canEdit = UserManager.getInstance().getWriteableCalendars().contains(event.getCalendarName())
|
||||||
|| UserManager.getInstance().isAdmin();
|
|| UserManager.getInstance().isAdmin();
|
||||||
|
|
||||||
|
|
@ -122,6 +122,12 @@ public class CalendarDetailsBottomSheet extends BottomSheetDialogFragment {
|
||||||
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
|
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
Toast.makeText(getContext(), "Slettet!", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Slettet!", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
// VARSLE LISTEN OM AT NOE ER SLETTET
|
||||||
|
if (changeListener != null) {
|
||||||
|
changeListener.onEventChanged();
|
||||||
|
}
|
||||||
|
|
||||||
dismiss();
|
dismiss();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(getContext(), "Kunne ikke slette", Toast.LENGTH_LONG).show();
|
Toast.makeText(getContext(), "Kunne ikke slette", Toast.LENGTH_LONG).show();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.kbs.kbsintranett;
|
package com.kbs.kbsintranett;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
@ -46,16 +48,25 @@ public class CalendarFullFragment extends Fragment {
|
||||||
layoutManager = new LinearLayoutManager(getContext());
|
layoutManager = new LinearLayoutManager(getContext());
|
||||||
recyclerView.setLayoutManager(layoutManager);
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
backBtn.setOnClickListener(v -> Navigation.findNavController(view).navigateUp());
|
backBtn.setOnClickListener(v -> Navigation.findNavController(view).navigateUp());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
fetchAllEvents();
|
fetchAllEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchAllEvents() {
|
private void fetchAllEvents() {
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
// Hent personlige hendelser
|
|
||||||
List<CalendarEvent> deviceEvents = CalendarManager.getDeviceEvents(getContext());
|
|
||||||
|
|
||||||
// Hent felles hendelser fra WordPress Proxy (sikrer at vi får reminders)
|
new Thread(() -> {
|
||||||
|
// HER ER ENDRINGEN: isPreview = false (Hent alt)
|
||||||
|
List<CalendarEvent> deviceEvents = CalendarManager.getDeviceEvents(getContext(), false);
|
||||||
|
new Handler(Looper.getMainLooper()).post(() -> fetchApiEvents(deviceEvents));
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fetchApiEvents(List<CalendarEvent> deviceEvents) {
|
||||||
RetrofitClient.getApiService().getCalendarEvents().enqueue(new Callback<List<CalendarEvent>>() {
|
RetrofitClient.getApiService().getCalendarEvents().enqueue(new Callback<List<CalendarEvent>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<List<CalendarEvent>> call, Response<List<CalendarEvent>> response) {
|
public void onResponse(Call<List<CalendarEvent>> call, Response<List<CalendarEvent>> response) {
|
||||||
|
|
@ -65,7 +76,6 @@ public class CalendarFullFragment extends Fragment {
|
||||||
List<CalendarEvent> apiEvents = new ArrayList<>();
|
List<CalendarEvent> apiEvents = new ArrayList<>();
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
apiEvents = response.body();
|
apiEvents = response.body();
|
||||||
// Formater data for visning
|
|
||||||
for (CalendarEvent e : apiEvents) {
|
for (CalendarEvent e : apiEvents) {
|
||||||
CalendarManager.formatEventForUI(e);
|
CalendarManager.formatEventForUI(e);
|
||||||
}
|
}
|
||||||
|
|
@ -82,6 +92,7 @@ public class CalendarFullFragment extends Fragment {
|
||||||
|
|
||||||
CalendarAdapter adapter = new CalendarAdapter(allEvents, event -> {
|
CalendarAdapter adapter = new CalendarAdapter(allEvents, event -> {
|
||||||
CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event);
|
CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event);
|
||||||
|
sheet.setOnEventChangeListener(CalendarFullFragment.this::fetchAllEvents);
|
||||||
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
||||||
});
|
});
|
||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
@ -126,5 +137,4 @@ public class CalendarFullFragment extends Fragment {
|
||||||
layoutManager.scrollToPositionWithOffset(scrollIndex, 0);
|
layoutManager.scrollToPositionWithOffset(scrollIndex, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -9,8 +9,10 @@ import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
public class CalendarManager {
|
public class CalendarManager {
|
||||||
|
|
@ -44,7 +46,13 @@ public class CalendarManager {
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<CalendarEvent> getDeviceEvents(Context context) {
|
/**
|
||||||
|
* Henter hendelser fra enheten.
|
||||||
|
* @param context App Context
|
||||||
|
* @param isPreview Hvis true: Henter kun kommende måned (Raskt). Hvis false: Henter -1 til +6 mnd (Tregere).
|
||||||
|
* @return Liste med events
|
||||||
|
*/
|
||||||
|
public static List<CalendarEvent> getDeviceEvents(Context context, boolean isPreview) {
|
||||||
List<CalendarEvent> deviceEvents = new ArrayList<>();
|
List<CalendarEvent> deviceEvents = new ArrayList<>();
|
||||||
if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.READ_CALENDAR)
|
if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.READ_CALENDAR)
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
|
@ -57,8 +65,20 @@ public class CalendarManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
long startMillis = now - (365L * 24 * 60 * 60 * 1000);
|
long startMillis;
|
||||||
long endMillis = now + (365L * 24 * 60 * 60 * 1000);
|
long endMillis;
|
||||||
|
|
||||||
|
if (isPreview) {
|
||||||
|
// FORSIDEN: Optimalisert for hastighet.
|
||||||
|
// Henter fra NÅ og 30 dager frem i tid.
|
||||||
|
startMillis = now;
|
||||||
|
endMillis = now + (30L * 24 * 60 * 60 * 1000);
|
||||||
|
} else {
|
||||||
|
// FULL VISNING: Bredere tidsvindu.
|
||||||
|
// 1 mnd tilbake til 6 mnd frem.
|
||||||
|
startMillis = now - (30L * 24 * 60 * 60 * 1000);
|
||||||
|
endMillis = now + (180L * 24 * 60 * 60 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
String[] projection = new String[]{
|
String[] projection = new String[]{
|
||||||
CalendarContract.Events.TITLE,
|
CalendarContract.Events.TITLE,
|
||||||
|
|
@ -120,8 +140,7 @@ public class CalendarManager {
|
||||||
CalendarEvent event = new CalendarEvent(title, rawStart, rawEnd, desc, loc);
|
CalendarEvent event = new CalendarEvent(title, rawStart, rawEnd, desc, loc);
|
||||||
event.setReminderMinutes(0);
|
event.setReminderMinutes(0);
|
||||||
|
|
||||||
// NYTT V12.2: Sett standardfarge for lokale kalendere
|
event.setCalendarColor("#888888");
|
||||||
event.setCalendarColor("#888888"); // Grå for lokale events
|
|
||||||
event.setCalendarName("Min Kalender (Lokal)");
|
event.setCalendarName("Min Kalender (Lokal)");
|
||||||
|
|
||||||
formatEventForUI(event);
|
formatEventForUI(event);
|
||||||
|
|
@ -200,9 +219,24 @@ public class CalendarManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<CalendarEvent> mergeAndSort(List<CalendarEvent> apiEvents, List<CalendarEvent> deviceEvents) {
|
public static List<CalendarEvent> mergeAndSort(List<CalendarEvent> apiEvents, List<CalendarEvent> deviceEvents) {
|
||||||
List<CalendarEvent> all = new ArrayList<>(apiEvents);
|
List<CalendarEvent> all = new ArrayList<>();
|
||||||
all.addAll(deviceEvents);
|
Set<String> uniqueKeys = new HashSet<>();
|
||||||
|
|
||||||
|
// 1. Legg til alle API-events først (Prioritert)
|
||||||
|
for (CalendarEvent apiEvent : apiEvents) {
|
||||||
|
all.add(apiEvent);
|
||||||
|
uniqueKeys.add(generateKey(apiEvent));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Legg til Device-events KUN hvis nøkkelen ikke finnes
|
||||||
|
for (CalendarEvent deviceEvent : deviceEvents) {
|
||||||
|
String key = generateKey(deviceEvent);
|
||||||
|
if (!uniqueKeys.contains(key)) {
|
||||||
|
all.add(deviceEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Sorter alt kronologisk
|
||||||
Collections.sort(all, (e1, e2) -> {
|
Collections.sort(all, (e1, e2) -> {
|
||||||
String d1 = e1.getRawDate() != null ? e1.getRawDate() : "";
|
String d1 = e1.getRawDate() != null ? e1.getRawDate() : "";
|
||||||
String d2 = e2.getRawDate() != null ? e2.getRawDate() : "";
|
String d2 = e2.getRawDate() != null ? e2.getRawDate() : "";
|
||||||
|
|
@ -212,4 +246,20 @@ public class CalendarManager {
|
||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String generateKey(CalendarEvent event) {
|
||||||
|
String title = event.getTitle() != null ? event.getTitle().toLowerCase().trim() : "";
|
||||||
|
String datePart = "";
|
||||||
|
|
||||||
|
if (event.getRawDate() != null) {
|
||||||
|
String digits = event.getRawDate().replaceAll("[^0-9]", "");
|
||||||
|
if (digits.length() >= 12) {
|
||||||
|
datePart = digits.substring(0, 12);
|
||||||
|
} else if (digits.length() >= 8) {
|
||||||
|
datePart = digits.substring(0, 8);
|
||||||
|
} else {
|
||||||
|
datePart = digits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return title + "_" + datePart;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -139,6 +139,20 @@ public class CreateEventFragment extends Fragment {
|
||||||
etDesc.setText(cleanDesc);
|
etDesc.setText(cleanDesc);
|
||||||
etLocation.setText(event.getLocation());
|
etLocation.setText(event.getLocation());
|
||||||
|
|
||||||
|
// --- FIKS 404 FEIL VED OPPDATERING ---
|
||||||
|
// 1. Sett spinneren til riktig kalender
|
||||||
|
ArrayAdapter<String> adapter = (ArrayAdapter<String>) spinnerCalendar.getAdapter();
|
||||||
|
if (adapter != null) {
|
||||||
|
int position = adapter.getPosition(event.getCalendarName());
|
||||||
|
if (position >= 0) {
|
||||||
|
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
|
// Dato-parsing
|
||||||
try {
|
try {
|
||||||
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
|
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,13 @@ package com.kbs.kbsintranett;
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
|
|
@ -33,6 +36,8 @@ import retrofit2.Response;
|
||||||
public class HomeFragment extends Fragment {
|
public class HomeFragment extends Fragment {
|
||||||
private ActivityResultLauncher<String> requestPermissionLauncher;
|
private ActivityResultLauncher<String> requestPermissionLauncher;
|
||||||
private RecyclerView calendarRecycler;
|
private RecyclerView calendarRecycler;
|
||||||
|
private RecyclerView newsRecycler;
|
||||||
|
private ProgressBar mainProgressBar; // Variabelen som må være her
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
|
@ -58,12 +63,16 @@ public class HomeFragment extends Fragment {
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, 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);
|
||||||
|
|
||||||
View profileBtn = view.findViewById(R.id.btn_profile);
|
View profileBtn = view.findViewById(R.id.btn_profile);
|
||||||
if (profileBtn != null) {
|
if (profileBtn != null) {
|
||||||
profileBtn.setOnClickListener(v -> Navigation.findNavController(view).navigate(R.id.navigation_profile));
|
profileBtn.setOnClickListener(v -> Navigation.findNavController(view).navigate(R.id.navigation_profile));
|
||||||
}
|
}
|
||||||
|
|
||||||
// NY LOGIKK: Vis knapp hvis brukeren har tilgang til minst én kalender
|
|
||||||
Button btnCreateEvent = view.findViewById(R.id.btn_create_event);
|
Button btnCreateEvent = view.findViewById(R.id.btn_create_event);
|
||||||
List<String> writeable = UserManager.getInstance().getWriteableCalendars();
|
List<String> writeable = UserManager.getInstance().getWriteableCalendars();
|
||||||
|
|
||||||
|
|
@ -85,19 +94,13 @@ public class HomeFragment extends Fragment {
|
||||||
viewAllCalendar.setOnClickListener(v -> Navigation.findNavController(view).navigate(R.id.action_home_to_calendarFull));
|
viewAllCalendar.setOnClickListener(v -> Navigation.findNavController(view).navigate(R.id.action_home_to_calendarFull));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
fetchCalendarEvents(calendarRecycler);
|
|
||||||
} else {
|
|
||||||
requestPermissionLauncher.launch(Manifest.permission.READ_CALENDAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= 33) {
|
if (android.os.Build.VERSION.SDK_INT >= 33) {
|
||||||
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
|
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
|
||||||
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {}).launch(Manifest.permission.POST_NOTIFICATIONS);
|
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {}).launch(Manifest.permission.POST_NOTIFICATIONS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RecyclerView newsRecycler = view.findViewById(R.id.recycler_news);
|
newsRecycler = view.findViewById(R.id.recycler_news);
|
||||||
newsRecycler.setLayoutManager(new LinearLayoutManager(getContext()));
|
newsRecycler.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
newsRecycler.setNestedScrollingEnabled(false);
|
newsRecycler.setNestedScrollingEnabled(false);
|
||||||
newsRecycler.setAdapter(new NewsAdapter(new ArrayList<>(), item -> {}));
|
newsRecycler.setAdapter(new NewsAdapter(new ArrayList<>(), item -> {}));
|
||||||
|
|
@ -112,14 +115,32 @@ public class HomeFragment extends Fragment {
|
||||||
fetchNewsFromWordpress(newsRecycler);
|
fetchNewsFromWordpress(newsRecycler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchCalendarEvents(RecyclerView recyclerView) {
|
@Override
|
||||||
List<CalendarEvent> deviceEvents = CalendarManager.getDeviceEvents(getContext());
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
fetchCalendarEvents(calendarRecycler);
|
||||||
|
} else {
|
||||||
|
requestPermissionLauncher.launch(Manifest.permission.READ_CALENDAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fetchCalendarEvents(RecyclerView recyclerView) {
|
||||||
|
new Thread(() -> {
|
||||||
|
// isPreview = true for raskere lasting
|
||||||
|
List<CalendarEvent> deviceEvents = CalendarManager.getDeviceEvents(getContext(), true);
|
||||||
|
new Handler(Looper.getMainLooper()).post(() -> fetchApiEvents(recyclerView, deviceEvents));
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fetchApiEvents(RecyclerView recyclerView, List<CalendarEvent> deviceEvents) {
|
||||||
RetrofitClient.getApiService().getCalendarEvents().enqueue(new Callback<List<CalendarEvent>>() {
|
RetrofitClient.getApiService().getCalendarEvents().enqueue(new Callback<List<CalendarEvent>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<List<CalendarEvent>> call, Response<List<CalendarEvent>> response) {
|
public void onResponse(Call<List<CalendarEvent>> call, Response<List<CalendarEvent>> response) {
|
||||||
if (!isAdded()) return;
|
if (!isAdded()) return;
|
||||||
|
|
||||||
|
if (mainProgressBar != null) mainProgressBar.setVisibility(View.GONE);
|
||||||
|
|
||||||
List<CalendarEvent> apiEvents = new ArrayList<>();
|
List<CalendarEvent> apiEvents = new ArrayList<>();
|
||||||
if (response.isSuccessful() && response.body() != null) {
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
apiEvents = response.body();
|
apiEvents = response.body();
|
||||||
|
|
@ -145,6 +166,7 @@ public class HomeFragment extends Fragment {
|
||||||
|
|
||||||
recyclerView.setAdapter(new CalendarAdapter(top5, event -> {
|
recyclerView.setAdapter(new CalendarAdapter(top5, event -> {
|
||||||
CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event);
|
CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event);
|
||||||
|
sheet.setOnEventChangeListener(() -> fetchCalendarEvents(recyclerView));
|
||||||
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
@ -152,6 +174,9 @@ public class HomeFragment extends Fragment {
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<List<CalendarEvent>> call, Throwable t) {
|
public void onFailure(Call<List<CalendarEvent>> call, Throwable t) {
|
||||||
if (!isAdded()) return;
|
if (!isAdded()) return;
|
||||||
|
|
||||||
|
if (mainProgressBar != null) mainProgressBar.setVisibility(View.GONE);
|
||||||
|
|
||||||
if (!deviceEvents.isEmpty()) {
|
if (!deviceEvents.isEmpty()) {
|
||||||
List<CalendarEvent> top5 = new ArrayList<>();
|
List<CalendarEvent> top5 = new ArrayList<>();
|
||||||
for(int i=0; i<Math.min(deviceEvents.size(), 5); i++) top5.add(deviceEvents.get(i));
|
for(int i=0; i<Math.min(deviceEvents.size(), 5); i++) top5.add(deviceEvents.get(i));
|
||||||
|
|
@ -160,9 +185,7 @@ public class HomeFragment extends Fragment {
|
||||||
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
List<CalendarEvent> errorList = new ArrayList<>();
|
recyclerView.setAdapter(new CalendarAdapter(new ArrayList<>(), null));
|
||||||
errorList.add(new CalendarEvent("Kunne ikke laste kalender", "Sjekk nettverk", "!", "OBS", ""));
|
|
||||||
recyclerView.setAdapter(new CalendarAdapter(errorList, null));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
package com.kbs.kbsintranett;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.drawable.ColorDrawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
|
||||||
|
|
||||||
|
public class ImageDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
|
private static final String ARG_URL = "image_url";
|
||||||
|
|
||||||
|
public static ImageDialogFragment newInstance(String imageUrl) {
|
||||||
|
ImageDialogFragment fragment = new ImageDialogFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(ARG_URL, imageUrl);
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
// Gjør dialogen fullskjerm
|
||||||
|
Dialog dialog = getDialog();
|
||||||
|
if (dialog != null) {
|
||||||
|
int width = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||||
|
int height = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||||
|
dialog.getWindow().setLayout(width, height);
|
||||||
|
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
View view = inflater.inflate(R.layout.fragment_image_dialog, container, false);
|
||||||
|
|
||||||
|
ImageView imageView = view.findViewById(R.id.full_screen_image);
|
||||||
|
ImageButton closeBtn = view.findViewById(R.id.btn_close_image);
|
||||||
|
ProgressBar progressBar = view.findViewById(R.id.loading_image);
|
||||||
|
|
||||||
|
String url = getArguments() != null ? getArguments().getString(ARG_URL) : null;
|
||||||
|
|
||||||
|
if (url != null) {
|
||||||
|
Glide.with(this)
|
||||||
|
.load(url)
|
||||||
|
.transition(DrawableTransitionOptions.withCrossFade())
|
||||||
|
.listener(new com.bumptech.glide.request.RequestListener<android.graphics.drawable.Drawable>() {
|
||||||
|
@Override
|
||||||
|
public boolean onLoadFailed(@Nullable com.bumptech.glide.load.engine.GlideException e, Object model, com.bumptech.glide.request.target.Target<android.graphics.drawable.Drawable> target, boolean isFirstResource) {
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onResourceReady(android.graphics.drawable.Drawable resource, Object model, com.bumptech.glide.request.target.Target<android.graphics.drawable.Drawable> target, com.bumptech.glide.load.DataSource dataSource, boolean isFirstResource) {
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.into(imageView);
|
||||||
|
}
|
||||||
|
|
||||||
|
closeBtn.setOnClickListener(v -> dismiss());
|
||||||
|
// Lukk også hvis man trykker på selve bildet
|
||||||
|
imageView.setOnClickListener(v -> dismiss());
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||||
|
Dialog dialog = super.onCreateDialog(savedInstanceState);
|
||||||
|
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -36,14 +36,12 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
// VIKTIG: Sørg for at denne matcher den du har i Google Cloud Console
|
public static final String GOOGLE_WEB_CLIENT_ID = "738325360287-cidl3plnqv9ei74vm9vm5muustj6eenb.apps.googleusercontent.com"; // Bytt med din egen hvis denne er feil
|
||||||
public static final String GOOGLE_WEB_CLIENT_ID = "738325360287-cidl3plnqv9ei74vm9vm5muustj6eenb.apps.googleusercontent.com";
|
|
||||||
|
|
||||||
private static final String TAG = "MainActivity";
|
private static final String TAG = "MainActivity";
|
||||||
private NavController navController;
|
private NavController navController;
|
||||||
private BottomNavigationView bottomNav;
|
private BottomNavigationView bottomNav;
|
||||||
|
|
||||||
// Launcher for å spørre om varslingstillatelse (Android 13+)
|
|
||||||
private ActivityResultLauncher<String> requestPermissionLauncher;
|
private ActivityResultLauncher<String> requestPermissionLauncher;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -52,7 +50,6 @@ public class MainActivity extends AppCompatActivity {
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
// --- 1. SETUP UI & NAVIGASJON ---
|
// --- 1. SETUP UI & NAVIGASJON ---
|
||||||
// Sjekket activity_main.xml: ID er "bottom_nav_view"
|
|
||||||
bottomNav = findViewById(R.id.bottom_nav_view);
|
bottomNav = findViewById(R.id.bottom_nav_view);
|
||||||
|
|
||||||
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager()
|
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager()
|
||||||
|
|
@ -62,6 +59,13 @@ public class MainActivity extends AppCompatActivity {
|
||||||
navController = navHostFragment.getNavController();
|
navController = navHostFragment.getNavController();
|
||||||
if (bottomNav != null) {
|
if (bottomNav != null) {
|
||||||
NavigationUI.setupWithNavController(bottomNav, navController);
|
NavigationUI.setupWithNavController(bottomNav, navController);
|
||||||
|
|
||||||
|
// --- NYTT: Håndter "Reselection" (Klikk på fanen man allerede er i) ---
|
||||||
|
bottomNav.setOnItemReselectedListener(item -> {
|
||||||
|
// Dette fjerner alt som ligger "oppå" hovedsiden i stabelen.
|
||||||
|
// F.eks: Hjem -> Kalender Full -> (Klikk Hjem) -> Hjem
|
||||||
|
navController.popBackStack(item.getItemId(), false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skjul meny på login-skjerm
|
// Skjul meny på login-skjerm
|
||||||
|
|
@ -76,32 +80,26 @@ public class MainActivity extends AppCompatActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 2. VARSLINGSOPPSETT (NYTT) ---
|
// --- 2. VARSLINGSOPPSETT ---
|
||||||
createNotificationChannel();
|
createNotificationChannel();
|
||||||
|
|
||||||
// Initialiser permission launcher for varsler
|
|
||||||
requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
|
requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
|
||||||
if (isGranted) {
|
if (isGranted) {
|
||||||
Log.d(TAG, "Varslingstillatelse gitt!");
|
Log.d(TAG, "Varslingstillatelse gitt!");
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Varslingstillatelse avslått. Bruker får ikke kalendervarsler.");
|
Log.e(TAG, "Varslingstillatelse avslått.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sjekk tillatelser (både Varsler og Alarmer)
|
|
||||||
checkNotificationPermission();
|
checkNotificationPermission();
|
||||||
checkExactAlarmPermission();
|
checkExactAlarmPermission();
|
||||||
|
|
||||||
// Start bakgrunnsjobben for kalenderen
|
|
||||||
scheduleCalendarWork();
|
scheduleCalendarWork();
|
||||||
|
|
||||||
// --- 3. AUTENTISERING (GAMMELT) ---
|
// --- 3. AUTENTISERING ---
|
||||||
checkLoginState();
|
checkLoginState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sjekker om brukeren er logget inn med Google, og gjør en silent refresh mot WP.
|
|
||||||
*/
|
|
||||||
private void checkLoginState() {
|
private void checkLoginState() {
|
||||||
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
|
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
|
|
@ -160,8 +158,6 @@ public class MainActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- NYE HJELPEMETODER FOR VARSLING ---
|
|
||||||
|
|
||||||
private void createNotificationChannel() {
|
private void createNotificationChannel() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
CharSequence name = "KBS Kalendervarsler";
|
CharSequence name = "KBS Kalendervarsler";
|
||||||
|
|
@ -184,10 +180,6 @@ public class MainActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sjekker om appen har lov til å sette nøyaktige alarmer (SCHEDULE_EXACT_ALARM).
|
|
||||||
* Hvis ikke, spør brukeren om å gå til innstillinger.
|
|
||||||
*/
|
|
||||||
private void checkExactAlarmPermission() {
|
private void checkExactAlarmPermission() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||||
|
|
@ -206,9 +198,6 @@ public class MainActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Starter WorkManager som sjekker kalenderen hvert 15. minutt.
|
|
||||||
*/
|
|
||||||
private void scheduleCalendarWork() {
|
private void scheduleCalendarWork() {
|
||||||
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(NotificationWorker.class, 15, TimeUnit.MINUTES)
|
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(NotificationWorker.class, 15, TimeUnit.MINUTES)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
package com.kbs.kbsintranett;
|
package com.kbs.kbsintranett;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Html;
|
|
||||||
import android.text.method.LinkMovementMethod;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.webkit.JavascriptInterface;
|
||||||
|
import android.webkit.WebSettings;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import android.webkit.WebViewClient;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
@ -17,6 +20,41 @@ import com.bumptech.glide.Glide;
|
||||||
|
|
||||||
public class NewsDetailFragment extends Fragment {
|
public class NewsDetailFragment extends Fragment {
|
||||||
|
|
||||||
|
// CSS Styling (Samme stil som håndboken, pluss bildehåndtering)
|
||||||
|
private static final String CSS_STYLE =
|
||||||
|
"<style>" +
|
||||||
|
"body { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #333333; line-height: 1.6; padding: 0; margin: 0; }" +
|
||||||
|
"p, ul, li { margin-bottom: 12px; font-size: 16px; }" +
|
||||||
|
"a { color: #0069B3; font-weight: bold; text-decoration: none; }" +
|
||||||
|
"h1, h2, h3 { color: #0069B3; margin-top: 20px; margin-bottom: 10px; }" +
|
||||||
|
|
||||||
|
// Bilde-styling
|
||||||
|
"img { " +
|
||||||
|
" max-width: 100% !important; " +
|
||||||
|
" height: auto !important; " +
|
||||||
|
" border-radius: 4px; " +
|
||||||
|
" margin: 16px 0; " +
|
||||||
|
" box-shadow: 0 2px 5px rgba(0,0,0,0.1); " +
|
||||||
|
" display: block;" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
// Fjerner unødvendig whitespace fra WP-galleri
|
||||||
|
".gallery-item { margin: 0; padding: 0; }" +
|
||||||
|
"</style>";
|
||||||
|
|
||||||
|
// JavaScript for å fange opp bildeklikk
|
||||||
|
private static final String JS_SCRIPT =
|
||||||
|
"<script>" +
|
||||||
|
"document.addEventListener('DOMContentLoaded', function() {" +
|
||||||
|
" var images = document.getElementsByTagName('img');" +
|
||||||
|
" for (var i = 0; i < images.length; i++) {" +
|
||||||
|
" images[i].onclick = function() {" +
|
||||||
|
" Android.showImage(this.src);" +
|
||||||
|
" }" +
|
||||||
|
" }" +
|
||||||
|
"});" +
|
||||||
|
"</script>";
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
|
@ -27,7 +65,6 @@ public class NewsDetailFragment extends Fragment {
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
// Hent data fra argumentene (sendt fra HomeFragment/NewsFullFragment)
|
|
||||||
if (getArguments() != null) {
|
if (getArguments() != null) {
|
||||||
WpPost post = (WpPost) getArguments().getSerializable("post_data");
|
WpPost post = (WpPost) getArguments().getSerializable("post_data");
|
||||||
if (post != null) {
|
if (post != null) {
|
||||||
|
|
@ -44,9 +81,10 @@ public class NewsDetailFragment extends Fragment {
|
||||||
TextView title = view.findViewById(R.id.detail_title);
|
TextView title = view.findViewById(R.id.detail_title);
|
||||||
TextView category = view.findViewById(R.id.detail_category);
|
TextView category = view.findViewById(R.id.detail_category);
|
||||||
TextView date = view.findViewById(R.id.detail_date);
|
TextView date = view.findViewById(R.id.detail_date);
|
||||||
TextView author = view.findViewById(R.id.detail_author); // NY
|
TextView author = view.findViewById(R.id.detail_author);
|
||||||
TextView content = view.findViewById(R.id.detail_content);
|
WebView webView = view.findViewById(R.id.detail_webview);
|
||||||
|
|
||||||
|
// Header bilde
|
||||||
String imgUrl = post.getFeaturedImageUrl();
|
String imgUrl = post.getFeaturedImageUrl();
|
||||||
if (imgUrl != null) {
|
if (imgUrl != null) {
|
||||||
Glide.with(this).load(imgUrl).centerCrop().into(image);
|
Glide.with(this).load(imgUrl).centerCrop().into(image);
|
||||||
|
|
@ -57,11 +95,59 @@ public class NewsDetailFragment extends Fragment {
|
||||||
title.setText(post.getTitleStr());
|
title.setText(post.getTitleStr());
|
||||||
category.setText(post.getCategoryName());
|
category.setText(post.getCategoryName());
|
||||||
date.setText("Publisert: " + post.date);
|
date.setText("Publisert: " + post.date);
|
||||||
|
|
||||||
// NYTT: Sett forfatter
|
|
||||||
author.setText("Av: " + post.getAuthorName());
|
author.setText("Av: " + post.getAuthorName());
|
||||||
|
|
||||||
content.setText(Html.fromHtml(post.getContentStr(), Html.FROM_HTML_MODE_COMPACT));
|
// Konfigurer WebView
|
||||||
content.setMovementMethod(LinkMovementMethod.getInstance());
|
WebSettings settings = webView.getSettings();
|
||||||
|
settings.setJavaScriptEnabled(true);
|
||||||
|
settings.setDomStorageEnabled(true);
|
||||||
|
|
||||||
|
// Legg til Interface for å snakke med Java
|
||||||
|
webView.addJavascriptInterface(new WebAppInterface(getContext()), "Android");
|
||||||
|
|
||||||
|
// Håndter linker internt (som i Håndboken)
|
||||||
|
webView.setWebViewClient(new WebViewClient() {
|
||||||
|
@Override
|
||||||
|
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||||
|
// Bruk samme link-logikk som i Håndboken hvis nødvendig,
|
||||||
|
// men her lar vi linker åpnes i nettleser for enkelhets skyld foreløpig
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Bygg HTML
|
||||||
|
String rawContent = post.getContentStr();
|
||||||
|
|
||||||
|
// Vask innholdet litt hvis nødvendig (f.eks fjerne inline styles som ødelegger)
|
||||||
|
// Her legger vi bare til vår CSS og JS
|
||||||
|
String htmlData = "<!DOCTYPE html><html><head>" +
|
||||||
|
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" +
|
||||||
|
CSS_STYLE +
|
||||||
|
JS_SCRIPT +
|
||||||
|
"</head><body>" +
|
||||||
|
rawContent +
|
||||||
|
"</body></html>";
|
||||||
|
|
||||||
|
webView.loadDataWithBaseURL("https://intranet.kbs.no", htmlData, "text/html", "UTF-8", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bridge-klasse for å ta imot klikk fra JavaScript
|
||||||
|
public class WebAppInterface {
|
||||||
|
Context mContext;
|
||||||
|
|
||||||
|
WebAppInterface(Context c) {
|
||||||
|
mContext = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JavascriptInterface
|
||||||
|
public void showImage(String url) {
|
||||||
|
// Må kjøres på UI-tråden
|
||||||
|
if (getActivity() != null) {
|
||||||
|
getActivity().runOnUiThread(() -> {
|
||||||
|
ImageDialogFragment dialog = ImageDialogFragment.newInstance(url);
|
||||||
|
dialog.show(getParentFragmentManager(), "image_lightbox");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -27,22 +27,24 @@ public class ProfileFragment extends Fragment {
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_profile, container, false);
|
View view = inflater.inflate(R.layout.fragment_profile, container, false);
|
||||||
|
|
||||||
// 1. Finn Views
|
|
||||||
ImageView closeBtn = view.findViewById(R.id.btn_close_profile);
|
ImageView closeBtn = view.findViewById(R.id.btn_close_profile);
|
||||||
ImageView profileImage = view.findViewById(R.id.profile_image);
|
ImageView profileImage = view.findViewById(R.id.profile_image);
|
||||||
TextView nameText = view.findViewById(R.id.profile_name);
|
TextView nameText = view.findViewById(R.id.profile_name);
|
||||||
TextView emailText = view.findViewById(R.id.profile_email);
|
TextView emailText = view.findViewById(R.id.profile_email);
|
||||||
TextView roleText = view.findViewById(R.id.profile_role);
|
TextView roleText = view.findViewById(R.id.profile_role);
|
||||||
Button logoutBtn = view.findViewById(R.id.btn_logout);
|
Button logoutBtn = view.findViewById(R.id.btn_logout);
|
||||||
Button updateInfoBtn = view.findViewById(R.id.btn_update_info); // NY
|
Button updateInfoBtn = view.findViewById(R.id.btn_update_info);
|
||||||
|
TextView versionText = view.findViewById(R.id.tv_version_info); // NYTT
|
||||||
|
|
||||||
// 2. Hent data fra UserManager
|
|
||||||
UserManager user = UserManager.getInstance();
|
UserManager user = UserManager.getInstance();
|
||||||
nameText.setText(user.getUserDisplayName());
|
nameText.setText(user.getUserDisplayName());
|
||||||
emailText.setText(user.getUserEmail());
|
emailText.setText(user.getUserEmail());
|
||||||
roleText.setText("Rolle: " + user.getUserRole());
|
roleText.setText("Rolle: " + user.getUserRole());
|
||||||
|
|
||||||
// 3. Last bilde med Glide
|
// NYTT: Sett versjonstekst
|
||||||
|
String versionInfo = "Versjon " + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")";
|
||||||
|
versionText.setText(versionInfo);
|
||||||
|
|
||||||
if (user.getPhotoUrl() != null) {
|
if (user.getPhotoUrl() != null) {
|
||||||
Glide.with(this)
|
Glide.with(this)
|
||||||
.load(user.getPhotoUrl())
|
.load(user.getPhotoUrl())
|
||||||
|
|
@ -50,44 +52,33 @@ public class ProfileFragment extends Fragment {
|
||||||
.into(profileImage);
|
.into(profileImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Håndter "Lukk" (X) knapp - Gå tilbake til forrige skjerm
|
|
||||||
closeBtn.setOnClickListener(v -> {
|
closeBtn.setOnClickListener(v -> {
|
||||||
Navigation.findNavController(view).navigateUp();
|
Navigation.findNavController(view).navigateUp();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 5. Håndter "Oppdater opplysninger" (Skjema ID 1)
|
|
||||||
updateInfoBtn.setOnClickListener(v -> {
|
updateInfoBtn.setOnClickListener(v -> {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putInt("formId", 1); // ID 1 er Ansatteopplysninger
|
bundle.putInt("formId", 1);
|
||||||
Navigation.findNavController(view).navigate(R.id.action_profile_to_form, bundle);
|
Navigation.findNavController(view).navigate(R.id.action_profile_to_form, bundle);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 6. Håndter utlogging
|
|
||||||
logoutBtn.setOnClickListener(v -> performLogout());
|
logoutBtn.setOnClickListener(v -> performLogout());
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performLogout() {
|
private void performLogout() {
|
||||||
// A. Konfigurer Google Client
|
|
||||||
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||||
.requestIdToken(MainActivity.GOOGLE_WEB_CLIENT_ID)
|
.requestIdToken(MainActivity.GOOGLE_WEB_CLIENT_ID)
|
||||||
.requestEmail()
|
.requestEmail()
|
||||||
.build();
|
.build();
|
||||||
GoogleSignInClient client = GoogleSignIn.getClient(requireActivity(), gso);
|
GoogleSignInClient client = GoogleSignIn.getClient(requireActivity(), gso);
|
||||||
|
|
||||||
// B. Logg ut fra Google
|
|
||||||
client.signOut().addOnCompleteListener(task -> {
|
client.signOut().addOnCompleteListener(task -> {
|
||||||
|
|
||||||
// C. Tøm interne data
|
|
||||||
UserManager.getInstance().logout();
|
UserManager.getInstance().logout();
|
||||||
RetrofitClient.clearClient();
|
RetrofitClient.clearClient();
|
||||||
|
|
||||||
// D. Naviger tilbake til Login-skjermen
|
|
||||||
NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment);
|
NavController navController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment);
|
||||||
// Denne aksjonen finnes i mobile_navigation.xml
|
|
||||||
navController.navigate(R.id.action_profile_to_login);
|
navController.navigate(R.id.action_profile_to_login);
|
||||||
|
|
||||||
Toast.makeText(getContext(), "Du er nå logget ut", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Du er nå logget ut", Toast.LENGTH_SHORT).show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,126 +1,137 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:background="@color/kbs_very_light_blue">
|
android:background="@color/kbs_very_light_blue">
|
||||||
|
|
||||||
<!-- OVERSKRIFT OG PROFIL -->
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:paddingHorizontal="8dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="KBS Intranett"
|
|
||||||
android:textSize="24sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:textColor="@color/kbs_muted_blue_gray"
|
|
||||||
android:layout_centerVertical="true"/>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/btn_profile"
|
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:src="@android:drawable/ic_menu_my_calendar"
|
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
app:tint="@color/kbs_logo_blue"/>
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<!-- NYTT: KNAPP FOR Å OPPRETTE HENDELSE -->
|
|
||||||
<!-- Denne var borte i din fil. Den settes til visibility="gone" som standard,
|
|
||||||
og skrus på av Java-koden hvis brukeren er admin. -->
|
|
||||||
<Button
|
|
||||||
android:id="@+id/btn_create_event"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="+ Ny Kalenderhendelse"
|
|
||||||
android:backgroundTint="@color/kbs_logo_blue"
|
|
||||||
android:textColor="#FFFFFF"
|
|
||||||
android:layout_marginHorizontal="8dp"
|
|
||||||
android:layout_marginBottom="12dp"
|
|
||||||
android:visibility="gone"/>
|
|
||||||
|
|
||||||
<!-- KALENDER-SEKSJON -->
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:orientation="horizontal"
|
android:orientation="vertical"
|
||||||
android:gravity="center_vertical"
|
android:padding="8dp">
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginEnd="8dp">
|
|
||||||
|
|
||||||
<TextView
|
<!-- OVERSKRIFT OG PROFIL -->
|
||||||
android:layout_width="0dp"
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:paddingHorizontal="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="KBS Intranett"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/kbs_muted_blue_gray"
|
||||||
|
android:layout_centerVertical="true"/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/btn_profile"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:src="@android:drawable/ic_menu_my_calendar"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
app:tint="@color/kbs_logo_blue"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_create_event"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="+ Ny Kalenderhendelse"
|
||||||
|
android:backgroundTint="@color/kbs_logo_blue"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:layout_marginHorizontal="8dp"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
|
<!-- KALENDER-SEKSJON -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Kommende hendelser"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/black"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/btn_view_all_calendar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Se alle >"
|
||||||
|
android:textColor="@color/kbs_logo_blue"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:background="?attr/selectableItemBackground"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_calendar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="Kommende hendelser"
|
android:scrollbars="vertical"
|
||||||
android:textSize="18sp"
|
android:layout_marginBottom="16dp"/>
|
||||||
android:textStyle="bold"
|
|
||||||
android:textColor="@color/black"/>
|
|
||||||
|
|
||||||
<TextView
|
<!-- NYHETER-SEKSJON -->
|
||||||
android:id="@+id/btn_view_all_calendar"
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Se alle >"
|
android:orientation="horizontal"
|
||||||
android:textColor="@color/kbs_logo_blue"
|
android:gravity="center_vertical"
|
||||||
android:textStyle="bold"
|
android:layout_marginBottom="8dp"
|
||||||
android:padding="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:background="?attr/selectableItemBackground"/>
|
android:layout_marginEnd="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Siste nytt"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/black"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/btn_view_all_news"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Se alle >"
|
||||||
|
android:textColor="@color/kbs_logo_blue"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:background="?attr/selectableItemBackground"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_news"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="2"
|
||||||
|
android:scrollbars="vertical"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<!-- DENNE MANGLER SANNZYNLIGVIS HOS DEG NÅ: -->
|
||||||
android:id="@+id/recycler_calendar"
|
<ProgressBar
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/main_loading_spinner"
|
||||||
android:layout_height="0dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_weight="1"
|
|
||||||
android:scrollbars="vertical"
|
|
||||||
android:layout_marginBottom="16dp"/>
|
|
||||||
|
|
||||||
<!-- NYHETER-SEKSJON -->
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:layout_gravity="center"
|
||||||
android:gravity="center_vertical"
|
android:visibility="visible"/>
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginEnd="8dp">
|
|
||||||
|
|
||||||
<TextView
|
</FrameLayout>
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="Siste nytt"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:textColor="@color/black"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/btn_view_all_news"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Se alle >"
|
|
||||||
android:textColor="@color/kbs_logo_blue"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:background="?attr/selectableItemBackground"/>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/recycler_news"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="2"
|
|
||||||
android:scrollbars="vertical"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
36
app/src/main/res/layout/fragment_image_dialog.xml
Normal file
36
app/src/main/res/layout/fragment_image_dialog.xml
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@android:color/black">
|
||||||
|
|
||||||
|
<!-- Lukkeknapp -->
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_close_image"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:src="@android:drawable/ic_menu_close_clear_cancel"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:tint="@android:color/white"
|
||||||
|
android:elevation="10dp"/>
|
||||||
|
|
||||||
|
<!-- Selve bildet -->
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/full_screen_image"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:adjustViewBounds="true"/>
|
||||||
|
|
||||||
|
<!-- Loading spinner -->
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/loading_image"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="16dp">
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<!-- Kategori -->
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/detail_category"
|
android:id="@+id/detail_category"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
@ -55,6 +56,7 @@
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
android:layout_marginBottom="8dp"/>
|
android:layout_marginBottom="8dp"/>
|
||||||
|
|
||||||
|
<!-- Tittel -->
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/detail_title"
|
android:id="@+id/detail_title"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
@ -64,6 +66,7 @@
|
||||||
android:textColor="@android:color/black"
|
android:textColor="@android:color/black"
|
||||||
android:layout_marginBottom="8dp"/>
|
android:layout_marginBottom="8dp"/>
|
||||||
|
|
||||||
|
<!-- Dato og Forfatter -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
@ -88,13 +91,12 @@
|
||||||
android:text="Av: Forfatter"/>
|
android:text="Av: Forfatter"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<!-- BYTTET FRA TextView TIL WebView -->
|
||||||
android:id="@+id/detail_content"
|
<WebView
|
||||||
|
android:id="@+id/detail_webview"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="#333333"
|
android:scrollbars="none" />
|
||||||
android:textSize="16sp"
|
|
||||||
android:lineSpacingExtra="4dp"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,17 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Logg ut"
|
android:text="Logg ut"
|
||||||
android:backgroundTint="@color/kbs_logo_accent_red"
|
android:backgroundTint="@color/kbs_logo_accent_red"
|
||||||
android:textColor="@color/white"/>
|
android:textColor="@color/white"
|
||||||
|
android:layout_marginBottom="32dp"/>
|
||||||
|
|
||||||
|
<!-- NYTT: VERSJONSINFO -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_version_info"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Versjon 1.0"
|
||||||
|
android:textColor="#999999"
|
||||||
|
android:textSize="12sp"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application) apply false
|
alias(libs.plugins.android.application) apply false
|
||||||
}
|
// NY LINJE: Legg til Google Services plugin her
|
||||||
|
id("com.google.gms.google-services") version "4.4.2" apply false
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue