Skip to content

Commit

Permalink
Show calendar event title of active shift in overview (#324)
Browse files Browse the repository at this point in the history
  • Loading branch information
frimtec authored May 30, 2022
1 parent 25ec111 commit 40e0886
Show file tree
Hide file tree
Showing 18 changed files with 150 additions and 65 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.github.frimtec.android.pikettassist.domain;

import static com.github.frimtec.android.pikettassist.domain.OnOffState.ON;

import java.util.Optional;

public class ShiftState {

private final OnOffState state;
private final Shift shift;

public ShiftState(Shift shift) {
this.state = ON;
this.shift = shift;
}

public ShiftState(OnOffState state) {
this.state = state;
this.shift = null;
}

public boolean isOn() {
return this.state == ON;
}

public OnOffState getState() {
return this.state;
}

public Optional<Shift> getShift() {
return Optional.ofNullable(this.shift);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ final class LowSignalServiceWorkUnit implements ServiceWorkUnit {
@Override
public Optional<ScheduleInfo> apply(Intent intent) {
int currentFilterState = intent.getIntExtra(EXTRA_FILTER_STATE, 0);
boolean pikettState = this.shiftService.getState() == OnOffState.ON;
boolean pikettState = this.shiftService.getShiftState().isOn();
SignalLevel level = this.signalStrengthService.getSignalStrength();
if (pikettState && this.applicationPreferences.getSuperviseSignalStrength(context) && !isInCall() && !isAlarmStateOn() && isLowSignal(level, this.applicationPreferences.getSuperviseSignalStrengthMinLevel(context))) {
int lowSignalFilter = this.applicationPreferences.getLowSignalFilterSeconds(context);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.github.frimtec.android.pikettassist.service;

import static com.github.frimtec.android.pikettassist.domain.OnOffState.OFF;
import static com.github.frimtec.android.pikettassist.domain.OnOffState.ON;

import android.content.Context;

import com.github.frimtec.android.pikettassist.domain.OnOffState;
import com.github.frimtec.android.pikettassist.domain.Shift;
import com.github.frimtec.android.pikettassist.domain.ShiftState;
import com.github.frimtec.android.pikettassist.service.dao.ShiftDao;
import com.github.frimtec.android.pikettassist.state.ApplicationPreferences;
import com.github.frimtec.android.pikettassist.state.ApplicationState;
Expand All @@ -22,29 +25,32 @@ public ShiftService(Context context) {
this.shiftDao = new ShiftDao(context);
}

public OnOffState getState() {
return ApplicationState.instance().getPikettStateManuallyOn() ||
hasShiftEventForNow(
ApplicationPreferences.instance().getCalendarEventPikettTitlePattern(this.context),
ApplicationPreferences.instance().getCalendarSelection(this.context),
ApplicationPreferences.instance().getPrePostRunTime(context)
) ? OnOffState.ON : OnOffState.OFF;
public ShiftState getShiftState() {
if (ApplicationState.instance().getPikettStateManuallyOn()) {
return new ShiftState(ON);
}
return hasShiftEventForNow(
ApplicationPreferences.instance().getCalendarEventPikettTitlePattern(this.context),
ApplicationPreferences.instance().getCalendarSelection(this.context),
ApplicationPreferences.instance().getPrePostRunTime(context)
).map(ShiftState::new).orElse(new ShiftState(OFF));
}

public Optional<Shift> findCurrentOrNextShift(Instant now) {
ApplicationPreferences preferences = ApplicationPreferences.instance();
return this.shiftDao.getShifts(
preferences.getCalendarEventPikettTitlePattern(this.context),
preferences.getCalendarSelection(this.context),
preferences.getPartnerExtractionEnabled(this.context) ? preferences.getPartnerSearchExtractPattern(this.context) : ""
).stream()
preferences.getCalendarEventPikettTitlePattern(this.context),
preferences.getCalendarSelection(this.context),
preferences.getPartnerExtractionEnabled(this.context) ? preferences.getPartnerSearchExtractPattern(this.context) : ""
).stream()
.filter(shift -> !shift.isOver(now, preferences.getPrePostRunTime(context)))
.findFirst();
}

private boolean hasShiftEventForNow(String eventTitleFilterPattern, String calendarSelection, Duration prePostRunTime) {
private Optional<Shift> hasShiftEventForNow(String eventTitleFilterPattern, String calendarSelection, Duration prePostRunTime) {
return this.shiftDao.getShifts(eventTitleFilterPattern, calendarSelection, null).stream()
.anyMatch(shift -> shift.isNow(prePostRunTime));
.filter(shift -> shift.isNow(prePostRunTime))
.findFirst();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void onReceive(Context context, Intent intent) {
receivedSms.stream()
.filter(sms -> SecureSmsProxyFacade.PHONE_NUMBER_LOOPBACK.equals(sms.getNumber()))
.forEach(sms -> Toast.makeText(context, context.getString(R.string.sms_listener_loopback_sms_received), Toast.LENGTH_SHORT).show());
if (shiftService.getState() == OnOffState.OFF) {
if (shiftService.getShiftState().getState() == OnOffState.OFF) {
Log.d(TAG, "Drop SMS, not on-call");
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public TestAlarmServiceWorkUnit(
@Override
public Optional<ScheduleInfo> apply(Intent intent) {
boolean initial = intent.getBooleanExtra(PARAM_INITIAL, true);
OnOffState shiftState = this.shiftService.getState();
OnOffState shiftState = this.shiftService.getShiftState().getState();
Log.i(TAG, "Service cycle; shift state: " + shiftState + "; initial: " + initial);
boolean testAlarmEnabled = this.applicationPreferences.getTestAlarmEnabled(context);
Set<Integer> testAlarmCheckWeekdays = this.applicationPreferences.getTestAlarmCheckWeekdays(context).stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ private void registerBroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction()) &&
new ShiftService(context).getState() == OnOffState.ON) {
new ShiftService(context).getShiftState().isOn()) {
LowSignalService.enqueueWork(context);
}
refresh();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public boolean onContextItemSelected(MenuItem item) {
@Override
protected Optional<View.OnClickListener> addAction() {
if (Feature.PERMISSION_CALENDAR_READ.isAllowed(getContext()) &&
new ShiftService(getContext()).getState() == OnOffState.ON) {
new ShiftService(getContext()).getShiftState().isOn()) {
return Optional.of(view -> {
AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
builder.setTitle(getString(R.string.manually_created_alarm_reason));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class AlarmState extends State {
stateContext.getString(R.string.state_fragment_alarm_state),
stateContext.getString(getAlertValue(stateContext.getAlarmState().first)),
getSupplierButtons(stateContext),
getAlertTrafficLight(stateContext.getAlarmState().first, stateContext.getPikettState())
getAlertTrafficLight(stateContext.getAlarmState().first, stateContext.getShiftState().getState())
);
this.stateContext = stateContext;
}
Expand Down Expand Up @@ -105,7 +105,7 @@ public void onClickAction(Context context) {

@Override
public void onCreateContextMenu(Context context, ContextMenu menu) {
if (stateContext.getPikettState() == OnOffState.ON) {
if (stateContext.getShiftState().isOn()) {
menu.add(Menu.NONE, MENU_CONTEXT_CREATE_ALARM_MANUALLY, Menu.NONE, R.string.menu_create_manually_alarm);
}
menu.add(Menu.NONE, MENU_CONTEXT_BOGUS_ALARM, Menu.NONE, R.string.list_item_menu_bogus_alarm);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ private static TrafficLight getBatteryLevelTrafficLight(StateContext stateContex
if (!ApplicationPreferences.instance().getSuperviseBatteryLevel(stateContext.getContext())) {
return YELLOW;
}
if (stateContext.getPikettState() == OnOffState.OFF) {
if (stateContext.getShiftState().getState() == OnOffState.OFF) {
return TrafficLight.OFF;
}
int level = stateContext.getBatteryStatus().getLevel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import android.view.MenuItem;

import com.github.frimtec.android.pikettassist.R;
import com.github.frimtec.android.pikettassist.domain.OnOffState;
import com.github.frimtec.android.pikettassist.service.LowSignalService;
import com.github.frimtec.android.pikettassist.service.PikettService;
import com.github.frimtec.android.pikettassist.state.ApplicationState;
Expand All @@ -28,9 +27,9 @@ class OnCallState extends State {
super(
R.drawable.ic_eye,
stateContext.getString(R.string.state_fragment_pikett_state),
String.format("%s %s", stateContext.getString(stateContext.getPikettState() == OnOffState.ON ? (stateContext.isPikettStateManuallyOn() ? R.string.state_manually_on : (R.string.state_on)) : R.string.state_off), stateContext.getPikettStateDuration()),
String.format("%s %s", stateContext.getString(stateContext.getShiftState().isOn() ? (stateContext.isPikettStateManuallyOn() ? R.string.state_manually_on : (R.string.state_on)) : R.string.state_off), stateContext.getPikettStateDuration()),
null,
stateContext.getPikettState() == OnOffState.ON ? (stateContext.isPikettStateManuallyOn() ? TrafficLight.YELLOW : TrafficLight.GREEN) : TrafficLight.OFF
stateContext.getShiftState().isOn() ? (stateContext.isPikettStateManuallyOn() ? TrafficLight.YELLOW : TrafficLight.GREEN) : TrafficLight.OFF
);
this.stateContext = stateContext;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class SignalStrengthState extends State {
super(
R.drawable.ic_signal_cellular_connected_no_internet_1_bar_black_24dp,
stateContext.getNetworkOperatorName() != null ? String.format("%s %s", stateContext.getString(R.string.state_fragment_signal_level), stateContext.getNetworkOperatorName()) : stateContext.getString(R.string.state_fragment_signal_level),
stateContext.isSuperviseSignalStrength() ? (stateContext.getPikettState() == OnOffState.ON ? getSignalStrength(stateContext) : stateContext.getString(R.string.general_enabled)) : stateContext.getString(R.string.general_disabled),
stateContext.isSuperviseSignalStrength() ? (stateContext.getShiftState().isOn() ? getSignalStrength(stateContext) : stateContext.getString(R.string.general_enabled)) : stateContext.getString(R.string.general_disabled),
null,
getSignalStrengthTrafficLight(stateContext)
);
Expand All @@ -46,7 +46,7 @@ private static String getSignalStrength(StateContext stateContext) {
private static TrafficLight getSignalStrengthTrafficLight(StateContext stateContext) {
if (!stateContext.isSuperviseSignalStrength()) {
return YELLOW;
} else if (stateContext.getPikettState() == OnOffState.OFF) {
} else if (stateContext.getShiftState().getState() == OnOffState.OFF) {
return OFF;
} else if (stateContext.getSignalStrengthLevel().ordinal() <= SignalLevel.NONE.ordinal()) {
return RED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import com.github.frimtec.android.pikettassist.domain.AlertState;
import com.github.frimtec.android.pikettassist.domain.BatteryStatus;
import com.github.frimtec.android.pikettassist.domain.Contact;
import com.github.frimtec.android.pikettassist.domain.OnOffState;
import com.github.frimtec.android.pikettassist.domain.ShiftState;
import com.github.frimtec.android.pikettassist.service.system.SignalStrengthService.SignalLevel;
import com.github.frimtec.android.securesmsproxyapi.SecureSmsProxyFacade.Installation;

Expand All @@ -30,7 +30,7 @@ class StateContext {
private final Runnable closeAlertAction;
private final Runnable showDonationDialogAction;

private final OnOffState pikettState;
private final ShiftState shiftState;
private final String pikettStateDuration;
private final Pair<AlertState, Long> alarmState;
private final boolean pikettStateManuallyOn;
Expand Down Expand Up @@ -62,7 +62,7 @@ class StateContext {
boolean smsAdapterMissing,
boolean smsAdapterVersionOutdated,
boolean smsAdapterPermissionsGranted,
OnOffState pikettState,
ShiftState shiftState,
String pikettStateDuration,
Pair<AlertState, Long> alarmState,
boolean pikettStateManuallyOn,
Expand All @@ -85,7 +85,7 @@ class StateContext {
this.smsAdapterMissing = smsAdapterMissing;
this.smsAdapterVersionOutdated = smsAdapterVersionOutdated;
this.smsAdapterPermissionsGranted = smsAdapterPermissionsGranted;
this.pikettState = pikettState;
this.shiftState = shiftState;
this.pikettStateDuration = pikettStateDuration;
this.alarmState = alarmState;
this.pikettStateManuallyOn = pikettStateManuallyOn;
Expand Down Expand Up @@ -147,8 +147,8 @@ boolean isSmsAdapterPermissionsGranted() {
return smsAdapterPermissionsGranted;
}

OnOffState getPikettState() {
return pikettState;
ShiftState getShiftState() {
return shiftState;
}

public String getPikettStateDuration() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.github.frimtec.android.pikettassist.domain.ContactPerson;
import com.github.frimtec.android.pikettassist.domain.OnOffState;
import com.github.frimtec.android.pikettassist.domain.Shift;
import com.github.frimtec.android.pikettassist.domain.ShiftState;
import com.github.frimtec.android.pikettassist.domain.TestAlarmContext;
import com.github.frimtec.android.pikettassist.donation.billing.BillingProvider.BillingState;
import com.github.frimtec.android.pikettassist.service.AlertService;
Expand Down Expand Up @@ -214,7 +215,7 @@ private void regularStates(List<State> states) {
ShiftService shiftService = new ShiftService(getContext());
BatteryService batteryService = new BatteryService(getContext());
boolean pikettStateManuallyOn = ApplicationState.instance().getPikettStateManuallyOn();
OnOffState pikettState = shiftService.getState();
ShiftState shiftState = shiftService.getShiftState();
Instant now = Shift.now();
Duration prePostRunTime = ApplicationPreferences.instance().getPrePostRunTime(getContext());
Optional<Shift> currentOrNextShift = shiftService.findCurrentOrNextShift(now);
Expand All @@ -231,8 +232,8 @@ private void regularStates(List<State> states) {
!smsAdapterInstallation.getAppVersion().isPresent(),
smsAdapterInstallation.getAppVersion().isPresent() && smsAdapterInstallation.getApiVersion().compareTo(smsAdapterInstallation.getAppVersion().get()) > 0,
s2msp.areSmsPermissionsGranted(),
pikettState,
currentOrNextShift.map(shift -> toDuration(pikettStateManuallyOn, pikettState, shift, now, prePostRunTime)).orElse(""),
shiftState,
currentOrNextShift.map(shift -> toDuration(pikettStateManuallyOn, shiftState, shift, now, prePostRunTime)).orElse(""),
this.alertDao.getAlertState(),
pikettStateManuallyOn,
!(operationsCenterPhoneNumbers.isEmpty() || s2msp.isAllowed(operationsCenterPhoneNumbers)),
Expand All @@ -244,12 +245,12 @@ private void regularStates(List<State> states) {
batteryService.batteryStatus()
);
states.add(new SmsAdapterState(stateContext));
if (pikettState == OnOffState.ON && new NotificationService(getContext()).isDoNotDisturbEnabled()) {
if (shiftState.isOn() && new NotificationService(getContext()).isDoNotDisturbEnabled()) {
states.add(new DoNotDisturbState(stateContext));
}
states.add(new OperationsCenterState(stateContext));
Optional<List<String>> partners = currentOrNextShift.map(Shift::getPartners);
if (pikettState == OnOffState.ON && partners.isPresent()) {
if (shiftState.isOn() && partners.isPresent()) {
List<String> pairAliases = (List<String>) partners.get();
Map<String, ContactPerson> contactPersonsByAliases = this.contactPersonService.findContactPersonsByAliases(new HashSet<>(pairAliases));
pairAliases.forEach(pair -> states.add(new PartnerState(stateContext, contactPersonsByAliases.getOrDefault(pair, new ContactPerson(pair)))));
Expand Down Expand Up @@ -281,9 +282,11 @@ private void regularStates(List<State> states) {
}
}

private String toDuration(boolean pikettStateManuallyOn, OnOffState pikettState, Shift currentOrNextShift, Instant now, Duration prePostRunTime) {
return pikettStateManuallyOn ? "" : String.format("(%s)",
toDurationString(Duration.between(now, pikettState == OnOffState.ON ? currentOrNextShift.getEndTime(prePostRunTime) : currentOrNextShift.getStartTime(prePostRunTime)), siFormatter()));
private String toDuration(boolean pikettStateManuallyOn, ShiftState shiftState, Shift currentOrNextShift, Instant now, Duration prePostRunTime) {
return pikettStateManuallyOn ? "" : String.format("(%s)%s",
toDurationString(Duration.between(now, shiftState.isOn() ? currentOrNextShift.getEndTime(prePostRunTime) : currentOrNextShift.getStartTime(prePostRunTime)), siFormatter()),
shiftState.getShift().map(shift -> "\n" + shift.getTitle()).orElse("")
);
}

private boolean randomizedOn() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class TestAlarmState extends State {
testAlarmStateContext.getTestAlarmContext().getContext(),
testAlarmStateContext.getLastReceived(),
getTestAlarmCloseButtonSupplier(testAlarmStateContext.getStateContext(), testAlarmStateContext.getTestAlarmContext(), testAlarmStateContext.getTestAlarmState()),
testAlarmStateContext.getStateContext().getPikettState() == OnOffState.ON ? (testAlarmStateContext.getTestAlarmState() == OnOffState.ON ? TrafficLight.RED : TrafficLight.GREEN) : TrafficLight.OFF);
testAlarmStateContext.getStateContext().getShiftState().isOn() ? (testAlarmStateContext.getTestAlarmState() == OnOffState.ON ? TrafficLight.RED : TrafficLight.GREEN) : TrafficLight.OFF);
this.testAlarmContext = testAlarmStateContext.getTestAlarmContext();
}

Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/layout/state_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center_horizontal"
android:textSize="15sp"
android:textStyle="bold" />

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.github.frimtec.android.pikettassist.domain;

import static com.github.frimtec.android.pikettassist.domain.OnOffState.OFF;
import static com.github.frimtec.android.pikettassist.domain.OnOffState.ON;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

import org.junit.jupiter.api.Test;

class ShiftStateTest {

@Test
public void createWithShift() {
Shift shift = mock(Shift.class);
ShiftState shiftState = new ShiftState(shift);

assertThat(shiftState.isOn()).isTrue();
assertThat(shiftState.getState()).isEqualTo(ON);
assertThat(shiftState.getShift()).isPresent();
assertThat(shiftState.getShift().get()).isSameAs(shift);
}

@Test
public void createWithStetOff() {
ShiftState shiftState = new ShiftState(OFF);

assertThat(shiftState.isOn()).isFalse();
assertThat(shiftState.getState()).isEqualTo(OFF);
assertThat(shiftState.getShift()).isNotPresent();
}

@Test
public void createWithStetOn() {
ShiftState shiftState = new ShiftState(ON);

assertThat(shiftState.isOn()).isTrue();
assertThat(shiftState.getState()).isEqualTo(ON);
assertThat(shiftState.getShift()).isNotPresent();
}

}
Loading

0 comments on commit 40e0886

Please sign in to comment.