mirror of
https://github.com/etesync/android
synced 2024-12-23 07:08:16 +00:00
Journal item: implement showing calendar events (based on etar)
This shows the calendar events in a nicer way based on Etar[1] which is in turn based on the AOSP calendar. 1: https://github.com/Etar-Group/Etar-Calendar/
This commit is contained in:
parent
7dba220d06
commit
b964b8dfe1
@ -2,12 +2,16 @@ package com.etesync.syncadapter.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Time;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -20,6 +24,19 @@ import com.etesync.syncadapter.model.CollectionInfo;
|
||||
import com.etesync.syncadapter.model.JournalEntity;
|
||||
import com.etesync.syncadapter.model.SyncEntry;
|
||||
|
||||
import net.fortuna.ical4j.model.component.VAlarm;
|
||||
import net.fortuna.ical4j.model.property.Attendee;
|
||||
|
||||
import org.apache.commons.codec.Charsets;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
|
||||
import at.bitfire.ical4android.Event;
|
||||
import at.bitfire.ical4android.InvalidCalendarException;
|
||||
import io.requery.Persistable;
|
||||
import io.requery.sql.EntityDataStore;
|
||||
|
||||
@ -102,7 +119,11 @@ public class JournalItemActivity extends BaseActivity implements Refreshable {
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
return TextFragment.newInstance(syncEntry);
|
||||
if (position == 0) {
|
||||
return EventFragment.newInstance(info, syncEntry);
|
||||
} else {
|
||||
return TextFragment.newInstance(syncEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,6 +149,140 @@ public class JournalItemActivity extends BaseActivity implements Refreshable {
|
||||
}
|
||||
}
|
||||
|
||||
public static class EventFragment extends Fragment {
|
||||
CollectionInfo info;
|
||||
SyncEntry syncEntry;
|
||||
|
||||
public static EventFragment newInstance(CollectionInfo info, SyncEntry syncEntry) {
|
||||
EventFragment frag = new EventFragment();
|
||||
Bundle args = new Bundle(1);
|
||||
args.putSerializable(Constants.KEY_COLLECTION_INFO, info);
|
||||
args.putSerializable(KEY_SYNC_ENTRY, syncEntry);
|
||||
frag.setArguments(args);
|
||||
return frag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.event_info, container, false);
|
||||
|
||||
info = (CollectionInfo) getArguments().getSerializable(Constants.KEY_COLLECTION_INFO);
|
||||
syncEntry = (SyncEntry) getArguments().getSerializable(KEY_SYNC_ENTRY);
|
||||
|
||||
new LoadEventTask(v).execute();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
private class LoadEventTask extends AsyncTask<Void, Void, Event> {
|
||||
View view;
|
||||
LoadEventTask(View v) {
|
||||
super();
|
||||
view = v;
|
||||
}
|
||||
@Override
|
||||
protected Event doInBackground(Void... aVoids) {
|
||||
InputStream is = new ByteArrayInputStream(syncEntry.getContent().getBytes(Charsets.UTF_8));
|
||||
|
||||
try {
|
||||
Event event = Event.fromStream(is, Charsets.UTF_8, null)[0];
|
||||
return event;
|
||||
} catch (InvalidCalendarException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Event event) {
|
||||
final View loader = view.findViewById(R.id.event_info_loading_msg);
|
||||
loader.setVisibility(View.GONE);
|
||||
final View contentContainer = view.findViewById(R.id.event_info_scroll_view);
|
||||
contentContainer.setVisibility(View.VISIBLE);
|
||||
|
||||
setTextViewText(view, R.id.title, event.summary);
|
||||
|
||||
setTextViewText(view, R.id.when_datetime, getDisplayedDatetime(event.dtStart.getDate().getTime(), event.dtEnd.getDate().getTime(), event.isAllDay(), getContext()));
|
||||
|
||||
setTextViewText(view, R.id.where, event.location);
|
||||
|
||||
if (event.organizer != null) {
|
||||
TextView tv = (TextView) view.findViewById(R.id.organizer);
|
||||
tv.setText(event.organizer.getCalAddress().toString().replaceFirst("mailto:", ""));
|
||||
} else {
|
||||
View organizer = view.findViewById(R.id.organizer_container);
|
||||
organizer.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
setTextViewText(view, R.id.description, event.description);
|
||||
|
||||
boolean first = true;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Attendee attendee : event.attendees) {
|
||||
if (first) {
|
||||
first = false;
|
||||
sb.append("Attendees: ");
|
||||
} else {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(attendee.getCalAddress().toString().replaceFirst("mailto:", ""));
|
||||
}
|
||||
setTextViewText(view, R.id.attendees, sb.toString());
|
||||
|
||||
first = true;
|
||||
sb = new StringBuilder();
|
||||
for (VAlarm alarm : event.alarms) {
|
||||
if (first) {
|
||||
first = false;
|
||||
sb.append("Reminders: ");
|
||||
} else {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(alarm.getTrigger().getValue());
|
||||
}
|
||||
setTextViewText(view, R.id.reminders, sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static void setTextViewText(View parent, int id, String text) {
|
||||
TextView tv = (TextView) parent.findViewById(id);
|
||||
if (text == null) {
|
||||
tv.setVisibility(View.GONE);
|
||||
} else {
|
||||
tv.setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDisplayedDatetime(long startMillis, long endMillis, boolean allDay, Context context) {
|
||||
// Configure date/time formatting.
|
||||
int flagsDate = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
|
||||
int flagsTime = DateUtils.FORMAT_SHOW_TIME;
|
||||
if (DateFormat.is24HourFormat(context)) {
|
||||
flagsTime |= DateUtils.FORMAT_24HOUR;
|
||||
}
|
||||
|
||||
String datetimeString = null;
|
||||
if (allDay) {
|
||||
// For multi-day allday events or single-day all-day events that are not
|
||||
// today or tomorrow, use framework formatter.
|
||||
Formatter f = new Formatter(new StringBuilder(50), Locale.getDefault());
|
||||
datetimeString = DateUtils.formatDateRange(context, f, startMillis,
|
||||
endMillis, flagsDate, Time.TIMEZONE_UTC).toString();
|
||||
} else {
|
||||
// For multiday events, shorten day/month names.
|
||||
// Example format: "Fri Apr 6, 5:00pm - Sun, Apr 8, 6:00pm"
|
||||
int flagsDatetime = flagsDate | flagsTime | DateUtils.FORMAT_ABBREV_MONTH |
|
||||
DateUtils.FORMAT_ABBREV_WEEKDAY;
|
||||
datetimeString = DateUtils.formatDateRange(context, startMillis, endMillis,
|
||||
flagsDatetime);
|
||||
}
|
||||
return datetimeString;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
116
app/src/main/res/layout/event_info.xml
Normal file
116
app/src/main/res/layout/event_info.xml
Normal file
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2006 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:background="#fafafa"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="0dp">
|
||||
<RelativeLayout
|
||||
android:id="@+id/event_info_loading_msg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<ProgressBar
|
||||
android:id="@+id/event_info_progress_bar"
|
||||
android:layout_width="100dip"
|
||||
android:layout_height="100dip"
|
||||
android:indeterminate="true"
|
||||
android:layout_centerInParent="true" />
|
||||
<TextView
|
||||
android:layout_below="@id/event_info_progress_bar"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="16dip"
|
||||
android:text="@string/loading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</RelativeLayout>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/event_info_scroll_view"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:fadingEdge="none"
|
||||
android:animateLayoutChanges="true"
|
||||
android:visibility="gone"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Container for the event's headline
|
||||
Name, Date, Time & Location
|
||||
-->
|
||||
<include layout="@layout/event_info_headline" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingRight="16dip"
|
||||
android:layout_marginTop="8dip"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Organizer -->
|
||||
<LinearLayout
|
||||
android:id="@+id/organizer_container"
|
||||
android:visibility="gone"
|
||||
android:paddingRight="16dip"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:id="@+id/organizer_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/event_info_organizer"
|
||||
style="?android:attr/textAppearanceSmall"
|
||||
android:textSize="14sp"/>
|
||||
<TextView
|
||||
android:id="@+id/organizer"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:layout_weight="1"
|
||||
android:singleLine="true"
|
||||
android:layout_marginLeft="2dip"
|
||||
android:textIsSelectable="true"
|
||||
style="?android:attr/textAppearanceSmall"
|
||||
android:textSize="14sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- DESCRIPTION -->
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/attendees"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reminders"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</FrameLayout>
|
82
app/src/main/res/layout/event_info_headline.xml
Normal file
82
app/src/main/res/layout/event_info_headline.xml
Normal file
@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright (C) 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/event_info_headline"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="@color/orange400"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="16dip"
|
||||
android:paddingLeft="16dip"
|
||||
android:paddingRight="16dip"
|
||||
android:paddingTop="8dip">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!-- WHAT -->
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
style="?android:attr/textAppearanceLarge"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight=".8"
|
||||
android:autoLink="all"
|
||||
android:textColor="@color/White"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- WHEN -->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/when_datetime"
|
||||
style="?android:attr/textAppearanceLarge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dip"
|
||||
android:textColor="@color/White"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/when_repeat"
|
||||
style="?android:attr/textAppearanceLarge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-3dip"
|
||||
android:textColor="@color/White"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<!-- WHERE -->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/where"
|
||||
style="?android:attr/textAppearanceLarge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dip"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="false"
|
||||
android:textColor="@color/White"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:background="#fafafa"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
@ -25,7 +25,6 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/add_member"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/activity_margin"
|
||||
|
@ -13,5 +13,4 @@
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
|
||||
<dimen name="nav_header_vertical_spacing">16dp</dimen>
|
||||
|
||||
</resources>
|
@ -7,7 +7,7 @@
|
||||
~ http://www.gnu.org/licenses/gpl.html
|
||||
-->
|
||||
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<!-- common strings -->
|
||||
<string name="app_name">EteSync</string>
|
||||
@ -249,7 +249,6 @@
|
||||
<string name="delete_collection_confirm_title">Are you sure?</string>
|
||||
<string name="delete_collection_confirm_warning">This collection (%s) and all its data will be removed from the server.</string>
|
||||
<string name="delete_collection_deleting_collection">Deleting collection</string>
|
||||
<string name="collection_stats_title">Stats</string>
|
||||
|
||||
<!-- JournalViewer -->
|
||||
<string name="journal_entries_list_empty">No entries found for this journal</string>
|
||||
@ -300,4 +299,6 @@
|
||||
<string name="import_button_local">From Account</string>
|
||||
<string name="import_select_account">Select Account</string>
|
||||
|
||||
<!-- Event (from Etar) -->
|
||||
<string name="event_info_organizer">Organizer:</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user