/** * Odoo, Open Source Management Solution * Copyright (C) 2012-today Odoo SA (<http:www.odoo.com>) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http:www.gnu.org/licenses/> * * Created on 25/2/15 12:07 PM */ package com.odoo.base.addons.mail.widget; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.TypedArray; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Color; import android.os.AsyncTask; import android.os.Bundle; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.odoo.App; import com.odoo.R; import com.odoo.base.addons.mail.MailMessage; import com.odoo.core.orm.ODataRow; import com.odoo.core.orm.OModel; import com.odoo.core.orm.fields.OColumn; import com.odoo.core.utils.BitmapUtils; import com.odoo.core.utils.IntentUtils; import com.odoo.core.utils.OControls; import com.odoo.core.utils.OCursorUtils; import com.odoo.core.utils.ODateUtils; import com.odoo.core.utils.OResource; import com.odoo.core.utils.StringUtils; import java.util.ArrayList; import java.util.List; import odoo.controls.ExpandableListControl; import odoo.helper.ODomain; public class MailChatterView extends LinearLayout implements ExpandableListControl.ExpandableListAdapterGetViewListener, View.OnClickListener { public static final String TAG = MailChatterView.class.getSimpleName(); private Context mContext; private String modelName = null; private int record_server_id = 0; private View mChatterCardView; private OModel mModel; private ExpandableListControl mChatterListView; private ExpandableListControl.ExpandableListAdapter mListAdapter; private List<Object> chatterItems = new ArrayList<>(); private MailMessage mailMessage; private ChatterMessagesLoader messagesLoader; private App app; private Boolean loadAllMessages = false; private boolean isExecuting = false; public MailChatterView(Context context) { super(context); init(context, null, 0); } public MailChatterView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs, 0); } public MailChatterView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs, defStyleAttr); } private void init(Context context, AttributeSet attrs, int defStyleAttr) { mContext = context; app = (App) mContext.getApplicationContext(); if (attrs != null) { TypedArray types = mContext.obtainStyledAttributes(attrs, R.styleable.MailChatterView); modelName = types.getString(R.styleable.MailChatterView_resModelName); types.recycle(); } setOrientation(VERTICAL); mailMessage = new MailMessage(context, null); mContext.registerReceiver(dataChangeReceiver, new IntentFilter("mail.message.update")); } public void generateView() { Log.v(TAG, "Generating View for Mail Chatter"); removeAllViews(); mChatterCardView = LayoutInflater.from(mContext).inflate(R.layout.base_mail_chatter, this, false); addView(mChatterCardView); findViewById(R.id.chatterSendMessage).setOnClickListener(this); findViewById(R.id.chatterLogInternalNote).setOnClickListener(this); if (modelName != null) { mModel = OModel.get(mContext, modelName, null); if (!mModel.hasMailChatter()) { removeAllViews(); } else { if (record_server_id > 0) { getMessages(); } } } else { removeAllViews(); } } private void getMessages() { mChatterListView = (ExpandableListControl) findViewById(R.id.chatterMessages); mListAdapter = mChatterListView.getAdapter( R.layout.base_mail_chatter_item, chatterItems, this); mListAdapter.notifyDataSetChanged(chatterItems); // Check for server updated messages if (app.inNetwork()) { messagesLoader = new ChatterMessagesLoader(); messagesLoader.execute(); } // Updating chatter messages updateChatterList(); } private void updateChatterList() { // Getting local messages if (modelName != null) { chatterItems.clear(); Cursor cr = mContext.getContentResolver().query(mailMessage.uri(), null, "model = ? and res_id = ?", new String[]{modelName, record_server_id + ""}, "date desc"); if (cr.moveToFirst()) { int limit = (loadAllMessages) ? cr.getCount() : (cr.getCount() > 3) ? 3 : cr.getCount(); for (int i = 0; i < limit; i++) { ODataRow row = OCursorUtils.toDatarow(cr); chatterItems.add(row); cr.moveToNext(); } } TextView loadMore = (TextView) findViewById(R.id.chatterLoadMoreMessages); if (cr.getCount() > 3 && !loadAllMessages) { loadMore.setVisibility(View.VISIBLE); loadMore.setOnClickListener(this); } else { loadMore.setVisibility(View.GONE); } mListAdapter.notifyDataSetChanged(chatterItems); if (chatterItems.isEmpty()) { loadMore.setVisibility(View.VISIBLE); loadMore.setText("No messages !"); } } } public void setModelName(String model) { modelName = model; } public void setRecordServerId(int record_server_id) { this.record_server_id = record_server_id; } @Override public View getView(int position, View view, ViewGroup parent) { ODataRow row = (ODataRow) chatterItems.get(position); if (row.getString("subtype_id").equals("false")) { view.setBackgroundResource(R.color.base_chatter_view_note_background); } else { view.setBackgroundColor(Color.WHITE); } view.findViewById(R.id.imgAttachments).setVisibility( (row.getBoolean("has_attachments")) ? View.VISIBLE : View.GONE ); if (row.getString("subject").equals("false")) { OControls.setGone(view, R.id.chatterSubject); } else { OControls.setVisible(view, R.id.chatterSubject); OControls.setText(view, R.id.chatterSubject, row.getString("subject")); } String date = ODateUtils.convertToDefault(row.getString("date"), ODateUtils.DEFAULT_FORMAT, "MMM dd hh:mm a"); OControls.setText(view, R.id.chatterDate, date); OControls.setText(view, R.id.chatterBody, StringUtils.htmlToString(row.getString("body"))); OControls.setText(view, R.id.chatterAuthor, row.getString("author_name")); String author_image = mailMessage.getAuthorImage(row.getInt(OColumn.ROW_ID)); if (!author_image.equals("false")) { Bitmap author = BitmapUtils.getBitmapImage(mContext, author_image); OControls.setImage(view, R.id.authorImage, author); } else { OControls.setImage(view, R.id.authorImage, R.drawable.avatar); } view.setTag(row); view.setOnClickListener(this); return view; } @Override public void onClick(View v) { Bundle extra = new Bundle(); extra.putString("model", mModel.getModelName()); extra.putInt("server_id", record_server_id); switch (v.getId()) { case R.id.chatterSendMessage: if (app.inNetwork()) { extra.putString("type", MailChatterCompose.MessageType.Message.toString()); IntentUtils.startActivity(mContext, MailChatterCompose.class, extra); } else { Toast.makeText(mContext, OResource.string(mContext, R.string.toast_network_required), Toast.LENGTH_LONG).show(); } break; case R.id.chatterLogInternalNote: if (app.inNetwork()) { extra.putString("type", MailChatterCompose.MessageType.InternalNote.toString()); IntentUtils.startActivity(mContext, MailChatterCompose.class, extra); } else { Toast.makeText(mContext, OResource.string(mContext, R.string.toast_network_required), Toast.LENGTH_LONG).show(); } break; case R.id.chatterLoadMoreMessages: loadAllMessages = true; updateChatterList(); break; default: ODataRow row = (ODataRow) v.getTag(); extra.putAll(row.getPrimaryBundleData()); if (row != null) { IntentUtils.startActivity(mContext, MailDetailDialog.class, extra); } break; } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (messagesLoader != null) messagesLoader.cancel(true); mContext.unregisterReceiver(dataChangeReceiver); } private class ChatterMessagesLoader extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { super.onPreExecute(); findViewById(R.id.chatterProgress).setVisibility(View.VISIBLE); findViewById(R.id.chatterOr).setVisibility(View.GONE); } @Override protected Void doInBackground(Void... params) { try { Thread.sleep(500); ODomain domain = new ODomain(); domain.add("model", "=", modelName); domain.add("res_id", "=", record_server_id); List<Integer> serverIds = mailMessage.getServerIds(modelName, record_server_id); if (serverIds.size() > 0) { domain.add("id", "not in", serverIds); } mailMessage.quickSyncRecords(domain); } catch (Exception e) { } return null; } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); findViewById(R.id.chatterProgress).setVisibility(View.GONE); findViewById(R.id.chatterOr).setVisibility(View.VISIBLE); updateChatterList(); isExecuting = false; } } private BroadcastReceiver dataChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (!isExecuting) { if (messagesLoader != null) messagesLoader.cancel(true); messagesLoader = new ChatterMessagesLoader(); messagesLoader.execute(); isExecuting = true; } } }; }