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 {
|
||||
alias(libs.plugins.android.application)
|
||||
// NY LINJE: Aktiver Google Services plugin her
|
||||
id("com.google.gms.google-services")
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
@ -10,8 +12,8 @@ android {
|
|||
applicationId = "com.kbs.kbsintranett"
|
||||
minSdk = 28
|
||||
targetSdk = 34
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
versionCode = 2
|
||||
versionName = "1.2"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
|
@ -63,4 +65,10 @@ dependencies {
|
|||
|
||||
// Swipe Refresh Layout
|
||||
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 androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import com.google.gson.JsonElement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class CalendarDetailsBottomSheet extends BottomSheetDialogFragment {
|
||||
private CalendarEvent event;
|
||||
private OnEventChangeListener changeListener;
|
||||
|
||||
// Interface for å varsle foreldre-fragmentet om endringer
|
||||
public interface OnEventChangeListener {
|
||||
void onEventChanged();
|
||||
}
|
||||
|
||||
public CalendarDetailsBottomSheet(CalendarEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public void setOnEventChangeListener(OnEventChangeListener listener) {
|
||||
this.changeListener = listener;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
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 desc = view.findViewById(R.id.sheet_desc);
|
||||
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);
|
||||
Button btnDelete = view.findViewById(R.id.btn_delete);
|
||||
|
|
@ -50,7 +58,6 @@ public class CalendarDetailsBottomSheet extends BottomSheetDialogFragment {
|
|||
title.setText(event.getTitle());
|
||||
time.setText(event.getTime() + " (" + event.getDay() + ". " + event.getMonth() + ")");
|
||||
|
||||
// NYTT: Sett navn og farge
|
||||
calName.setText(event.getCalendarName().toUpperCase());
|
||||
try {
|
||||
int color = Color.parseColor(event.getCalendarColor());
|
||||
|
|
@ -75,13 +82,6 @@ public class CalendarDetailsBottomSheet extends BottomSheetDialogFragment {
|
|||
|
||||
// Sjekk admin-rettigheter
|
||||
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())
|
||||
|| UserManager.getInstance().isAdmin();
|
||||
|
||||
|
|
@ -122,6 +122,12 @@ public class CalendarDetailsBottomSheet extends BottomSheetDialogFragment {
|
|||
public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
|
||||
if (response.isSuccessful()) {
|
||||
Toast.makeText(getContext(), "Slettet!", Toast.LENGTH_SHORT).show();
|
||||
|
||||
// VARSLE LISTEN OM AT NOE ER SLETTET
|
||||
if (changeListener != null) {
|
||||
changeListener.onEventChanged();
|
||||
}
|
||||
|
||||
dismiss();
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Kunne ikke slette", Toast.LENGTH_LONG).show();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
|
@ -46,16 +48,25 @@ public class CalendarFullFragment extends Fragment {
|
|||
layoutManager = new LinearLayoutManager(getContext());
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
backBtn.setOnClickListener(v -> Navigation.findNavController(view).navigateUp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
fetchAllEvents();
|
||||
}
|
||||
|
||||
private void fetchAllEvents() {
|
||||
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>>() {
|
||||
@Override
|
||||
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<>();
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
apiEvents = response.body();
|
||||
// Formater data for visning
|
||||
for (CalendarEvent e : apiEvents) {
|
||||
CalendarManager.formatEventForUI(e);
|
||||
}
|
||||
|
|
@ -82,6 +92,7 @@ public class CalendarFullFragment extends Fragment {
|
|||
|
||||
CalendarAdapter adapter = new CalendarAdapter(allEvents, event -> {
|
||||
CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event);
|
||||
sheet.setOnEventChangeListener(CalendarFullFragment.this::fetchAllEvents);
|
||||
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
||||
});
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
|
@ -126,5 +137,4 @@ public class CalendarFullFragment extends Fragment {
|
|||
layoutManager.scrollToPositionWithOffset(scrollIndex, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,8 +9,10 @@ import java.text.SimpleDateFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class CalendarManager {
|
||||
|
|
@ -44,7 +46,13 @@ public class CalendarManager {
|
|||
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<>();
|
||||
if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.READ_CALENDAR)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
|
|
@ -57,8 +65,20 @@ public class CalendarManager {
|
|||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
long startMillis = now - (365L * 24 * 60 * 60 * 1000);
|
||||
long endMillis = now + (365L * 24 * 60 * 60 * 1000);
|
||||
long startMillis;
|
||||
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[]{
|
||||
CalendarContract.Events.TITLE,
|
||||
|
|
@ -120,8 +140,7 @@ public class CalendarManager {
|
|||
CalendarEvent event = new CalendarEvent(title, rawStart, rawEnd, desc, loc);
|
||||
event.setReminderMinutes(0);
|
||||
|
||||
// NYTT V12.2: Sett standardfarge for lokale kalendere
|
||||
event.setCalendarColor("#888888"); // Grå for lokale events
|
||||
event.setCalendarColor("#888888");
|
||||
event.setCalendarName("Min Kalender (Lokal)");
|
||||
|
||||
formatEventForUI(event);
|
||||
|
|
@ -200,9 +219,24 @@ public class CalendarManager {
|
|||
}
|
||||
|
||||
public static List<CalendarEvent> mergeAndSort(List<CalendarEvent> apiEvents, List<CalendarEvent> deviceEvents) {
|
||||
List<CalendarEvent> all = new ArrayList<>(apiEvents);
|
||||
all.addAll(deviceEvents);
|
||||
List<CalendarEvent> all = new ArrayList<>();
|
||||
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) -> {
|
||||
String d1 = e1.getRawDate() != null ? e1.getRawDate() : "";
|
||||
String d2 = e2.getRawDate() != null ? e2.getRawDate() : "";
|
||||
|
|
@ -212,4 +246,20 @@ public class CalendarManager {
|
|||
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);
|
||||
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
|
||||
try {
|
||||
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.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
|
|
@ -33,6 +36,8 @@ import retrofit2.Response;
|
|||
public class HomeFragment extends Fragment {
|
||||
private ActivityResultLauncher<String> requestPermissionLauncher;
|
||||
private RecyclerView calendarRecycler;
|
||||
private RecyclerView newsRecycler;
|
||||
private ProgressBar mainProgressBar; // Variabelen som må være her
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
|
|
@ -58,12 +63,16 @@ public class HomeFragment extends Fragment {
|
|||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
// Her leter vi etter IDen som MÅ finnes i XML-filen over
|
||||
mainProgressBar = view.findViewById(R.id.main_loading_spinner);
|
||||
|
||||
if (mainProgressBar != null) mainProgressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
View profileBtn = view.findViewById(R.id.btn_profile);
|
||||
if (profileBtn != null) {
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
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 (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
|
||||
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.setNestedScrollingEnabled(false);
|
||||
newsRecycler.setAdapter(new NewsAdapter(new ArrayList<>(), item -> {}));
|
||||
|
|
@ -112,14 +115,32 @@ public class HomeFragment extends Fragment {
|
|||
fetchNewsFromWordpress(newsRecycler);
|
||||
}
|
||||
|
||||
private void fetchCalendarEvents(RecyclerView recyclerView) {
|
||||
List<CalendarEvent> deviceEvents = CalendarManager.getDeviceEvents(getContext());
|
||||
@Override
|
||||
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>>() {
|
||||
@Override
|
||||
public void onResponse(Call<List<CalendarEvent>> call, Response<List<CalendarEvent>> response) {
|
||||
if (!isAdded()) return;
|
||||
|
||||
if (mainProgressBar != null) mainProgressBar.setVisibility(View.GONE);
|
||||
|
||||
List<CalendarEvent> apiEvents = new ArrayList<>();
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
apiEvents = response.body();
|
||||
|
|
@ -145,6 +166,7 @@ public class HomeFragment extends Fragment {
|
|||
|
||||
recyclerView.setAdapter(new CalendarAdapter(top5, event -> {
|
||||
CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event);
|
||||
sheet.setOnEventChangeListener(() -> fetchCalendarEvents(recyclerView));
|
||||
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
||||
}));
|
||||
}
|
||||
|
|
@ -152,6 +174,9 @@ public class HomeFragment extends Fragment {
|
|||
@Override
|
||||
public void onFailure(Call<List<CalendarEvent>> call, Throwable t) {
|
||||
if (!isAdded()) return;
|
||||
|
||||
if (mainProgressBar != null) mainProgressBar.setVisibility(View.GONE);
|
||||
|
||||
if (!deviceEvents.isEmpty()) {
|
||||
List<CalendarEvent> top5 = new ArrayList<>();
|
||||
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");
|
||||
}));
|
||||
} else {
|
||||
List<CalendarEvent> errorList = new ArrayList<>();
|
||||
errorList.add(new CalendarEvent("Kunne ikke laste kalender", "Sjekk nettverk", "!", "OBS", ""));
|
||||
recyclerView.setAdapter(new CalendarAdapter(errorList, null));
|
||||
recyclerView.setAdapter(new CalendarAdapter(new ArrayList<>(), 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 {
|
||||
|
||||
// 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";
|
||||
public static final String GOOGLE_WEB_CLIENT_ID = "738325360287-cidl3plnqv9ei74vm9vm5muustj6eenb.apps.googleusercontent.com"; // Bytt med din egen hvis denne er feil
|
||||
|
||||
private static final String TAG = "MainActivity";
|
||||
private NavController navController;
|
||||
private BottomNavigationView bottomNav;
|
||||
|
||||
// Launcher for å spørre om varslingstillatelse (Android 13+)
|
||||
private ActivityResultLauncher<String> requestPermissionLauncher;
|
||||
|
||||
@Override
|
||||
|
|
@ -52,7 +50,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
setContentView(R.layout.activity_main);
|
||||
|
||||
// --- 1. SETUP UI & NAVIGASJON ---
|
||||
// Sjekket activity_main.xml: ID er "bottom_nav_view"
|
||||
bottomNav = findViewById(R.id.bottom_nav_view);
|
||||
|
||||
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager()
|
||||
|
|
@ -62,6 +59,13 @@ public class MainActivity extends AppCompatActivity {
|
|||
navController = navHostFragment.getNavController();
|
||||
if (bottomNav != null) {
|
||||
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
|
||||
|
|
@ -76,32 +80,26 @@ public class MainActivity extends AppCompatActivity {
|
|||
});
|
||||
}
|
||||
|
||||
// --- 2. VARSLINGSOPPSETT (NYTT) ---
|
||||
// --- 2. VARSLINGSOPPSETT ---
|
||||
createNotificationChannel();
|
||||
|
||||
// Initialiser permission launcher for varsler
|
||||
requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
|
||||
if (isGranted) {
|
||||
Log.d(TAG, "Varslingstillatelse gitt!");
|
||||
} 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();
|
||||
checkExactAlarmPermission();
|
||||
|
||||
// Start bakgrunnsjobben for kalenderen
|
||||
scheduleCalendarWork();
|
||||
|
||||
// --- 3. AUTENTISERING (GAMMELT) ---
|
||||
// --- 3. AUTENTISERING ---
|
||||
checkLoginState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sjekker om brukeren er logget inn med Google, og gjør en silent refresh mot WP.
|
||||
*/
|
||||
private void checkLoginState() {
|
||||
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
|
||||
if (account == null) {
|
||||
|
|
@ -160,8 +158,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
// --- NYE HJELPEMETODER FOR VARSLING ---
|
||||
|
||||
private void createNotificationChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
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() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
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() {
|
||||
PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(NotificationWorker.class, 15, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
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.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
|
|
@ -17,6 +20,41 @@ import com.bumptech.glide.Glide;
|
|||
|
||||
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
|
||||
@Override
|
||||
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) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
// Hent data fra argumentene (sendt fra HomeFragment/NewsFullFragment)
|
||||
if (getArguments() != null) {
|
||||
WpPost post = (WpPost) getArguments().getSerializable("post_data");
|
||||
if (post != null) {
|
||||
|
|
@ -44,9 +81,10 @@ public class NewsDetailFragment extends Fragment {
|
|||
TextView title = view.findViewById(R.id.detail_title);
|
||||
TextView category = view.findViewById(R.id.detail_category);
|
||||
TextView date = view.findViewById(R.id.detail_date);
|
||||
TextView author = view.findViewById(R.id.detail_author); // NY
|
||||
TextView content = view.findViewById(R.id.detail_content);
|
||||
TextView author = view.findViewById(R.id.detail_author);
|
||||
WebView webView = view.findViewById(R.id.detail_webview);
|
||||
|
||||
// Header bilde
|
||||
String imgUrl = post.getFeaturedImageUrl();
|
||||
if (imgUrl != null) {
|
||||
Glide.with(this).load(imgUrl).centerCrop().into(image);
|
||||
|
|
@ -57,11 +95,59 @@ public class NewsDetailFragment extends Fragment {
|
|||
title.setText(post.getTitleStr());
|
||||
category.setText(post.getCategoryName());
|
||||
date.setText("Publisert: " + post.date);
|
||||
|
||||
// NYTT: Sett forfatter
|
||||
author.setText("Av: " + post.getAuthorName());
|
||||
|
||||
content.setText(Html.fromHtml(post.getContentStr(), Html.FROM_HTML_MODE_COMPACT));
|
||||
content.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
// Konfigurer WebView
|
||||
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) {
|
||||
View view = inflater.inflate(R.layout.fragment_profile, container, false);
|
||||
|
||||
// 1. Finn Views
|
||||
ImageView closeBtn = view.findViewById(R.id.btn_close_profile);
|
||||
ImageView profileImage = view.findViewById(R.id.profile_image);
|
||||
TextView nameText = view.findViewById(R.id.profile_name);
|
||||
TextView emailText = view.findViewById(R.id.profile_email);
|
||||
TextView roleText = view.findViewById(R.id.profile_role);
|
||||
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();
|
||||
nameText.setText(user.getUserDisplayName());
|
||||
emailText.setText(user.getUserEmail());
|
||||
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) {
|
||||
Glide.with(this)
|
||||
.load(user.getPhotoUrl())
|
||||
|
|
@ -50,44 +52,33 @@ public class ProfileFragment extends Fragment {
|
|||
.into(profileImage);
|
||||
}
|
||||
|
||||
// 4. Håndter "Lukk" (X) knapp - Gå tilbake til forrige skjerm
|
||||
closeBtn.setOnClickListener(v -> {
|
||||
Navigation.findNavController(view).navigateUp();
|
||||
});
|
||||
|
||||
// 5. Håndter "Oppdater opplysninger" (Skjema ID 1)
|
||||
updateInfoBtn.setOnClickListener(v -> {
|
||||
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);
|
||||
});
|
||||
|
||||
// 6. Håndter utlogging
|
||||
logoutBtn.setOnClickListener(v -> performLogout());
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void performLogout() {
|
||||
// A. Konfigurer Google Client
|
||||
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
.requestIdToken(MainActivity.GOOGLE_WEB_CLIENT_ID)
|
||||
.requestEmail()
|
||||
.build();
|
||||
GoogleSignInClient client = GoogleSignIn.getClient(requireActivity(), gso);
|
||||
|
||||
// B. Logg ut fra Google
|
||||
client.signOut().addOnCompleteListener(task -> {
|
||||
|
||||
// C. Tøm interne data
|
||||
UserManager.getInstance().logout();
|
||||
RetrofitClient.clearClient();
|
||||
|
||||
// D. Naviger tilbake til Login-skjermen
|
||||
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);
|
||||
|
||||
Toast.makeText(getContext(), "Du er nå logget ut", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,126 +1,137 @@
|
|||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
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
|
||||
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">
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
<!-- 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>
|
||||
|
||||
<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:text="Kommende hendelser"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/black"/>
|
||||
android:scrollbars="vertical"
|
||||
android:layout_marginBottom="16dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btn_view_all_calendar"
|
||||
android:layout_width="wrap_content"
|
||||
<!-- NYHETER-SEKSJON -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
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"/>
|
||||
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="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>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_calendar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:scrollbars="vertical"
|
||||
android:layout_marginBottom="16dp"/>
|
||||
|
||||
<!-- NYHETER-SEKSJON -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
<!-- DENNE MANGLER SANNZYNLIGVIS HOS DEG NÅ: -->
|
||||
<ProgressBar
|
||||
android:id="@+id/main_loading_spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp">
|
||||
android:layout_gravity="center"
|
||||
android:visibility="visible"/>
|
||||
|
||||
<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>
|
||||
</FrameLayout>
|
||||
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:padding="16dp">
|
||||
|
||||
<!-- Kategori -->
|
||||
<TextView
|
||||
android:id="@+id/detail_category"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
@ -55,6 +56,7 @@
|
|||
android:textSize="12sp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<!-- Tittel -->
|
||||
<TextView
|
||||
android:id="@+id/detail_title"
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -64,6 +66,7 @@
|
|||
android:textColor="@android:color/black"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<!-- Dato og Forfatter -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -88,13 +91,12 @@
|
|||
android:text="Av: Forfatter"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/detail_content"
|
||||
<!-- BYTTET FRA TextView TIL WebView -->
|
||||
<WebView
|
||||
android:id="@+id/detail_webview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp"
|
||||
android:lineSpacingExtra="4dp"/>
|
||||
android:scrollbars="none" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
|
|
|||
|
|
@ -97,7 +97,17 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="Logg ut"
|
||||
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>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
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