Før håndbok versjon 2
This commit is contained in:
parent
e4affef594
commit
b6423384ca
20 changed files with 785 additions and 40 deletions
|
|
@ -1,25 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
tools:ignore="ScopedStorage"
|
||||
android:maxSdkVersion="32" />
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<application
|
||||
|
|
@ -44,6 +36,8 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".WebViewActivity" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="com.kbs.kbsintranett.fileprovider"
|
||||
|
|
|
|||
107
app/src/main/java/com/kbs/kbsintranett/HandbookAdapter.java
Normal file
107
app/src/main/java/com/kbs/kbsintranett/HandbookAdapter.java
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
// FILSTI: app\src\main\java\com\kbs\kbsintranett\HandbookAdapter.java
|
||||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class HandbookAdapter extends RecyclerView.Adapter<HandbookAdapter.ViewHolder> {
|
||||
|
||||
private List<HandbookItem> fullList;
|
||||
private List<HandbookItem> filteredList;
|
||||
private OnItemClickListener listener;
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(HandbookItem item);
|
||||
}
|
||||
|
||||
public HandbookAdapter(List<HandbookItem> items, OnItemClickListener listener) {
|
||||
this.fullList = items;
|
||||
this.filteredList = new ArrayList<>(items);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_handbook, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
HandbookItem item = filteredList.get(position);
|
||||
holder.title.setText(item.getTitle());
|
||||
|
||||
// Håndter ingress: Kutt etter 80 tegn hvis den er veldig lang
|
||||
String desc = item.getDescription();
|
||||
if (desc == null) desc = "";
|
||||
if (desc.length() > 100) {
|
||||
desc = desc.substring(0, 100) + "...";
|
||||
}
|
||||
holder.desc.setText(desc);
|
||||
|
||||
// Mapp ikon-type til ressurs (Utvidet liste fra PHP v3.0)
|
||||
int iconRes = R.drawable.ic_handbook_general; // Fallback
|
||||
String type = item.getIconType() != null ? item.getIconType() : "";
|
||||
|
||||
switch (type) {
|
||||
case "car": iconRes = R.drawable.ic_handbook_car; break;
|
||||
case "health": iconRes = R.drawable.ic_handbook_health; break;
|
||||
case "people": iconRes = R.drawable.ic_handbook_people; break;
|
||||
case "warning": iconRes = R.drawable.ic_handbook_warning; break;
|
||||
case "doc": iconRes = R.drawable.ic_handbook_doc; break;
|
||||
case "card": iconRes = R.drawable.ic_handbook_doc; break; // Bruker doc inntil videre
|
||||
case "computer": iconRes = R.drawable.ic_handbook_general; break;
|
||||
case "calendar": iconRes = R.drawable.ic_handbook_general; break;
|
||||
case "money": iconRes = R.drawable.ic_handbook_doc; break;
|
||||
case "helmet": iconRes = R.drawable.ic_handbook_warning; break;
|
||||
case "trash": iconRes = R.drawable.ic_handbook_general; break;
|
||||
case "book": iconRes = R.drawable.ic_book; break; // Gjenbruk eksisterende ic_book
|
||||
case "chat": iconRes = R.drawable.ic_handbook_people; break;
|
||||
default: iconRes = R.drawable.ic_handbook_general; break;
|
||||
}
|
||||
holder.icon.setImageResource(iconRes);
|
||||
|
||||
holder.itemView.setOnClickListener(v -> listener.onItemClick(item));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return filteredList.size();
|
||||
}
|
||||
|
||||
public void filter(String query) {
|
||||
filteredList.clear();
|
||||
if (query.isEmpty()) {
|
||||
filteredList.addAll(fullList);
|
||||
} else {
|
||||
String q = query.toLowerCase();
|
||||
for (HandbookItem item : fullList) {
|
||||
if (item.getTitle().toLowerCase().contains(q) ||
|
||||
(item.getDescription() != null && item.getDescription().toLowerCase().contains(q))) {
|
||||
filteredList.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView title, desc;
|
||||
ImageView icon;
|
||||
|
||||
public ViewHolder(View view) {
|
||||
super(view);
|
||||
title = view.findViewById(R.id.title);
|
||||
desc = view.findViewById(R.id.desc);
|
||||
icon = view.findViewById(R.id.icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
// FILSTI: app\src\main\java\com\kbs\kbsintranett\HandbookDetailFragment.java
|
||||
package com.kbs.kbsintranett;
|
||||
|
||||
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.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.text.HtmlCompat; // Bedre HTML støtte
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class HandbookDetailFragment extends Fragment {
|
||||
|
||||
private int pageId;
|
||||
private String pageTitle; // Fallback tittel før lasting
|
||||
private TextView titleView;
|
||||
private TextView contentView;
|
||||
private ProgressBar progressBar;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_handbook_detail, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
// Hent argumenter fra navigasjon
|
||||
if (getArguments() != null) {
|
||||
pageId = getArguments().getInt("page_id");
|
||||
pageTitle = getArguments().getString("page_title");
|
||||
}
|
||||
|
||||
Toolbar toolbar = view.findViewById(R.id.detail_toolbar);
|
||||
toolbar.setTitle("Håndbok");
|
||||
toolbar.setNavigationOnClickListener(v -> Navigation.findNavController(view).navigateUp());
|
||||
|
||||
titleView = view.findViewById(R.id.detail_title);
|
||||
contentView = view.findViewById(R.id.detail_content);
|
||||
progressBar = view.findViewById(R.id.detail_loading);
|
||||
|
||||
titleView.setText(pageTitle); // Sett midlertidig tittel
|
||||
|
||||
fetchContent();
|
||||
}
|
||||
|
||||
private void fetchContent() {
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
RetrofitClient.getApiService().getHandbookPage(pageId).enqueue(new Callback<HandbookPage>() {
|
||||
@Override
|
||||
public void onResponse(Call<HandbookPage> call, Response<HandbookPage> response) {
|
||||
if (!isAdded()) return;
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
HandbookPage page = response.body();
|
||||
titleView.setText(page.title);
|
||||
|
||||
// RENDERING AV HTML
|
||||
// HtmlCompat.FROM_HTML_MODE_COMPACT håndterer grunnleggende tags (p, br, b, i, h1-h6, ul, li)
|
||||
// Det støtter dessverre ikke tabeller eller bilder optimalt rett i TextView.
|
||||
if (page.content != null) {
|
||||
contentView.setText(HtmlCompat.fromHtml(page.content, HtmlCompat.FROM_HTML_MODE_COMPACT));
|
||||
contentView.setMovementMethod(LinkMovementMethod.getInstance()); // Gjør linker klikkbare
|
||||
} else {
|
||||
contentView.setText("Ingen innhold funnet.");
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Kunne ikke laste innhold.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<HandbookPage> call, Throwable t) {
|
||||
if (!isAdded()) return;
|
||||
progressBar.setVisibility(View.GONE);
|
||||
Toast.makeText(getContext(), "Nettverksfeil", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,91 @@
|
|||
// FILSTI: app\src\main\java\com\kbs\kbsintranett\HandbookFragment.java
|
||||
package com.kbs.kbsintranett;
|
||||
|
||||
import androidx.fragment.app.Fragment; // Viktig import!
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation; // Viktig
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.util.List;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class HandbookFragment extends Fragment {
|
||||
// Tomt innhold er OK, men klassen må hete det samme som filnavnet
|
||||
// og den må arve fra (extends) Fragment.
|
||||
|
||||
public HandbookFragment() {
|
||||
super(R.layout.fragment_home); // Kobler til layouten automatisk
|
||||
private RecyclerView recyclerView;
|
||||
private ProgressBar progressBar;
|
||||
private EditText searchField;
|
||||
private HandbookAdapter adapter;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_handbook, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
recyclerView = view.findViewById(R.id.recycler_handbook);
|
||||
progressBar = view.findViewById(R.id.progressBar);
|
||||
searchField = view.findViewById(R.id.search_field);
|
||||
|
||||
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
||||
|
||||
searchField.addTextChangedListener(new TextWatcher() {
|
||||
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
||||
@Override public void afterTextChanged(Editable s) {
|
||||
if (adapter != null) adapter.filter(s.toString());
|
||||
}
|
||||
});
|
||||
|
||||
fetchHandbook();
|
||||
}
|
||||
|
||||
private void fetchHandbook() {
|
||||
RetrofitClient.getApiService().getHandbookItems().enqueue(new Callback<List<HandbookItem>>() {
|
||||
@Override
|
||||
public void onResponse(Call<List<HandbookItem>> call, Response<List<HandbookItem>> response) {
|
||||
if (!isAdded()) return;
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
adapter = new HandbookAdapter(response.body(), item -> {
|
||||
// NYTT: Naviger til Native Detail Fragment
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("page_id", item.getId());
|
||||
bundle.putString("page_title", item.getTitle());
|
||||
|
||||
Navigation.findNavController(getView())
|
||||
.navigate(R.id.action_handbook_to_detail, bundle);
|
||||
});
|
||||
recyclerView.setAdapter(adapter);
|
||||
} else {
|
||||
String msg = "Kunne ikke laste håndboken. Kode: " + response.code();
|
||||
if (response.code() == 404) msg += "\n(Fant ikke foreldresiden 'interninstruks-hms')";
|
||||
Toast.makeText(getContext(), msg, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<List<HandbookItem>> call, Throwable t) {
|
||||
if (!isAdded()) return;
|
||||
progressBar.setVisibility(View.GONE);
|
||||
Toast.makeText(getContext(), "Nettverksfeil", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
28
app/src/main/java/com/kbs/kbsintranett/HandbookItem.java
Normal file
28
app/src/main/java/com/kbs/kbsintranett/HandbookItem.java
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// FILSTI: app\src\main\java\com\kbs\kbsintranett\HandbookItem.java
|
||||
package com.kbs.kbsintranett;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class HandbookItem implements Serializable {
|
||||
@SerializedName("id")
|
||||
private int id; // NYTT
|
||||
|
||||
@SerializedName("title")
|
||||
private String title;
|
||||
|
||||
@SerializedName("desc")
|
||||
private String description;
|
||||
|
||||
@SerializedName("icon_type")
|
||||
private String iconType;
|
||||
|
||||
@SerializedName("url")
|
||||
private String url;
|
||||
|
||||
public int getId() { return id; }
|
||||
public String getTitle() { return title; }
|
||||
public String getDescription() { return description; }
|
||||
public String getIconType() { return iconType; }
|
||||
public String getUrl() { return url; }
|
||||
}
|
||||
15
app/src/main/java/com/kbs/kbsintranett/HandbookPage.java
Normal file
15
app/src/main/java/com/kbs/kbsintranett/HandbookPage.java
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// FILSTI: app\src\main\java\com\kbs\kbsintranett\HandbookPage.java
|
||||
package com.kbs.kbsintranett;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class HandbookPage {
|
||||
@SerializedName("id")
|
||||
public int id;
|
||||
|
||||
@SerializedName("title")
|
||||
public String title;
|
||||
|
||||
@SerializedName("content")
|
||||
public String content; // Dette er HTML-strengen
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
// FILSTI: app\src\main\java\com\kbs\kbsintranett\InternalLinkMovementMethod.java
|
||||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle; // <-- Sjekk at denne er med!
|
||||
import android.text.Spannable;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.URLSpan;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class InternalLinkMovementMethod extends LinkMovementMethod {
|
||||
private static InternalLinkMovementMethod instance;
|
||||
private static final String TAG = "InternalLinkMethod";
|
||||
|
||||
public static InternalLinkMovementMethod getInstance() {
|
||||
if (instance == null) instance = new InternalLinkMovementMethod();
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
|
||||
int action = event.getAction();
|
||||
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
int x = (int) event.getX();
|
||||
int y = (int) event.getY();
|
||||
|
||||
x -= widget.getTotalPaddingLeft();
|
||||
y -= widget.getTotalPaddingTop();
|
||||
|
||||
x += widget.getScrollX();
|
||||
y += widget.getScrollY();
|
||||
|
||||
int line = widget.getLayout().getLineForVertical(y);
|
||||
int off = widget.getLayout().getOffsetForHorizontal(line, x);
|
||||
|
||||
URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
|
||||
if (link.length != 0) {
|
||||
String url = link[0].getURL();
|
||||
handleLink(widget.getContext(), url, widget);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(widget, buffer, event);
|
||||
}
|
||||
|
||||
private void handleLink(Context context, String url, View view) {
|
||||
Log.d(TAG, "Link clicked: " + url);
|
||||
|
||||
// 1. Sjekk om det er en intern lenke
|
||||
if (url.contains("intranet.kbs.no") || url.startsWith("/")) {
|
||||
|
||||
// a) Prøv å finne ID hvis den finnes i URLen (?p=123)
|
||||
int pageId = extractIdFromUrl(url);
|
||||
|
||||
if (pageId > 0) {
|
||||
navigateToInternalPage(view, pageId, "Laster...");
|
||||
} else {
|
||||
// b) Det er en "pen" URL. Vi må spørre APIet hva IDen er.
|
||||
// Vi bruker Toast for å gi feedback om at noe skjer
|
||||
Toast.makeText(context, "Åpner side...", Toast.LENGTH_SHORT).show();
|
||||
|
||||
RetrofitClient.getApiService().lookupPageId(url).enqueue(new Callback<JsonObject>() {
|
||||
@Override
|
||||
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
int id = response.body().get("id").getAsInt();
|
||||
if (id > 0) {
|
||||
// Suksess! Naviger internt
|
||||
navigateToInternalPage(view, id, "Laster...");
|
||||
} else {
|
||||
// Fant ikke ID, åpne i WebView som fallback
|
||||
openInWebView(context, url);
|
||||
}
|
||||
} else {
|
||||
openInWebView(context, url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<JsonObject> call, Throwable t) {
|
||||
openInWebView(context, url);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Ekstern lenke - åpne i nettleser
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
context.startActivity(browserIntent);
|
||||
}
|
||||
}
|
||||
|
||||
private int extractIdFromUrl(String url) {
|
||||
Pattern p = Pattern.compile("[?&](p|page_id|post)=([0-9]+)");
|
||||
Matcher m = p.matcher(url);
|
||||
if (m.find()) {
|
||||
try {
|
||||
return Integer.parseInt(m.group(2));
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void navigateToInternalPage(View view, int pageId, String title) {
|
||||
try {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("page_id", pageId);
|
||||
bundle.putString("page_title", title);
|
||||
Navigation.findNavController(view).navigate(R.id.action_handbook_to_detail, bundle);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Kunne ikke navigere", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void openInWebView(Context context, String url) {
|
||||
Intent intent = new Intent(context, WebViewActivity.class);
|
||||
intent.putExtra(WebViewActivity.EXTRA_URL, url);
|
||||
intent.putExtra(WebViewActivity.EXTRA_TITLE, "KBS Intranett");
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
54
app/src/main/java/com/kbs/kbsintranett/WebViewActivity.java
Normal file
54
app/src/main/java/com/kbs/kbsintranett/WebViewActivity.java
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.webkit.CookieManager;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
public class WebViewActivity extends AppCompatActivity {
|
||||
|
||||
public static final String EXTRA_URL = "extra_url";
|
||||
public static final String EXTRA_TITLE = "extra_title";
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_webview);
|
||||
|
||||
String url = getIntent().getStringExtra(EXTRA_URL);
|
||||
String title = getIntent().getStringExtra(EXTRA_TITLE);
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
toolbar.setTitle(title != null ? title : "Håndbok");
|
||||
toolbar.setNavigationIcon(android.R.drawable.ic_menu_revert);
|
||||
toolbar.setNavigationOnClickListener(v -> finish());
|
||||
|
||||
WebView webView = findViewById(R.id.webview);
|
||||
WebSettings settings = webView.getSettings();
|
||||
settings.setJavaScriptEnabled(true);
|
||||
settings.setDomStorageEnabled(true);
|
||||
settings.setBuiltInZoomControls(true);
|
||||
settings.setDisplayZoomControls(false);
|
||||
|
||||
// --- MAGIEN SKJER HER: INJISER COOKIE ---
|
||||
String cookie = UserManager.getInstance().getCookie();
|
||||
if (cookie != null && !cookie.isEmpty()) {
|
||||
CookieManager cookieManager = CookieManager.getInstance();
|
||||
cookieManager.setAcceptCookie(true);
|
||||
// Vi antar at domenet er intranet.kbs.no basert på APIet
|
||||
cookieManager.setCookie("https://intranet.kbs.no", cookie);
|
||||
}
|
||||
// ----------------------------------------
|
||||
|
||||
webView.setWebViewClient(new WebViewClient()); // Åpne linker i samme WebView
|
||||
|
||||
if (url != null) {
|
||||
webView.loadUrl(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// FILSTI: app\src\main\java\com\kbs\kbsintranett\WordPressApiService.java
|
||||
package com.kbs.kbsintranett;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject; // NY IMPORT
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import okhttp3.MultipartBody;
|
||||
|
|
@ -17,27 +17,21 @@ import retrofit2.http.PartMap;
|
|||
import retrofit2.http.Query;
|
||||
|
||||
public interface WordPressApiService {
|
||||
// 1. Hent nyheter
|
||||
@GET("wp-json/wp/v2/posts?per_page=10&_embed")
|
||||
Call<List<WpPost>> getPosts();
|
||||
|
||||
// 2. Hent et spesifikt skjema med ID (Oppdatert til custom endpoint for tilgang)
|
||||
@GET("wp-json/kbs/v1/forms/{id}")
|
||||
Call<GravityForm> getForm(@Path("id") int formId);
|
||||
|
||||
// 3. SEND INN SKJEMA (JSON-data uten filer)
|
||||
@POST("wp-json/gf/v2/forms/{id}/submissions")
|
||||
Call<JsonElement> submitForm(@Path("id") int formId, @Body FormSubmission submission);
|
||||
|
||||
// 4. LOGIN MED GOOGLE
|
||||
@POST("wp-json/kbs/v1/login")
|
||||
Call<LoginResponse> googleLogin(@Body LoginRequest request);
|
||||
|
||||
// 5. HENT LISTE AV SKJEMAER (Oppdatert til custom endpoint og List)
|
||||
@GET("wp-json/kbs/v1/forms")
|
||||
Call<List<GravityForm>> getFormsList();
|
||||
|
||||
// 6. SEND INN SKJEMA (MULTIPART - for filopplasting)
|
||||
@Multipart
|
||||
@POST("wp-json/gf/v2/forms/{id}/submissions")
|
||||
Call<JsonElement> submitMultipartForm(
|
||||
|
|
@ -46,11 +40,9 @@ public interface WordPressApiService {
|
|||
@Part List<MultipartBody.Part> files
|
||||
);
|
||||
|
||||
// 7. HENT KALENDERHENDELSER
|
||||
@GET("wp-json/kbs/v1/calendar/events")
|
||||
Call<List<CalendarEvent>> getCalendarEvents();
|
||||
|
||||
// 8. HENT INNSENDINGER (Entries) - LISTE
|
||||
@GET("wp-json/gf/v2/entries")
|
||||
Call<GravityEntryResponse> getEntries(
|
||||
@Query("form_ids") int formId,
|
||||
|
|
@ -58,11 +50,19 @@ public interface WordPressApiService {
|
|||
@Query("paging[page_size]") int pageSize
|
||||
);
|
||||
|
||||
// 9. HENT ÉN ENKELT INNSENDING
|
||||
@GET("wp-json/gf/v2/entries/{entry_id}")
|
||||
Call<JsonElement> getSingleEntry(@Path("entry_id") String entryId);
|
||||
|
||||
// 10. HENT ALLE NYHETER (F.eks 50 stk) - Brukes av "Se alle" siden
|
||||
@GET("wp-json/wp/v2/posts?per_page=50&_embed")
|
||||
Call<List<WpPost>> getAllPosts();
|
||||
|
||||
@GET("wp-json/kbs/v1/handbook")
|
||||
Call<List<HandbookItem>> getHandbookItems();
|
||||
|
||||
@GET("wp-json/kbs/v1/handbook/{id}")
|
||||
Call<HandbookPage> getHandbookPage(@Path("id") int id);
|
||||
|
||||
// NY: Slå opp ID fra URL
|
||||
@GET("wp-json/kbs/v1/lookup-id")
|
||||
Call<JsonObject> lookupPageId(@Query("url") String url);
|
||||
}
|
||||
8
app/src/main/res/drawable/ic_handbook_car.xml
Normal file
8
app/src/main/res/drawable/ic_handbook_car.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#0069B3">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M18.92,6.01C18.72,5.42 18.16,5 17.5,5h-11c-0.66,0 -1.21,0.42 -1.42,1.01L3,12v8c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1h12v1c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-8l-2.08,-5.99zM6.5,16c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,13 6.5,13s1.5,0.67 1.5,1.5S7.33,16 6.5,16zM17.5,16c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM5,11l1.5,-4.5h11L19,11H5z"/>
|
||||
</vector>
|
||||
8
app/src/main/res/drawable/ic_handbook_doc.xml
Normal file
8
app/src/main/res/drawable/ic_handbook_doc.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#0069B3">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M14,2H6c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2H18c1.1,0 2,-0.9 2,-2V8l-6,-6zm2,16H8v-2h8v2zm0,-4H8v-2h8v2zm-3,-5V3.5L18.5,9H13z"/>
|
||||
</vector>
|
||||
8
app/src/main/res/drawable/ic_handbook_general.xml
Normal file
8
app/src/main/res/drawable/ic_handbook_general.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#0069B3">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2V7h-2v2z"/>
|
||||
</vector>
|
||||
8
app/src/main/res/drawable/ic_handbook_health.xml
Normal file
8
app/src/main/res/drawable/ic_handbook_health.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#0069B3">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M19,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5C21,3.9 20.1,3 19,3zM17,13h-4v4h-2v-4H7v-2h4V7h2v4h4V13z"/>
|
||||
</vector>
|
||||
8
app/src/main/res/drawable/ic_handbook_people.xml
Normal file
8
app/src/main/res/drawable/ic_handbook_people.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#0069B3">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M16,11c1.66,0 2.99,-1.34 2.99,-3S17.66,5 16,5c-1.66,0 -3,1.34 -3,3s1.34,3 3,3zm-8,0c1.66,0 2.99,-1.34 2.99,-3S9.66,5 8,5C6.34,5 5,6.34 5,8s1.34,3 3,3zm0,2c-2.33,0 -7,1.17 -7,3.5V19h14v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5zm8,0c-0.29,0 -0.62,0.02 -0.97,0.05 1.16,0.84 1.97,1.97 1.97,3.45V19h6v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5z"/>
|
||||
</vector>
|
||||
8
app/src/main/res/drawable/ic_handbook_warning.xml
Normal file
8
app/src/main/res/drawable/ic_handbook_warning.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="#0069B3">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M1,21h22L12,2 1,21zm12,-3h-2v-2h2v2zm0,-4h-2v-4h2v4z"/>
|
||||
</vector>
|
||||
19
app/src/main/res/layout/activity_webview.xml
Normal file
19
app/src/main/res/layout/activity_webview.xml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/white"
|
||||
android:elevation="4dp"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Light" />
|
||||
|
||||
<WebView
|
||||
android:id="@+id/webview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</LinearLayout>
|
||||
|
|
@ -1,11 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<TextView
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="#F5F5F5">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:background="@color/white"
|
||||
android:elevation="4dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Håndbok"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#333333"
|
||||
android:layout_marginBottom="12dp"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/search_field"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:background="@drawable/bg_category_unselected"
|
||||
android:hint="Søk i håndboken..."
|
||||
android:paddingHorizontal="16dp"
|
||||
android:drawableStart="@android:drawable/ic_menu_search"
|
||||
android:drawablePadding="8dp"
|
||||
android:textColor="#333"
|
||||
android:textSize="14sp"
|
||||
android:inputType="text"/>
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Håndbok"
|
||||
android:layout_gravity="center"
|
||||
android:textSize="24sp"/>
|
||||
</FrameLayout>
|
||||
android:layout_marginTop="32dp"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_handbook"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="8dp"
|
||||
android:clipToPadding="false"/>
|
||||
|
||||
</LinearLayout>
|
||||
56
app/src/main/res/layout/fragment_handbook_detail.xml
Normal file
56
app/src/main/res/layout/fragment_handbook_detail.xml
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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:background="@color/white">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/detail_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/kbs_very_light_blue"
|
||||
android:elevation="4dp"
|
||||
app:navigationIcon="@android:drawable/ic_menu_revert"
|
||||
app:titleTextColor="@color/black" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/detail_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Tittel"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/kbs_logo_blue"
|
||||
android:layout_marginBottom="24dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/detail_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:linksClickable="true" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/detail_loading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="32dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
||||
49
app/src/main/res/layout/item_handbook.xml
Normal file
49
app/src/main/res/layout/item_handbook.xml
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView 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="wrap_content"
|
||||
android:layout_margin="6dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="2dp"
|
||||
app:cardBackgroundColor="@color/white">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:gravity="center_horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@drawable/ic_handbook_general"
|
||||
app:tint="@color/kbs_logo_blue"
|
||||
android:layout_marginBottom="12dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Tittel"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="4dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/desc"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Beskrivelse..."
|
||||
android:textColor="#666666"
|
||||
android:textSize="12sp"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"/>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
|
@ -22,15 +22,12 @@
|
|||
android:name="com.kbs.kbsintranett.HomeFragment"
|
||||
android:label="Hjem"
|
||||
tools:layout="@layout/fragment_home">
|
||||
|
||||
<action
|
||||
android:id="@+id/action_home_to_calendarFull"
|
||||
app:destination="@id/navigation_calendar_full" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_home_to_newsFull"
|
||||
app:destination="@id/navigation_news_full" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_home_to_newsDetail"
|
||||
app:destination="@id/navigation_news_detail" />
|
||||
|
|
@ -62,9 +59,10 @@
|
|||
android:id="@+id/navigation_forms"
|
||||
android:name="com.kbs.kbsintranett.FormsListFragment"
|
||||
android:label="Skjemaer"
|
||||
tools:layout="@layout/fragment_forms_list"> <action
|
||||
android:id="@+id/action_formsListFragment_to_formsDetailFragment"
|
||||
app:destination="@id/navigation_forms_detail" />
|
||||
tools:layout="@layout/fragment_forms_list">
|
||||
<action
|
||||
android:id="@+id/action_formsListFragment_to_formsDetailFragment"
|
||||
app:destination="@id/navigation_forms_detail" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
|
@ -82,7 +80,28 @@
|
|||
android:id="@+id/navigation_handbook"
|
||||
android:name="com.kbs.kbsintranett.HandbookFragment"
|
||||
android:label="Håndbok"
|
||||
tools:layout="@layout/fragment_handbook" />
|
||||
tools:layout="@layout/fragment_handbook">
|
||||
<action
|
||||
android:id="@+id/action_handbook_to_detail"
|
||||
app:destination="@id/navigation_handbook_detail" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/navigation_handbook_detail"
|
||||
android:name="com.kbs.kbsintranett.HandbookDetailFragment"
|
||||
android:label="Håndbok Detaljer"
|
||||
tools:layout="@layout/fragment_handbook_detail">
|
||||
<argument
|
||||
android:name="page_id"
|
||||
app:argType="integer" />
|
||||
<argument
|
||||
android:name="page_title"
|
||||
app:argType="string" />
|
||||
|
||||
<action
|
||||
android:id="@+id/action_handbook_to_detail"
|
||||
app:destination="@id/navigation_handbook_detail" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/navigation_profile"
|
||||
|
|
|
|||
Loading…
Reference in a new issue