Panagiotis Triantafyllou

magenta fixes and additions

......@@ -4,6 +4,14 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-02-13T08:44:19.612560Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=R58M42EM7YT" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
</selectionStates>
</component>
......
......@@ -55,6 +55,7 @@ dependencies {
api "androidx.security:security-crypto:1.1.0-alpha03"
// For minSDK 23 use 1.0.0, for minSDK 21 use 1.1.0 that is currently in alpha
api 'org.altbeacon:android-beacon-library:2.19.3'
api 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
api 'io.reactivex.rxjava3:rxjava:3.1.8'
api 'io.reactivex.rxjava3:rxandroid:3.0.2'
implementation 'com.google.android.material:material:1.5.0'
......
......@@ -51,7 +51,7 @@ public class BaseFragmentActivity extends FragmentActivity implements Navigation
mBottomNavigationView = findViewById(R.id.bt_tabs);
if (WarplyDBHelper.getInstance(this).isTableNotEmpty("auth")) {
WarplyManager.getCampaigns(mCampaignsCallback);
WarplyManager.getSupermarketCampaign(mCampaignsCallback);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
......
......@@ -176,7 +176,10 @@ public class WarpViewActivity extends WarpBaseActivity {
@Subscribe()
public void onMessageEvent(WarplyEventBusManager event) {
if (event.getQuestionnaire() != null) {
setResult(RESULT_OK, new Intent());
finish();
}
}
// ===========================================================
......
......@@ -23,6 +23,7 @@ import ly.warp.sdk.R;
import ly.warp.sdk.db.WarplyDBHelper;
import ly.warp.sdk.io.callbacks.CallbackReceiver;
import ly.warp.sdk.io.models.Campaign;
import ly.warp.sdk.utils.WarplyManagerHelper;
import ly.warp.sdk.utils.managers.WarplyManager;
public class HomeFragment extends Fragment implements View.OnClickListener, SwipeRefreshLayout.OnRefreshListener {
......@@ -31,7 +32,7 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip
private TextView mTvUsername, mTvUser;
private SwipeRefreshLayout mSwipeRefresh;
private EditText mEtGuid;
private LinearLayout mLlAuthLogin, mLlAuthLogout;
private LinearLayout mLlAuthLogin, mLlAuthLogout, mRlSmFlow, mRlSmMap;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
......@@ -72,6 +73,10 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip
mLlAuthLogout = view.findViewById(R.id.ll_auth_logout);
mLlAuthLogout.setOnClickListener(this);
mTvUser = view.findViewById(R.id.tv_login);
mRlSmFlow = view.findViewById(R.id.ll_sm_flow);
mRlSmFlow.setOnClickListener(this);
mRlSmMap = view.findViewById(R.id.ll_sm_map);
mRlSmMap.setOnClickListener(this);
if (!WarplyDBHelper.getInstance(getActivity()).isTableNotEmpty("auth")) {
mTvUser.setVisibility(View.GONE);
......@@ -94,7 +99,7 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip
@Override
public void onRefresh() {
if (WarplyDBHelper.getInstance(getActivity()).isTableNotEmpty("auth")) {
WarplyManager.getCampaigns(mCampaignsCallback);
WarplyManager.getSupermarketCampaign(mCampaignsCallback);
mSwipeRefresh.setRefreshing(false);
} else {
mSwipeRefresh.setRefreshing(false);
......@@ -113,6 +118,14 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip
if (view.getId() == R.id.ll_auth_logout) {
mPbLoading.setVisibility(View.VISIBLE);
WarplyManager.logout(mLogoutReceiver);
return;
}
if (view.getId() == R.id.ll_sm_flow) {
WarplyManagerHelper.openSuperMarketsFlow(getContext());
return;
}
if (view.getId() == R.id.ll_sm_map) {
WarplyManagerHelper.openSupermarketsMap(getContext());
}
}
......@@ -168,7 +181,7 @@ public class HomeFragment extends Fragment implements View.OnClickListener, Swip
// }
// }
WarplyManager.getCampaigns(mCampaignsCallback);
WarplyManager.getSupermarketCampaign(mCampaignsCallback);
}
@Override
......
/*
* Copyright 2010-2013 Warply Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package ly.warp.sdk.io.callbacks;
import org.json.JSONObject;
import ly.warp.sdk.io.models.InboxStats;
public class InboxStatsHook implements CallbackReceiver<JSONObject> {
public InboxStatsHook(CallbackReceiver<InboxStats> receiver) {
mReceiver = receiver;
}
private final CallbackReceiver<InboxStats> mReceiver;
@Override
public void onSuccess(JSONObject result) {
mReceiver.onSuccess(new InboxStats(result));
}
@Override
public void onFailure(int errorCode) {
mReceiver.onFailure(errorCode);
}
}
/*
* Copyright 2010-2013 Warply Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE WARPLY LTD ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL WARPLY LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package ly.warp.sdk.io.models;
import ly.warp.sdk.utils.WarpUtils;
import ly.warp.sdk.Warply;
import org.json.JSONException;
import org.json.JSONObject;
public class InboxStats {
/* Constants used to export the campaign in JSON formal and vice versa */
private static final String TOTAL_COUNT = "count";
private static final String NEW_COUNT = "new";
private static final String UNREAD_COUNT = "unread";
/* Member variables of the Campaign object */
private int totalCount;
private int newCount;
private int unreadCount;
/**
* Basic constructor using a String, representing a JSON Object
*
* @param json
* The String, representing the JSON Object
* @throws JSONException
* Thrown if the String cannot be converted to JSON
*/
public InboxStats(String json) throws JSONException {
this(new JSONObject(json));
}
/**
* Constructor used to create an IboxStats object from a given JSON object
*
* @param jObj
* JSON Object used to create the Campaign
*/
public InboxStats(JSONObject jObj) {
JSONObject inboxStatus = null;
try {
inboxStatus = jObj.getJSONObject("context").getJSONObject("MAPP_OFFER");
} catch (JSONException e) {
WarpUtils.warn("Exception on parsing Inbox Status JSON", e);
}
totalCount = 0;
newCount = 0;
unreadCount = 0;
if (inboxStatus != null) {
if (inboxStatus.has(TOTAL_COUNT))
totalCount = inboxStatus.optInt(TOTAL_COUNT);
if (inboxStatus.has(NEW_COUNT))
newCount = inboxStatus.optInt(NEW_COUNT);
if (inboxStatus.has(UNREAD_COUNT))
unreadCount = inboxStatus.optInt(UNREAD_COUNT);
}
}
/**
* Converts IboxStats into a JSON Object
*
* @return The JSON Object created
*/
public JSONObject toJSONObject() {
JSONObject jObj = new JSONObject();
try {
jObj.putOpt(TOTAL_COUNT, totalCount);
jObj.putOpt(NEW_COUNT, newCount);
jObj.putOpt(UNREAD_COUNT, unreadCount);
} catch (JSONException e) {
}
return jObj;
}
/**
* String representation of the IbnoxStats, as a JSON object
*/
@Override
public String toString() {
return toJSONObject().toString();
}
/**
* String representation of the IboxStats, as a human readable JSON object
*
* @return A human readable String representation
*/
public String toHumanReadableString() {
String s = null;
try {
s = toJSONObject().toString(2);
} catch (JSONException e) {
}
return s;
}
/**
* The total number of active campaigns - This is the number of campaigns
* that the {@link Warply#getInbox(ly.warp.sdk.io.callbacks.CallbackReceiver)
* Warply.getInbox} call with return
*/
public int getTotalCount() {
return totalCount;
}
/**
* The number of campaigns that have never been returned with a call to
* {@link Warply#getInbox(ly.warp.sdk.io.callbacks.CallbackReceiver) Warply.getInbox}
*/
public int getNewCount() {
return newCount;
}
/**
* The number of campaigns that have never been opened
*/
public int getUnreadCount() {
return unreadCount;
}
}
package ly.warp.sdk.io.models;
/**
* Created by Panagiotis Triantafyllou on 20-June-22.
*/
public class QuestionnaireEventModel {
private String name;
private String parameter;
public QuestionnaireEventModel() {
this.name = "";
this.parameter = "";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getParameter() {
return parameter;
}
public void setParameter(String parameter) {
this.parameter = parameter;
}
}
......@@ -55,7 +55,8 @@ public class WarplyManagerHelper {
// ===========================================================
private static CouponList mCouponRedeemedList = new CouponList();
private static ArrayList<Campaign> mCampaignListAll = new ArrayList<Campaign>();
private static ArrayList<Campaign> mCampaignListAll = new ArrayList<Campaign>(),
mSupermarketCampaigns = new ArrayList<Campaign>();
// ===========================================================
// Methods for/from SuperClass/Interfaces
......@@ -74,6 +75,11 @@ public class WarplyManagerHelper {
mCampaignListAll.addAll(campaignList);
}
public static void setSupermarketCampaigns(ArrayList<Campaign> campaignList) {
mSupermarketCampaigns.clear();
mSupermarketCampaigns.addAll(campaignList);
}
public static void setCouponRedeemedList(CouponList couponRedeemedList) {
mCouponRedeemedList.clear();
mCouponRedeemedList.addAll(couponRedeemedList);
......@@ -111,7 +117,7 @@ public class WarplyManagerHelper {
}
public static void openSuperMarketsFlow(Context context) {
if (mCampaignListAll == null || mCampaignListAll.isEmpty()) {
if (mSupermarketCampaigns == null || mSupermarketCampaigns.isEmpty()) {
return;
}
......@@ -131,7 +137,7 @@ public class WarplyManagerHelper {
WarpUtils.setWebviewParams(context, params);
context.startActivity(WarpViewActivity.createIntentFromURL(context, WarplyManagerHelper.constructCampaignUrl(mCampaignListAll.get(0))));
context.startActivity(WarpViewActivity.createIntentFromURL(context, WarplyManagerHelper.constructCampaignUrl(mSupermarketCampaigns.get(0))));
}
public static void openSupermarketsMap(Context context) {
......
......@@ -25,23 +25,16 @@
package ly.warp.sdk.utils.managers;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
import ly.warp.sdk.Warply;
import ly.warp.sdk.io.callbacks.CallbackReceiver;
import ly.warp.sdk.io.models.CampaignList;
import ly.warp.sdk.io.models.PushCampaign;
import ly.warp.sdk.io.request.WarplyInboxRequest;
import ly.warp.sdk.utils.WarpUtils;
import ly.warp.sdk.utils.constants.WarpConstants;
import static ly.warp.sdk.Warply.INSTANCE;
import static ly.warp.sdk.Warply.getWarplyContext;
public class WarplyAnalyticsManager {
......@@ -57,30 +50,6 @@ public class WarplyAnalyticsManager {
sendEvent(eventPage, eventId, metadata, false);
}
public static void logTrackersEvent(Context context, String eventType, String eventName) {
if (WarpUtils.getTrackersEnabled(context)) {
// Warply.getInitializer(context).init();
sendEvent(context, null, eventType.concat(":").concat(eventName), null, false);
}
}
/**
* Log screen events so after we can check if there are in app campaigns to show
* (per screen or all screens). After we send the event with priority we make
* a get_inbox request with extra parameters.
*
* @param eventPage
* @param eventId
* @param metadata
* @param force
* @param context
*/
public static void logEventInApp(Context context, @Nullable String eventPage,
@NonNull String eventId, @Nullable JSONObject metadata,
boolean force) {
sendEventInApp(context, eventPage, eventId, metadata, force);
}
/**
* Default method for logging events with high priority happening in a page
*
......@@ -102,19 +71,6 @@ public class WarplyAnalyticsManager {
/*foreground ? "NB_WillEnterForeground" : "NB_DidEnterBackground"*/);
}
public static void logUserReceivedPush(String sessionUUID) {
JSONObject metadata = new JSONObject();
try {
metadata.putOpt("session_uuid", sessionUUID);
} catch (JSONException e) {
if (WarpConstants.DEBUG) {
e.printStackTrace();
}
}
sendEvent(WarpConstants.MICROAPP_APPLICATION_PAGE_ID,
"NB_PushReceived", metadata, true);
}
public static void logUserReceivedPush(PushCampaign pc) {
JSONObject metadata = new JSONObject();
try {
......@@ -128,21 +84,11 @@ public class WarplyAnalyticsManager {
"NB_PushReceived", metadata, false);
}
// public static void logUserEngagedPush(JSONObject pushSessionUUID) {
// sendEvent(WarpConstants.MICROAPP_APPLICATION_PAGE_ID, "NB_PushAck",
// pushSessionUUID, true);
// }
public static void logUserEngagedPush(JSONObject pushSessionUUID) {
sendPushAckEvent(WarpConstants.MICROAPP_APPLICATION_PAGE_ID, "NB_PushAck",
pushSessionUUID, false);
}
public static void logUserReceivedPush(JSONObject pushSessionUUID) {
sendEvent(WarpConstants.MICROAPP_APPLICATION_PAGE_ID,
"NB_PushReceived", pushSessionUUID, true);
}
/**
* Send an event to the Warply server
*
......@@ -174,81 +120,6 @@ public class WarplyAnalyticsManager {
WarpUtils.log("analytics micro-app is not active");
}
private static void sendEvent(Context context, @Nullable String eventPage, String eventId, @Nullable JSONObject metadata, boolean force) {
boolean isInAppAnalyticsMicroAppActive = WarplyServerPreferencesManager.isMicroAppActive(context, WarpConstants.MicroApp.CUSTOM_ANALYTICS);
if (isInAppAnalyticsMicroAppActive)
try {
JSONObject jObj = new JSONObject();
if (eventPage != null) {
jObj.putOpt("page_id", eventPage);
}
jObj.putOpt("event_id", eventId);
jObj.putOpt("time_submitted", System.currentTimeMillis() / 1000);
if (metadata != null) {
jObj.putOpt("action_metadata", metadata);
}
if (context != null)
Warply.postMicroappData(context, WarpConstants.MICROAPP_INAPP_ANALYTICS, jObj, force);
} catch (JSONException e) {
if (WarpConstants.DEBUG) {
e.printStackTrace();
}
}
else
WarpUtils.log("analytics micro-app is not active");
}
/**
* Send an in app event to the Warply server and show a campaign per screen
*
* @param eventPage Event page ID
* @param eventId Event ID
* @param metadata Event metadata
* @param force If this event should be forced or not
*/
private static void sendEventInApp(final Context context, @Nullable String eventPage,
@NonNull final String eventId, @Nullable JSONObject metadata, boolean force) {
boolean isInAppAnalyticsMicroAppActive = WarplyServerPreferencesManager.isMicroAppActive(WarpConstants.MicroApp.CUSTOM_ANALYTICS);
if (isInAppAnalyticsMicroAppActive) {
try {
JSONObject jObj = new JSONObject();
if (eventPage != null) {
jObj.putOpt("page_id", eventPage);
}
jObj.putOpt("event_id", eventId);
jObj.putOpt("time_submitted", System.currentTimeMillis() / 1000);
if (metadata != null) {
jObj.putOpt("action_metadata", metadata);
}
Warply.postMicroappData(WarpConstants.MICROAPP_INAPP_ANALYTICS, jObj, force);
} catch (JSONException e) {
if (WarpConstants.DEBUG) {
e.printStackTrace();
}
}
} else
WarpUtils.log("analytics micro-app is not active");
// TODO: check for the interval else INSTANCE.getInAppCampaigns()
// if() {
WarplyInboxRequest inboxFilterRequest = new WarplyInboxRequest().setUseCache(false);
Warply.getInboxInApp(inboxFilterRequest, new CallbackReceiver<CampaignList>() {
@Override
public void onSuccess(CampaignList result) {
INSTANCE.mInAppCampaigns = result;
}
@Override
public void onFailure(int errorCode) {
}
});
// } else {
//Warply.showInAppCampaign(context, eventId);
// }
}
private static void sendPushReceivedEvent(@Nullable String eventPage, String eventId, @Nullable JSONObject metadata, boolean force) {
boolean isInAppAnalyticsMicroAppActive = WarplyServerPreferencesManager
.isMicroAppActive(WarpConstants.MicroApp.CUSTOM_ANALYTICS);
......
......@@ -2,6 +2,7 @@ package ly.warp.sdk.utils.managers;
import ly.warp.sdk.io.models.LoyaltySDKDynatraceEventModel;
import ly.warp.sdk.io.models.LoyaltySDKFirebaseEventModel;
import ly.warp.sdk.io.models.QuestionnaireEventModel;
import ly.warp.sdk.io.models.WarplyWebviewActivityCallbackEventModel;
import ly.warp.sdk.io.models.WarplyWebviewCallbackEventModel;
......@@ -13,6 +14,7 @@ public class WarplyEventBusManager {
private LoyaltySDKDynatraceEventModel dynatraceEvent;
private WarplyWebviewCallbackEventModel webviewCallback;
private WarplyWebviewActivityCallbackEventModel webviewActivityCallback;
private QuestionnaireEventModel questionnaire;
public WarplyEventBusManager() {
......@@ -41,4 +43,12 @@ public class WarplyEventBusManager {
public WarplyWebviewActivityCallbackEventModel getWarplyWebviewActivityCallbackEventModel() {
return webviewActivityCallback;
}
public WarplyEventBusManager(QuestionnaireEventModel questionnaire) {
this.questionnaire = questionnaire;
}
public QuestionnaireEventModel getQuestionnaire() {
return questionnaire;
}
}
......
......@@ -85,6 +85,7 @@ import ly.warp.sdk.activities.WarpViewActivity;
import ly.warp.sdk.db.WarplyDBHelper;
import ly.warp.sdk.io.models.LoyaltySDKDynatraceEventModel;
import ly.warp.sdk.io.models.LoyaltySDKFirebaseEventModel;
import ly.warp.sdk.io.models.QuestionnaireEventModel;
import ly.warp.sdk.utils.WarpUtils;
import ly.warp.sdk.utils.WarplyProperty;
import ly.warp.sdk.utils.WarplyUrlHandler;
......@@ -457,6 +458,10 @@ public class WarpView extends WebView implements DefaultLifecycleObserver {
WarpViewActivity.setWebviewSupermarket(true);
} else if (parts[1].equals("closeArtwork")) {
WarpViewActivity.setWebviewSupermarket(false);
QuestionnaireEventModel questionnaireEvent = new QuestionnaireEventModel();
questionnaireEvent.setName(parts[1]);
EventBus.getDefault().post(new WarplyEventBusManager(questionnaireEvent));
} else if (parts[1].equals("request") || parts[1].equals("response")) {
WarpUtils.log("**************** WARPLY Webview Log START *****************");
WarpUtils.log(message);
......
......@@ -98,6 +98,7 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<RelativeLayout
android:id="@+id/rl_auth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/rl_header"
......@@ -126,7 +127,7 @@
android:textSize="20sp"
android:textStyle="bold"
android:visibility="gone"
tools:visibility="visible"/>
tools:visibility="visible" />
<TextView
android:id="@+id/tv_login"
......@@ -137,7 +138,7 @@
android:layout_marginStart="16dp"
android:textColor="@color/blue_dark"
android:textSize="20sp"
android:visibility="gone"/>
android:visibility="gone" />
<LinearLayout
android:id="@+id/ll_auth_login"
......@@ -192,9 +193,9 @@
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@android:color/transparent"
android:translationZ="100dp"
android:visibility="gone"
tools:visibility="visible"
android:translationZ="100dp">
tools:visibility="visible">
<ProgressBar
android:layout_width="48dp"
......@@ -205,6 +206,60 @@
android:indeterminateTintMode="src_atop" />
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_sm_view"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_below="@+id/rl_auth"
android:layout_marginHorizontal="8dp"
android:layout_marginTop="24dp"
android:layout_marginBottom="16dp"
android:background="@drawable/shape_cos_white">
<LinearLayout
android:id="@+id/ll_sm_flow"
android:layout_width="140dp"
android:layout_height="45dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="16dp"
android:background="@drawable/selector_button_green"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:includeFontPadding="false"
android:text="@string/demo_sm_flow"
android:textColor="@color/white"
android:textSize="16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_sm_map"
android:layout_width="140dp"
android:layout_height="45dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:background="@drawable/selector_button_green"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:includeFontPadding="false"
android:text="@string/demo_sm_map"
android:textColor="@color/white"
android:textSize="16sp" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
</ScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
......
......@@ -8,4 +8,6 @@
<string name="cos_login_text">Σύνδεση</string>
<string name="cos_logout_text">Αποσύνδεση</string>
<string name="menu_home">Αρχική</string>
<string name="demo_sm_flow">Open SM Flow</string>
<string name="demo_sm_map">Open SM Map</string>
</resources>
......